如果我在R中加载了xml,例如:
library(XML)
top <- newXMLNode("top")
tvp <- newXMLNode("TVP", parent = top)
time <- newXMLNode("time", "2012-01-01", parent = tvp)
value <- newXMLNode("value", "123", parent = tvp)
comment <- newXMLNode("comment",parent = tvp)
qualifer <-newXMLNode("qualifier", attrs = c(y = 'abc'), parent = comment)
commentText <-newXMLNode("info", attrs = c(y = 'something'), parent = comment)
tvp <- newXMLNode("TVP", parent = top)
time <- newXMLNode("time", "2012-01-02", parent = tvp)
value <- newXMLNode("value", "456", parent = tvp)
tvp <- newXMLNode("TVP", parent = top)
time <- newXMLNode("time", "2012-01-03", parent = tvp)
value <- newXMLNode("value", "789", parent = tvp)
comment <- newXMLNode("comment",parent = tvp)
newXMLNode("qualifier", attrs = c(y = 'efg'), parent = comment)
top
产生的XML:
<top>
<TVP>
<time>2012-01-01</time>
<value>123</value>
<comment>
<qualifier y="abc"/>
<info y="something"/>
</comment>
</TVP>
<TVP>
<time>2012-01-02</time>
<value>456</value>
</TVP>
<TVP>
<time>2012-01-03</time>
<value>789</value>
<comment>
<qualifier y="efg"/>
</comment>
</TVP>
</top>
如何才能正确地(即在正确的位置)获得包含限定符和信息属性的数据框?
这几乎可行,但不完全正确:
DF <- xmlToDataFrame(top,stringsAsFactors=FALSE)
结果如下:
time value comment
1 2012-01-01 123
2 2012-01-02 456 <NA>
3 2012-01-03 789
我真正需要的是获取注释的子节点属性的方法:
time value qualifer info
1 2012-01-01 123 abc something
2 2012-01-02 456
3 2012-01-03 789 efg
答案 0 :(得分:1)
请尝试以下代码:
require(plyr) ### provides rbind.fill
getDataframe <- function(xml){
out2 <- xmlSApply(xml,function(x){
out <- xmlSApply(x, function(y){
if(length(xmlChildren(y)) > 1){xmlSApply(y,xmlAttrs)
}else{xmlValue(y)}})
as.data.frame(t(unlist(out))) ## rbind.fill likes dataframes
})
return(do.call(rbind.fill,out2))
}
getDataframe(top)
这里的想法是:
答案 1 :(得分:1)
尝试以下方法。对于每个TVP,使用.//*[not(*)]
xpath表达式查找所有后代叶子,其中.
表示从当前点开始,即在当前TVP节点处,//*
表示遍历所有后代但[not(*)]
只限那些没有孩子的人。然后为每个TVP创建一个值列表(如果没有值,则为属性)一个列表组件。在最后一行中,它将每个列表组件转换为矩阵,并使用plyr的rbind.fill.matrix
将矩阵放在一起:
xp <- xpathApply(top, "/top/TVP", xpathSApply, ".//*[not(*)]", function(x)
setNames(ifelse(nzchar(xmlValue(x)), xmlValue(x), xmlAttrs(x)), xmlName(x)))
library(plyr)
do.call(rbind.fill.matrix, lapply(xp, t))
顺便说一句,在我的Windows GUI系统(没有RStudio)上,评论中的代码也崩溃了。
更新:解决方案的轻微缩短