2013-07-02 48 views
2

我有一本書的XML文件。主樹有Body/Pagecolumn/Region/Paragraph/Line/Word levels。不過,我對級別不感興趣。有沒有什麼辦法來融合級別而不破壞Word級別的R使用XML包或其他包?轉換後,主樹會車身/ Pagecolumn /地區/款/字如何融合R中XML數據中特定類型的節點?

下面提供的XML數據的樣本:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE DjVuXML> 
<DjVuXML> 
<BODY> 
<OBJECT data="file://localhost//book1.djvu" height="1650" type="image/x.djvu" usemap="book1.djvu" width="1275"> 
<PARAM name="PAGE" value="book1_001.djvu"/> 
<PARAM name="DPI" value="300"/> 
<HIDDENTEXT> 
<PAGECOLUMN> 
<REGION> 
<PARAGRAPH> 
<LINE> 
<WORD coords="1,2,3,4,5">Title</WORD> 
</LINE> 
</PARAGRAPH> 
</REGION> 
</PAGECOLUMN> 
<PAGECOLUMN> 
<REGION> 
<PARAGRAPH> 
<LINE> 
<WORD coords="30,564,90,545,559">This</WORD> 
<WORD coords="97,559,109,545,559">is</WORD> 
<WORD coords="115,564,162,545,559">a</WORD> 
</LINE> 
</PARAGRAPH> 
<PARAGRAPH> 
<LINE> 
<WORD coords="30,589,80,570,584">First</WORD> 
<WORD coords="88,584,115,570,584">line</WORD> 
<WORD coords="123,584,146,574,584">is</WORD> 
</LINE> 
<LINE> 
<WORD coords="30,614,90,598,609">Second</WORD> 
<WORD coords="97,609,143,595,609">line</WORD> 
<WORD coords="148,614,168,595,609">is</WORD> 
</LINE> 
<LINE> 
<WORD coords="30,640,56,626,640">Third</WORD> 
<WORD coords="63,640,95,626,640">line</WORD> 
<WORD coords="101,640,128,626,640">is</WORD> 
</LINE> 
</PARAGRAPH> 
</REGION> 
</PAGECOLUMN> 
</HIDDENTEXT> 
</OBJECT> 
<MAP name="book1.djvu"/> 
</BODY> 
</DjVuXML> 

感謝。

回答

3

我喜歡簡單的正則表達式的解決方案,在這種情況下,他們很可能要走的路。一般用XML我們會用XSLT。這是用於轉換XML的語言。有一個R包Sxslt可用於轉換XML。這個想法是定義2個模板:

  1. 第一個模板是什麼被稱爲身份變換。這會複製所有屬性和節點。如果某個特定元素存在更相關的模板,則xslt將使用該模板。
  2. 然後我們宣佈了一個與LINE更相關的模板。這什麼都不做。因此對於除LINE之外的所有節點和屬性,變換執行復制。

這裏MYE代碼:

# install package if needed 
# install.packages('Sxslt', repos = "http://www.omegahat.org/R") 
require(Sxslt) 
# define a transformation 
sltTemp <- '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
<xsl:template match="@* | node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="LINE"> 
    <xsl:apply-templates/> 
</xsl:template> 

</xsl:stylesheet>' 

# assume your XML is text variable named xdata 
# you can also work on a parsed file if you like 
# xD <- xmlParse(xdata) 
# xsltApplyStyleSheet(xD, sltTemp) 
# gives same result 

require(XML) 
newxdata <- saveXML(xsltApplyStyleSheet(xdata, sltTemp)) 
xmlParse(newxdata) 
<?xml version="1.0"?> 
<DjVuXML> 
    <BODY> 
    <OBJECT data="file://localhost//book1.djvu" height="1650" type="image/x.djvu" usemap="book1.djvu" width="1275"> 
     <PARAM name="PAGE" value="book1_001.djvu"/> 
     <PARAM name="DPI" value="300"/> 
     <HIDDENTEXT> 
     <PAGECOLUMN> 
      <REGION> 
      <PARAGRAPH> 
       <WORD coords="1,2,3,4,5">Title</WORD> 
      </PARAGRAPH> 
      </REGION> 
     </PAGECOLUMN> 
     <PAGECOLUMN> 
      <REGION> 
      <PARAGRAPH> 
       <WORD coords="30,290,65,276,290">This</WORD> 
       <WORD coords="73,290,84,276,290">is</WORD> 
       <WORD coords="92,290,100,280,290">a</WORD> 
      </PARAGRAPH> 
      <PARAGRAPH> 
       <WORD coords="30,290,65,276,290">First</WORD> 
       <WORD coords="73,290,84,276,290">line</WORD> 
       <WORD coords="92,290,100,280,290">is</WORD> 
       <WORD coords="30,290,65,276,290">Second</WORD> 
       <WORD coords="73,290,84,276,290">line</WORD> 
       <WORD coords="92,290,100,280,290">is</WORD> 
       <WORD coords="30,290,65,276,290">Third</WORD> 
       <WORD coords="73,290,84,276,290">line</WORD> 
       <WORD coords="92,290,100,280,290">is</WORD> 
      </PARAGRAPH> 
      </REGION> 
     </PAGECOLUMN> 
     </HIDDENTEXT> 
    </OBJECT> 
    <MAP name="book1.djvu"/> 
    </BODY> 
</DjVuXML> 
+0

謝謝!這看起來很棒!幾個問題,我不能安裝它的Windows,我需要從源代碼編譯它?如果我理解你的代碼,在這種情況下,代碼是否仍然適用於這個轉換'',我的意思是沒有@ *? – agstudy

+1

Unfortunatley我不認爲Windows版本可用。第一個模板是所謂的身份變換http://en.wikipedia.org/wiki/Identity_transform。這會複製所有屬性和節點。如果某個特定元素存在更相關的模板,則xslt將使用該模板。我們宣佈了一個與LINE更相關的模板。這什麼都不做。因此對於除LINE之外的所有節點和屬性,變換執行復制。結果是原始XML減去LINE部分。 – user1609452

+0

謝謝。我也在Windows上使用R.我試圖使用RStudio從源代碼安裝,但是我得到了這個錯誤:*請定義LIB_XSLT *。 – imriss

1

正確的方法是使用xml包並進行節點融合。

但是,對於您提供的示例xml,您可能可以通過簡單的gsub(查找和替換)逃脫。

線沿線的東西:

xmlfile <- readLines("test.xml") 
newfile <- gsub("<LINE>|</LINE>", "", xmlfile) 

,並從那裏。

+0

感謝。不過,我會再等一等,看看是否還有模塊化解決方案。 – imriss

1

使用grepl刪除所有行類似的解決方案:

ll <- readLines(textConnection(txt)) 
ll <- ll[!grepl("<LINE>|</LINE>" ,ll)] 
txt <- paste(ll, "\n", collapse="") 
xmlParse(txt,asText=TRUE) 
+0

謝謝。它適用於我固定設置爲FALSE時。 – imriss

+0

@imriss很棒!我編輯我的答案。 – agstudy

相關問題