装载XML到数据帧与父节点R属性

问题描述:

我有要处理成R,其中data.frame的每行包含的一行的一个data.frame的XML文件(一个TEI编码播放)播放,线路号码,该线路的发言人,场景号码和场景类型。 XML文件的正文是这样的(但更长):装载XML到数据帧与父节点R属性

<text> 
<body> 
<div1 type="scene" n="1"> 
    <sp who="fau"> 
     <l n="30">Settle thy studies, Faustus, and begin</l> 
     <l n="31">To sound the depth of that thou wilt profess;</l> 
     <l n="32">Having commenced, be a divine in show,</l> 
    </sp> 
    <sp who="eang"> 
     <l n="105">Go forward, Faustus, in that famous art,</l> 
    </sp> 
</div1> 
<div1 type="scene" n="2"> 
    <sp who="sch1"> 
     <l n="NA">I wonder what's become of Faustus, that was wont to make our schools ring with sic probo.</l> 
    </sp> 
    <sp who="sch2"> 
     <l n="NA">That shall we know, for see here comes his boy.</l> 
    </sp> 
    <sp who="sch1"> 
     <l n="NA">How now sirrah, where's thy master?</l> 
    </sp> 
    <sp who="wag"> 
     <l n="NA">God in heaven knows.</l> 
    </sp> 
</div1> 
</body> 
</text> 

这个问题似乎类似于提出的问题herehere,但我的XML文件的结构略有不同,所以他们都没有给我一个可行的解决方案。我已经成功地做到这一点:

library(XML) 
doc <- xmlTreeParse("data/faustus_sample.xml", useInternalNodes=TRUE) 

bodyToDF <- function(x){ 
    scenenum <- xmlGetAttr(x, "n") 
    scenetype <- xmlGetAttr(x, "type") 
    attributes <- sapply(xmlChildren(x, omitNodeTypes = "XMLInternalTextNode"), xmlAttrs) 
    linecontent <- sapply(xmlChildren(x), xmlValue) 
    data.frame(scenenum = scenenum, scenetype = scenetype, attributes = attributes, linecontent = linecontent, stringsAsFactors = FALSE) 
} 

res <- xpathApply(doc, '//div1', bodyToDF) 
temp.df <- do.call(rbind, res) 

这会返回一个data.frame与“场景号”,“场景类型”和“扬声器”完好,但我不能工作,如何打破它到每一行(并获得关联的行号)。

我尝试导入文件作为列表(通过xmlToList),但这给了我一个令人难以置信的列表清单列表,它也导致了很多不同的错误,如果我试图使用for循环来访问不同的元素(可怕的想法,我知道!)。

理想情况下,我正在寻找一个解决方案,将在其所有杂乱的完整的文件工作,也适用于其他类似结构化的XML文件。

我,使用R刚刚开始,处于亏损状态我完全。任何援助,你可以提供将非常感激。

感谢您的帮助!

编辑:完整的XML文件的副本可here。对于SP元素

添加额外xpathApply:

bodyToDF <- function(x){ 
    scenenum <- xmlGetAttr(x, "n") 
    scenetype <- xmlGetAttr(x, "type") 
    sp <- xpathApply(x, 'sp', function(sp) { 
    who <- xmlGetAttr(sp, "who") 
    if(is.null(who)) 
     who <- NA 
    line_num <- xpathSApply(sp, 'l', function(l) { xmlGetAttr(l,"n")}) 
    linecontent = xpathSApply(sp, 'l', function(l) { xmlValue(l,"n")}) 
    data.frame(scenenum, scenetype, who, line_num, linecontent) 
    }) 
    do.call(rbind, sp) 
} 

res <- xpathApply(doc, '//div1', bodyToDF) 
temp.df <- do.call(rbind, res) 

前4列

# > temp.df[,1:4] 
# scenenum scenetype who line_num 
# 1  1  scene fau  30 
# 2  1  scene fau  31 
# 3  1  scene fau  32 
# 4  1  scene eang  105 
# 5  2  scene sch1  NA 
# 6  2  scene sch2  NA 
# 7  2  scene sch1  NA 
# 8  2  scene wag  NA 
+0

原来,该解决方案完全适用于样本XML,但对完整的文档休息。据我所知,这两个格式是相同的。上运行的线'RES galenc 2015-03-05 04:09:30

+0

1,“'在整个文件有一行没有'who'属性我(谁)''is.null() – bergant 2015-03-05 08:03:17

+0

答案处理只是这种情况下,是的更新。 ,刚刚抓住它,仍然是这样一个R noob,但我会得到这个窍门。非常感谢你的帮助! – galenc 2015-03-05 08:17:44