2017-02-28 8 views
0

xml2 및 rvest를 사용하여 R의 XML 파일을 읽습니다. XML의 구조는 다음과 같습니다 (헤더는 포함되지 않음). <w:p></w:p> 사이의 모든 텍스트를 추출하고 싶지만 먼저 <w:br/>을 공백으로 변환하고 싶습니다.R - rvest를 사용하여 xml 태그를 공백으로 바꿉니다.

[1] "Example .docx file"                         
[2] "This is an example .docx file included with the \u0091readOffice\u0092 package to demonstrate functionality."  
[3] "There is nothing exciting in this file!Thank you!" 

하지만 줄 바꿈 <w:br/> 단지 사이에 공간을 남기지 않고 사라졌다 : 나는 (완전히 합법적 인 XML로) 다음 코드를 사용하는 경우

<w:p><w:r><w:t>First bit of text</w:t></w:r><w:r><w:br/><w:t>Thank you!</w:t></w:r></w:p> 

xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se wp14"> 
    <w:body><w:p w:rsidR="00C87F35" w:rsidRDefault="008836BC" w:rsidP="008836BC"><w:pPr> 
    <w:pStyle w:val="Heading1"/></w:pPr> 
    <w:r><w:t>Example .</w:t></w:r> 
    <w:proofErr w:type="spellStart"/><w:r><w:t>docx</w:t></w:r><w:proofErr w:type="spellEnd"/> 
    <w:r><w:t xml:space="preserve"> file</w:t></w:r></w:p> 
    <w:p w:rsidR="008836BC" w:rsidRDefault="008836BC" w:rsidP="008836BC"> 
    <w:r><w:t>This is an example .</w:t></w:r> 
    <w:proofErr w:type="spellStart"/> 
    <w:r><w:t>docx</w:t></w:r><w:proofErr w:type="spellEnd"/> 
    <w:r><w:t xml:space="preserve"> file included with the ‘</w:t></w:r> 
    <w:proofErr w:type="spellStart"/><w:r> 
    <w:t>readOffice</w:t></w:r> 
    <w:proofErr w:type="spellEnd"/> 
    <w:r><w:t>’ package to demonstrate functionality.</w:t></w:r></w:p> 
    <w:p w:rsidR="008836BC" w:rsidRPr="008836BC" w:rsidRDefault="008836BC" w:rsidP="008836BC"> 
    <w:r><w:t>There is nothing exciting in this file!</w:t></w:r> 
    <w:r><w:br/><w:t>Thank you!</w:t></w:r> 
    <w:bookmarkStart w:id="0" w:name="_GoBack"/> 
    <w:bookmarkEnd w:id="0"/></w:p> 
    <w:sectPr w:rsidR="008836BC" w:rsidRPr="008836BC"> 
    <w:pgSz w:w="12240" w:h="15840"/> 
    <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/> 
    <w:cols w:space="720"/> 
    <w:docGrid w:linePitch="360"/></w:sectPr> 
    </w:body></w:document>' 


    xml2::read_xml(xml) %>% 
     rvest::xml_nodes('w\\:p') %>% 
     xml2::xml_text() 

결과는 최종 감탄 부호 및 낱말 감사하십시오.

실제 응용 프로그램에서는 문자열 (read_xml 함수 사용)이 아닌 XML 파일을 읽고 있으므로 간단한 gsub 해결책이 아닙니다. 그것이 유일한 해결책이기 때문일 수도 있습니다. 하지만 내가 궁금해하는 건 특정 태그를 공백으로 변환하기 위해 rvest와 xml2를 어떻게 사용할 수 있습니까?

UPDATE

그래서 다른 대답하는 XPath로 normalize-space 기능을 사용하도록 제안했다. 텍스트가 <w:r><w:t>는 이제 도입 여분의 공백이 포함 모든 태그에 분할되어 있기 때문에

paragraphs = xml2::read_xml(xml) %>% 
    rvest::xml_nodes('w\\:p') 
purrr::map(paragraphs,function(x){ 
    paste(xml2::xml_text(rvest::xml_nodes(x,xpath=".//text()[normalize-space()]")),collapse=" ") 
}) 

그러나 이것은 원하는 결과를 생성하지 않습니다. 처음 두 요소에는 '.docx'에 공백이 있고 두 번째 요소에는 " 'readOffice'"에 공백이 있습니다.

[[1]] 
[1] "Example . docx file" 

[[2]] 
[1] "This is an example . docx file included with the ‘ readOffice ’ package to demonstrate functionality." 

[[3]] 
[1] "There is nothing exciting in this file, but if you’re reading it, it means you installed my package! Thank you!" 

나는 공간이 collapse=" "의 내 사용으로 인해 알고하지만 난 collapse=""를 사용하는 경우 그 결과는 원래의 코드에서 변경되지 않습니다.

+1

가능한 중복 ] (http://stackoverflow.com/questions/42003932/adding-whitespace-to-text-elements) - 당신은 내 anser에서 언급 한 것과 같은 기능을 사용할 수 있습니다. rvest를 사용하지 않으려면 html_ * by xml_ * 함수를 사용하십시오. – Rentrop

+0

@ Floo0 함수에서 사용하는 xpath는 지정된 태그뿐만 아니라 모든 태그의 텍스트를 나눕니다. 따라서 텍스트를 너무 많이 분리합니다. – Mark

답변

1

이 더 이상 필요하지 않을 수 있지만, 새 라인 문자로 각 w:br 노드의 (빈) 텍스트를 대체하고 전체 텍스트 추출 할 수 있습니다 : 요소를 텍스트로 [추가 공백의

library(rvest) 
library(purrr) 

read_xml(xml) %>% 
    xml_nodes('w\\:p') %>% 
    map(~{ 
     xml_nodes(.x, 'w\\:br') %>% `xml_text<-`('\n') 

     xml_text(.x) 
    }) -> r 

cat(r[[3]]) 
#> There is nothing exciting in this file! 
#> Thank you!