2014-12-04 3 views
1

Я пытаюсь разобрать XML в R, используя пакет XML от Duncan Temple Lang. Код у меня выглядит следующим образом:Добавить новую строку в data.frame в рекурсивной функции в R

library(XML) 
retrieveStructureInfo <- function(node, tableData) { 
    tableD <- data.frame(path = NA, node = NA, value = NA) 

    for (i in 1 : xmlSize(xmlAttrs(node))) { 
     tableD <- rbind(tableD, c("path", "node", "value")) 
     tableData <<- rbind(tableData, tableD)  
    } 

    #children is the no. of nodes within a node 
    for (i in 1 : children) { 
     #recursive function call 
     retrieveStructureInfo(node[[i]], tableD) 
    } 
} 

#parse xml document 
#xmlfile is the file path 
doc <- xmlParse(xmlfile) 
r <- xmlRoot(doc) 
tableData <- data.frame(path = NA, node = NA, value = NA) 
retrieveStructureInfo(r, tableData) 
tableData 

У меня возникли проблемы при добавлении строк в data.frame, потому что это делается в рекурсивной функции. Для XML, приведенного ниже, в data.frame добавляются только последние два значения атрибута, то есть Source = "b" и Available = "true". Я создал основную таблицу tableData и попытаюсь обновить ее с помощью локальной таблицы в функции tableD, но она не работает.

<CATALOG> 
    <PLANT> 
     <COMMON Source="a" Available="false">Bloodroot</COMMON> 
    </PLANT> 
    <PLANT> 
     <COMMON Source="b" Available="true">Columbine</COMMON> 
    </PLANT> 
</CATALOG> 

Я забыл добавить, что я стремлюсь создать функцию, которая считывает любой XML (именно поэтому я пошел с идеей рекурсии) и дает выход:

    path     node     value parent  type 
    CATALOG/PLANT/COMMON    Source     a PLANT attribute 
    CATALOG/PLANT/COMMON   Available     false PLANT attribute 
    CATALOG/PLANT/COMMON    COMMON    Bloodroot PLANT  text 

ответ

0

Обычно ответ xml и recursion - использовать xpath. Возможно, вы сможете создать таблицу с несколькими запросами xpath или одной из вспомогательных функций, таких как xmlToList.

x<- '<CATALOG> 
    <PLANT> 
     <COMMON Source="a" Available="false">Bloodroot</COMMON> 
    </PLANT> 
    <PLANT> 
     <COMMON Source="b" Available="true">Columbine</COMMON> 
    </PLANT> 
</CATALOG>' 

doc <- xmlParse(x) 

xpathSApply(doc, "//COMMON", xmlValue) 
[1] "Bloodroot" "Columbine" 
xpathSApply(doc, "//COMMON", xmlGetAttr, "Source") 
[1] "a" "b" 

y <- xmlToList(doc) 
data.frame(path=names(unlist(y)),value=unlist(y)) 
          path  value 
1    PLANT.COMMON.text Bloodroot 
2 PLANT.COMMON..attrs.Source   a 
3 PLANT.COMMON..attrs.Available  false 
4    PLANT.COMMON.text Columbine 
5 PLANT.COMMON..attrs.Source   b 
6 PLANT.COMMON..attrs.Available  true 

library(plyr) 
ldply(y, data.frame) #OR 
ldply(y, function(x) data.frame(x, names(x$COMMON$.attrs) )) 
    .id COMMON.text COMMON..attrs names.x.COMMON..attrs. 
1 PLANT Bloodroot    a     Source 
2 PLANT Bloodroot   false    Available 
3 PLANT Columbine    b     Source 
4 PLANT Columbine   true    Available 
+0

Спасибо за ваш ответ Крис. Из моего понимания XPath требуется указать путь. Но я создаю функцию, которая должна анализировать XML независимо от того, какой XML-скрипт ему предоставляется. Он должен анализировать XML и производить вывод, как в моем вопросе. – user2877232

Смежные вопросы