2016-06-21 16 views
1

我試圖導入一個XML文件與一組響應到R.這是一個link to a version with dummy data顯示該文件的結構。xml到與正確的列名稱的數據框

我已經試過與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

我相信你的縮小列表是不解析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列:元素名稱,元素值和與父節點的名稱的字符串。數據框順序是按節點級別排列的,因此頂部節點上的元素位於數據框的頂部,而第三級上的元素位於底部。

+0

這是有幫助的。名稱並不完全正確,因爲它們包含'something.varname'和'something.something.varname'。我只需要在上一段時間後保持一切。 –

+0

'sub('。* \\。','',names(unlist(xml_data)))''接近,除了我有一些像'varname.1'這樣的變量名,它會被剪切爲'1 '等 –

+0

請參閱上面的修改。 – Dave2e