Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将XML更高的节点属性、节点值和文件名获取到R data.frame_Xml_R_Dataframe - Fatal编程技术网

将XML更高的节点属性、节点值和文件名获取到R data.frame

将XML更高的节点属性、节点值和文件名获取到R data.frame,xml,r,dataframe,Xml,R,Dataframe,我已经和它斗争了很长一段时间,无法让它工作,所以我在这里发布。我不是一个高级的R用户,但我正在学习并慢慢前进。我还没有从Stackoverflow中找到一个可以适应这种情况的示例,这些示例似乎具有不同的结构,不需要循环每个节点的每个更高级别属性。或者这就是我现在理解差异的原因。问题与类似,但文件结构不同。现在我基本上用了 假设我有大量小XML文件,其结构如下所示。它们有file1.xml、file2.xml等名称。因此,file1.xml应该是: <NODE> <SUBNODE

我已经和它斗争了很长一段时间,无法让它工作,所以我在这里发布。我不是一个高级的R用户,但我正在学习并慢慢前进。我还没有从Stackoverflow中找到一个可以适应这种情况的示例,这些示例似乎具有不同的结构,不需要循环每个节点的每个更高级别属性。或者这就是我现在理解差异的原因。问题与类似,但文件结构不同。现在我基本上用了

假设我有大量小XML文件,其结构如下所示。它们有file1.xml、file2.xml等名称。因此,file1.xml应该是:

<NODE>
<SUBNODE TYPE="WORDS" SPEAKER="person1">
<WORD>word1</WORD>
<WORD>word2</WORD>
<WORD>word3</WORD>
</SUBNODE>
<SUBNODE TYPE="WORDS" SPEAKER="person2">
<WORD>word4</WORD>
<WORD>word5</WORD>
<WORD>word6</WORD>
</SUBNODE>
</NODE>
<NODE>
<SUBNODE TYPE="WORDS" SPEAKER="person3">
<WORD>word7</WORD>
<WORD>word8</WORD>
<WORD>word9</WORD>
</SUBNODE>
<SUBNODE TYPE="WORDS" SPEAKER="person4">
<WORD>word10</WORD>
<WORD>word11</WORD>
<WORD>word12</WORD>
</SUBNODE>
</NODE>
我可以使用以下命令将所有单词的列表放入一个数据框中:

library(XML)
library(plyr)
xmlfiles <- list.files(pattern = "*.xml")
dat <- ldply(seq(xmlfiles), function(i){
    doc <- xmlTreeParse(xmlfiles[i], useInternal = TRUE)
    Word <- xpathSApply(doc, "//SUBNODE[@TYPE='WORDS']/WORD", xmlValue)
    return(data.frame(Word))
})
然后,我也经常会出现如下错误:

"Error in UseMethod("xmlValue") : 
no applicable method for 'xmlValue' applied to an object of class "c('XMLInternalDocument', 'XMLAbstractDocument')"
或者我得到了一个错误,它们的长度不同,它们当然是,因为说话者比单词少。我尝试过很多东西,但我在这里只发布了我“最成功”的方法。我知道我需要一个函数,将上面节点中的每个单词与speaker属性进行某种程度的匹配,只是将它们提取到它们自己的列表中没有帮助,我想现在很幸运,在这个示例中,说话人和单词的数量是匹配的,所以它们像上面的数据框一样放在一起

然后我仍然需要将文件名放在一列中,因为它们包含一段我在XML文件本身中没有的信息。无论如何,这是我问题中最不重要的方面。我处理的实际文件要复杂得多,这就是为什么我在文件中有一些不必要的结构,比如子节点类型,等等


谢谢你的帮助

