使用父节点属性将 XML 加载到 R 中的 Dataframe
Load XML to Dataframe in R with parent node attributes
我有一个 XML 文件(TEI 编码的播放),我想在 R 中将其处理成 data.frame,其中 data.frame 的每一行都包含一行剧本、台词、该台词的发言人、场景编号和场景类型。 XML 文件的主体如下所示(但更长):
<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>
这个问题似乎与 here and here 提出的问题类似,但我的 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)
这个 returns 一个 data.frame 与 'scene number'、'scene type' 和 'speaker' 完好无损,但我不知道如何分解它到每一行(并获取关联的行号)。
我尝试将文件作为列表导入(通过 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
我有一个 XML 文件(TEI 编码的播放),我想在 R 中将其处理成 data.frame,其中 data.frame 的每一行都包含一行剧本、台词、该台词的发言人、场景编号和场景类型。 XML 文件的主体如下所示(但更长):
<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>
这个问题似乎与 here and here 提出的问题类似,但我的 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)
这个 returns 一个 data.frame 与 'scene number'、'scene type' 和 'speaker' 完好无损,但我不知道如何分解它到每一行(并获取关联的行号)。
我尝试将文件作为列表导入(通过 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