我正在尝试将带有一组响应的XML文件导入到R.这是一个显示文件结构的link to a version with dummy data。
我试图用XML
软件包将其与一个数据框纠缠在一起,如下所示:
library(XML)
file <- "test.xml"
data <- xmlParse(file)
xml_data <- xmlToList(data)
df <- data.frame(matrix(unlist(xml_data), nrow=1, byrow=T))
这给了我482列。
接下来,我尝试提取列名失败。
n <- NULL
for (i in 1:length(xml_data)) {
if (length(xml_data[[i]])==1) {
n <- c(n, names(xml_data[i]))
}
if (length(xml_data[[i]])>1) {
n <- c(n, names(xml_data[[i]]))
}
}
这只给出一个长度为290的向量,所以我缩短了一堆列名。
关于我哪里出错的任何想法?
答案 0 :(得分:0)
我相信你的缩减列表是不解析xml文档中的所有子节点。 由于您已准备好将文档解析为xml_data,请尝试从该列表中提取名称:
n<-names(unlist(xml_data))
这将提供您请求的482个名称的列表。
修改强> 为了提供节点名称和值的列表,我使用xml2包递归搜索XML文档并提取所请求的信息。该解决方案还具有从所有节点中提取值的好处,无论是否存在信息。此样本数据有754个元素,最多3个深度:
library(xml2)
filename <- "C:\\Users\\SO\\Downloads\\test.xml"
df<-data.frame()
findchildren<-function(nodes, df){
numchild<-sapply(nodes, function(x){length(xml_children(x))})
xmlname<-xml_name(nodes[numchild==0])
xmlvalue<-xml_text(nodes[numchild==0])
xmlpath<-sapply(nodes[numchild==0], function(x) {toString(rev(xml_name(xml_parents(x))))})
dftemp<-data.frame(xmlname, xmlvalue, xmlpath)
df<-rbind(df, dftemp)
print(dim(df))
if (sum(numchild)>0){
findchildren(xml_children(nodes[numchild>0]), df) }
else{ return(df)}
}
file<-read_xml(filename)
df<-findchildren(xml_children(file), df)
最终的数据框'df'有3列:元素名称,元素值和带有父节点名称的字符串。数据框顺序是按节点级别的,因此顶部节点的元素位于数据框的顶部,而第三级的元素位于底部。