一种可能是获取所有相关值(
xml
是我认为您的
doc

找到扬声器并将所有内容转换为简单的字符向量

isSpeaker = sapply(x, is, "XMLAttributeValue")
x[!isSpeaker] = sapply(x[!isSpeaker], xmlValue)
x = unlist(x, use.names=FALSE)
然后咀嚼结果

r = rle(isSpeaker)
data.frame(Speaker=rep(x[isSpeaker], r$length[!r$value]), Word=x[!isSpeaker])

(我不认为这对没有文字的演讲者来说是可靠的,但那会是什么样的演讲者?

一种可能是获取所有相关值(
xml
是我认为你的
doc

找到扬声器并将所有内容转换为简单的字符向量

isSpeaker = sapply(x, is, "XMLAttributeValue")
x[!isSpeaker] = sapply(x[!isSpeaker], xmlValue)
x = unlist(x, use.names=FALSE)
然后咀嚼结果

r = rle(isSpeaker)
data.frame(Speaker=rep(x[isSpeaker], r$length[!r$value]), Word=x[!isSpeaker])

(我不认为这对没有文字的演讲者来说是可靠的,但那会是什么样的演讲者?

我可能会尝试循环文件并解析getNodeSet。我不经常使用ldply,但是您可以用它来替换循环

xmlfiles <- list.files(pattern = "*.xml")
n <- length(xmlfiles)
dat <- vector("list", n)
for(i in 1:n){
   doc <- xmlParse(xmlfiles[i])
   nodes <- getNodeSet(doc, "//SUBNODE")
   x<- lapply(nodes, function(x){ data.frame(
     Filename = xmlfiles[i],
     Speaker= xpathSApply(x, "." , xmlGetAttr, "SPEAKER"),
     Word= xpathSApply(x, ".//WORD" , xmlValue) )})
     dat[[i]] <- do.call("rbind", x)
}
do.call("rbind", dat)

xmlfiles我可能会尝试遍历这些文件并解析getNodeSet。我不经常使用ldply,但是您可以用它来替换循环

xmlfiles <- list.files(pattern = "*.xml")
n <- length(xmlfiles)
dat <- vector("list", n)
for(i in 1:n){
   doc <- xmlParse(xmlfiles[i])
   nodes <- getNodeSet(doc, "//SUBNODE")
   x<- lapply(nodes, function(x){ data.frame(
     Filename = xmlfiles[i],
     Speaker= xpathSApply(x, "." , xmlGetAttr, "SPEAKER"),
     Word= xpathSApply(x, ".//WORD" , xmlValue) )})
     dat[[i]] <- do.call("rbind", x)
}
do.call("rbind", dat)

xmlfiles这也很有效!非常感谢。由于某些原因,我在“do.call(“rbind”,dat”)“do.call中的错误(“rbind”,“dat”):第二个参数必须是一个列表”你对为什么会发生这种情况有什么建议吗?我应该检查一下这个do.call(“rbind”)-东西是什么。它对do.call(“rbind”,dat)很有吸引力),并且很容易将其应用到我的实际数据中。谢谢!很抱歉出现了这个错误-它在上面被修复了这也很好!谢谢!出于某种原因,我在“do.call(“rbind”,dat”)“do.call中的错误(“rbind”,“dat”):第二个参数必须是一个列表”你有什么建议为什么会发生这种情况吗?我应该检查一下这是怎么回事。它与do.call(“rbind”,dat)的工作原理类似,很容易将其应用到我的真实数据中。谢谢对不起,上面的错误已经纠正了
xmlfiles <- list.files(pattern = "*.xml")
n <- length(xmlfiles)
dat <- vector("list", n)
for(i in 1:n){
   doc <- xmlParse(xmlfiles[i])
   nodes <- getNodeSet(doc, "//SUBNODE")
   x<- lapply(nodes, function(x){ data.frame(
     Filename = xmlfiles[i],
     Speaker= xpathSApply(x, "." , xmlGetAttr, "SPEAKER"),
     Word= xpathSApply(x, ".//WORD" , xmlValue) )})
     dat[[i]] <- do.call("rbind", x)
}
do.call("rbind", dat)