r - 如何将 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
错误。谢谢。
解决方案
考虑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"))
推荐阅读
- authentication - WSO2 APIM 缓存 JWT 令牌比它应该更长的时间添加过期令牌
- bash - Bash 从文件中读取值以设置变量
- javascript - 使外部 Vue 组件响应式
- css - 导航栏,一些元素位于中心,一些元素右对齐。图片需要调整大小
- c# - 根据下拉结果填充列表 ASP.NET MVC C#
- solidity - 创建一个智能合约,持有并发送资金以设置钱包
- azure-data-explorer - Kusto 查询以获取不为空的最新列值(对于每一列)
- mysql - 在 MySql 中合并两行
- google-apps-script - Google 表单回复 + 其他数据触发电子邮件
- batch-file - 批处理:如何按扩展对输出进行排序