这是使用“xml2”包的解决方案。我编写了这个函数来查找每个节点的阀门,但在您的情况下,我们只是想确定每个节点的属性“id”。
目的是找到所有没有子节点的顶级节点并提取它们的值,然后移动到有子节点的节点。然后递归地重复这个函数,直到找到并处理了最大的后代节点。
library(xml2)
file<-read_xml('<node id="A">
<node id = "AA">
<node id = "AAA"></node>
</node>
<node id = "AB">
</node>
<node id = "AC">
</node>
</node>')
findchildren<-function(nodes, df){
numchild<-sapply(nodes, function(x){length(xml_children(x))})
#extract out the attribute, value and parents
xmlattr<-xml_attr(nodes[numchild==0], "id")
#xmlvalue<-xml_text(nodes[numchild==0]) #value of node
xmlpath<-sapply(nodes[numchild==0], function(x) {toString(rev(xml_attr(xml_parents(x), "id")))})
#dftemp<-data.frame(xmlattr, xmlvalue, xmlpath)
dftemp<-data.frame(xmlpath, xmlattr)
#merge results back to master df
df<-rbind(df, dftemp)
print(dim(df)) #Print statement for status
#End of recursion
if (sum(numchild)>0){
findchildren(xml_children(nodes[numchild>0]), df) }
else{ return(df)}
}
df<-data.frame()
df<-findchildren(xml_children(file), df)
apply(df, 1, toString)
此函数输出一个 2 列数据框。第一列是第二列中节点的 xml 路径。我使用该apply
命令将这两列合并在一起以获得最终解决方案。最终列表的顺序不是基于文档的原始结构,而是列出父节点,然后是子节点,孙子节点......这个函数重复调用rbind
不是最有效的方法,但如果子节点的数量不是可以接受的太棒了。
希望这对你有用。