如何在 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"))
如何转换如下所示的 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"))