【问题标题】:Nested XML parsing in RR中的嵌套XML解析
【发布时间】:2016-01-06 07:45:12
【问题描述】:

我编写了以下代码来解析一个简单的 XML 文件。

xmlfile <- xmlTreeParse(inFile$datapath,encoding = "UTF-8")
    xmltop = xmlRoot(xmlfile)
    singlexml <- xmlSApply(xmltop, function(x) xmlSApply(x, xmlValue))
    singlexml_df <- as.data.frame(t(singlexml),row.names=NULL)
    indx <- sapply(singlexml_df, is.list)
    singlexml_df[indx] <- lapply(singlexml_df[indx], function(x) as.character(x))
    singlexml_df

XML:

<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
    <PLANT>
        <COMMON>Bloodroot</COMMON>
        <BOTANICAL>Sanguinaria canadensis</BOTANICAL>
        <ZONE>4</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>$2.44</PRICE>
        <AVAILABILITY>031599</AVAILABILITY>
    </PLANT>
    <PLANT>
        <COMMON>Columbine</COMMON>
        <BOTANICAL>Aquilegia canadensis</BOTANICAL>
        <ZONE>3</ZONE>
        <LIGHT>Mostly Shady</LIGHT>
        <PRICE>$9.37</PRICE>
        <AVAILABILITY>030699</AVAILABILITY>
    </PLANT>
</CATALOG>

它被成功解析并转换为数据帧。

但我的新要求是解析嵌套的 XML。

当我尝试解析新的嵌套 XML 时,所有内容都组合在一个列中,并且没有正确地转换为数据框。

我想要 请提供您的建议。

谢谢

【问题讨论】:

  • 您是否看到错误消息?您的第二个 xml 示例不是有效的 xml。它包含两个根节点,ALERT 和 CATALOG,xml 只允许一个根节点。此外,ALERT 标记未关闭,这是 xml 要求的。
  • 感谢@Matthew 发现错误。以前的 XML 是经过修改的。我现在已经更新了我想要解析的确切 XML。你能帮帮我吗?

标签: xml r


【解决方案1】:

我会使用 XPath 来解决这个问题,因为它可以让您更好地控制检索的内容,同时减少对特定结构的依赖。这是一种更加灵活的方法,并且很容易适应其他输入。在您的第一种情况下(使用植物),您可以这样做

library(XML)
plantfile <- xmlParse("plants.xml")
plant.df <- as.data.frame(t(xpathSApply(plantfile,"//PLANT",function(x) xmlSApply(x,xmlValue))))

在您的后一种情况下,假设我们要从警报突出显示中提取包含详细信息的数据框:

library(XML)
alertfile <- xmlParse("alerts.xml")
alert.df <- as.data.frame(t(xpathSApply(alertfile,"//AlertHighlights/Data/Detail",function(x) xmlSApply(x,xmlValue))))

在第一种情况下,使用 XPath 表达式“//PLANT”从文件中检索所有 PLANT 节点(无论它们出现多深)。

在第二种情况下,我们检索作为 Data 节点的子节点的所有 Detail 节点,这些节点是 AlertHighlights 节点的子节点(无论多深)。如果您确定这些是唯一的 Detail 节点,那么我们可以简化为 //Detail

如果你要经常这样做,我什至会把它包装成一个函数:

xpathToDataFrame <- function(xmlinput,expr) as.data.frame(t(xpathSApply(xmlinput,expr,function(x) xmlSApply(x,xmlValue))))

那我们就可以了

plant.df <- xpathToDataFrame(xmlParse("plants.xml"),"//PLANTS")
alert.df <- xpathToDataFrame(xmlParse("alerts.xml"),"//AlertHighlights/Data/Detail")

【讨论】:

  • 谢谢@Matthew。我将尝试上述给定的功能。实际上我正在尝试构建一个小的闪亮应用程序,它将表达式/节点作为输入并显示给定节点下所有子节点的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-19
  • 2020-10-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多