R中的XML解析 - 递归的子节点属性

时间:2014-12-11 17:34:23

标签: xml r xml-parsing

我是XML解析的新手,并且已经完成了各种教程。现在,我正在尝试从PsychInfo数据库的搜索结果中解析XML文档。基本上,我想要的是保存在数据框中的每篇文章的属性,可以轻松分析。但是,我的XML文档有一个我不完全理解的嵌套结构。

这是我的具体问题。 根据MR.FLICK的建议进行编辑

我想访问XML文件中子节点的所有属性 - 例如,文章标题(btl),发布日期(pubinfo),作者(au)等。当我应用函数{{ 1}}到根节点,它只返回一个项目。正如MrFlick在评论中所建议的那样,我需要建立某种形式的递归下降来提取这些其他属性。然后,这些其他属性将保存在数据框中。

下面提供的是我一直在使用的代码,后面是我希望实现的具体示例。

xmlChildren

以下是Gist上数据的完整路径。 (尝试缩短bit.ly可以防止它被正确读取。任何解决这个次要问题的建议都会有所帮助!)

DF< - read.url(“https://gist.githubusercontent.com/beperron/e75a17e653ed668211bd/raw/2c4c31e0200c080094353d318e8e0ee59dce60fa/PsychInfo”)

以下代码首先检查它是否属于XML文档类。后续代码提取根节点和子节点。

library(XML)
library(RCurl) 

read.url <- function(url, ...){
    tmpFile <- tempfile()
    download.file(url, destfile = tmpFile, method = "curl")
    url.data <- xmlParse(tmpFile, ... )
    return(url.data)
    }

此代码检查根节点的第一个子节点:

class(DF) #Check to see it is an XML document
RootNode <- xmlRoot(DF) #Obtain root node
ChildNodes <- xmlChildren(RootNode) #Obtain children of root

如上所述,pietyScale <- ChildNodes[[1]] xmlName(pietyScale) xmlSize(pietyScale) xmlAttrs(pietyScale) xmlValue(pietyScale) xmlChildren(pietyScale) xmlAttrs(pietyScale) 只返回一个项目resultID。我需要的信息嵌套在每个孩子中。我想要根据以下标记提取的数据框:rec resultID,btl,jtl,pubinfo,doi。我想提取更多信息,但这肯定足以让我朝着正确的方向前进。

xmlAttrs

1 个答案:

答案 0 :(得分:1)

在此特定文档中,您将访问元素文本,而不是属性。我认为不需要“递归下降”。

这似乎产生了你想要的东西:

get.data <- function(id) {
  tags <- c("bkinfo","jinfo","dt","artinfo/ui")
  data <- sapply(tags,function(tag){
    nodes <- DF[paste(sprintf("//rec[@resultID=%s]",id),tag,sep="//")]
    if (length(nodes)>0) xmlValue(nodes[[1]]) else NA
  })
  c(id,data)
}
ids    <- unlist(DF["//rec/@resultID"])
result <- as.data.frame(t(sapply(ids,get.data)),row.names=NA)
colnames(result) <- c("ID","title","journal","pubdate","doi")
t(result[1,])
#         1                                                             
# ID      "1"                                                           
# title   "Development and evaluation of the Arabic Filial Piety Scale."
# journal "Research on Social Work Practice1049731515527581"            
# pubdate "20100701"                                                    
# doi     "10.1177/1049731510369495"

所以这里result是一个数据框,每个ID有一行,每个数据有一列(ID,标题等)。您需要将数据从字符转换为适当的类。

需要注意的是,并非所有这些数据都存在于每个resultID中(例如,doi字段有时会丢失)。因此,我们需要在尝试提取xmlValue之前检查节点集是否存在。