如何在 R 中将 XML 文件转换为 dataframe/tibble?

How do I convert an XML file into a dataframe/tibble in 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>

转换成如下所示的 dataframe/tibble 格式:

# 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

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

考虑 XSLT,special-purpose 语言旨在将 XML 文件转换为 XPath。具体来说,您需要将所有数据扁平化到一个级别,例如 verse,您可以在其中将祖先节点或属性迁移到兄弟节点,当然还有数据框设置的重复值。

一旦转换,您就可以使用方便的方法 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"))