首页 > 解决方案 > 如何将 XML 文件转换为 R 中的数据框/小标题?

问题描述

如何转换如下所示的 XML 文件:

<bible>
  <b n="Psalm">
    <c n="1">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
    </c>
    <c n="2">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
  </c>
  </b>
  <b n="Revelation">
    <c n="1">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
    </c>
    <c n="2">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
    </c>
    <c n="3">
      <v n="1"> text text text text </v>
      <v n="2"> text text text text </v>
      <v n="3"> text text text text </v>
    </c>
  </b>
</bible>

变成如下所示的数据框/小标题格式:

# A tibble: 15 x 4
 book       chapter verse text               
 <chr>        <dbl> <int> <chr>              
1 Psalm            1     1 text text text text
2 Psalm            1     2 text text text text
3 Psalm            1     3 text text text text
4 Psalm            2     1 text text text text
5 Psalm            2     2 text text text text
6 Psalm            2     3 text text text text
7 Revelation       1     1 text text text text
8 Revelation       1     2 text text text text
9 Revelation       1     3 text text text text
10 Revelation       2     1 text text text text
11 Revelation       2     2 text text text text
12 Revelation       2     3 text text text text
13 Revelation       3     1 text text text text
14 Revelation       3     2 text text text text
15 Revelation       3     3 text text text text

我尝试过使用xmlToDataFrame(nodes = getNodeSet(doc, "/bible"))XML 包,但我只得到一个包含多列的观察结果。当我尝试更改 getNodeSet 函数的节点级别时,出现duplicate subscripts for columns错误。谢谢。

标签: rxmldplyrxml2

解决方案


考虑XSLT,这是一种专用语言,旨在将 XML 文件和同级文件转换为 XPath。具体来说,您需要将所有数据扁平化为一个级别,例如将祖先节点或属性迁移到兄弟节点的诗句,当然要为数据框设置重复值。

转换后,您可以使用XML::xmlToDataFrame适合更扁平 XML 的便捷方法。R 可以使用包运行 XSLT 1.0 xslt(扩展至xml2

XSLT (另存为 .xsl,一个特殊的 .xml 文件)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/bible">
        <xsl:copy>
            <xsl:apply-templates select="descendant::v"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="v">
        <data>
            <book><xsl:value-of select="ancestor::b/@n"/></book>
            <chapter><xsl:value-of select="ancestor::c/@n"/></chapter>
            <verse><xsl:value-of select="@n"/></verse>
            <text><xsl:value-of select="text()"/></text>
        </data>
    </xsl:template>

</xsl:stylesheet>

R (不需要循环或映射)

library(XML)
library(xslt)

doc <- read_xml("Import.xml", package = "xslt")
style <- read_xml("Script.xsl", package = "xslt")

new_xml <- xml_xslt(doc, style)

new_doc <- XML::xmlParse(new_xml)    
bible_df <- XML::xmlToDataFrame(nodes=getNodeSet(new_doc, "//data"))

推荐阅读