2

我有一本书的 XML 文件。主树有Body/Pagecolumn/Region/Paragraph/Line/Word级别。但是,我对Line级别不感兴趣。有没有办法在不破坏R 中使用 XML 包或任何其他包的Word级别的情况下融合Line级别?转换后,主树为Body/Pagecolumn/Region/Paragraph/Word

下面提供了 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>

谢谢。

4

3 回答 3

3

我喜欢简单的正则表达式解决方案,在这种情况下,它们可能是要走的路。一般来说,XML我们会考虑使用XSLT. 这是一种用于转换的语言XML。有一个 R 包Sxslt可用于转换XML. 这个想法是定义2个模板:

  1. 第一个模板是所谓的恒等变换。这会复制所有属性和节点。如果特定元素有更相关的模板,xslt 将使用该模板。
  2. 然后我们声明了一个与 LINE 更相关的模板。这无济于事。因此,对于除 LINE 之外的所有节点和属性,转换都会执行复制。

这里是我的代码:

# 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>
于 2013-07-02T19:10:44.583 回答
1

正确的方法是使用xml包并进行节点融合。

但是,对于您提供的示例 xml,您可能可以通过简单的gsub(查找和替换)来摆脱困境。

类似于以下内容:

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

然后从那里走。

于 2013-07-02T18:22:59.473 回答
1

grepl用于删除所有行的类似解决方案:

ll <- readLines(textConnection(txt))
ll <- ll[!grepl("<LINE>|</LINE>" ,ll)]
txt <- paste(ll, "\n", collapse="")
xmlParse(txt,asText=TRUE)
于 2013-07-02T18:29:49.997 回答