R:解析大型非结构化xml文件

时间:2018-05-02 20:00:57

标签: r xml parsing

我有一个非常复杂的xml文件需要解析并以R中的数据帧格式呈现。该结构可能类似于以下示例。节点不是并行的。

<Root>
  <A>
   <info1>a</info1>
     <child>
       <info2>b</info2>
       <info3>c</info3>
       <info4>d</info4>
     </child>
   <info5>e</info5>
  </A>
  <B>
   <info6>f</info6>
   <info7>g</info7>
  </B>
</Root>

我提出了一些代码来解析文件:

doc <- xmlParse(file="sample.xml", useInternal = TRUE)
rootnode <- xmlRoot(doc)
df1<-xmlToDataFrame(nodes=getNodeSet(rootnode, "//Root/A"))
df2<-xmlToDataFrame(nodes=getNodeSet(rootnode, "//Root/B"))
Final<-cbind.data.frame(df1,df2, all=TRUE)

结果返回为:(所有值表单节点都缩小在一起)

info1 child info5 info6 info7
  a    bcd    e     f     g

然而,我想要的理想结果是:

info1 info2 info3 info4 info5 info6 info7
  a     b     c     d     e     f     g

因为xml文件中存在大量类似于上述情况的节点,所以手动操作数据帧是不明智的。
我还尝试将路径语句更改为“// Root / A / child”,然后将丢失节点A和节点B下的所有值。 有没有人能提供解决这个问题的方法。提前致谢。

3 个答案:

答案 0 :(得分:2)

可以尝试使用xmlToListunlist来减少指定矢量格式的xml数据。可以使用gsub更改名称,以符合OP的预期:

library(XML)
result <- unlist(xmlToList(xmlParse(xml)))
#Change the name to refer only child 
names(result) <- gsub(".*\\.(\\w+)$","\\1", names(result))
result 
# info1 info2 info3 info4 info5 info6 info7 
# "a"   "b"   "c"   "d"   "e"   "f"   "g"

数据:

xml <- "<Root>
  <A>
  <info1>a</info1>
  <child>
  <info2>b</info2>
  <info3>c</info3>
  <info4>d</info4>
  </child>
  <info5>e</info5>
  </A>
  <B>
  <info6>f</info6>
  <info7>g</info7>
  </B>
  </Root>"

答案 1 :(得分:0)

在结构较少的XML中,最好执行以下操作:

library(XML)
Final <- data.frame(xmlToList(rootnode), recursive = T, use.names = T)

如果您不喜欢自动设置的列名称,只需执行use.names = F并设置自己的名称即可。

答案 2 :(得分:0)

使用starts-with()

匹配节点
> doc = xmlParse(xml)
> xpathSApply(doc, "//*[starts-with(name(), 'info')]", xmlValue)
[1] "a" "b" "c" "d" "e" "f" "g"
> xpathSApply(doc, "//*[starts-with(name(), 'info')]", xmlName)
[1] "info1" "info2" "info3" "info4" "info5" "info6" "info7"

所以

query <- "//*[starts-with(name(), 'info')]"
setNames(
    xpathSApply(doc, query, xmlValue),
    xpathSApply(doc, query, xmlName)
)