R中的XML解析 - 子节点属性的递归体面
Posted
技术标签:
【中文标题】R中的XML解析 - 子节点属性的递归体面【英文标题】:XML parsing in R - recursive decent on attributes of children nodes 【发布时间】:2014-12-11 17:34:22 【问题描述】:我是 XML 解析的新手,并且学习过各种教程。现在,我正在尝试从 PsychInfo 数据库的搜索结果中解析 XML 文档。基本上,我想要的是将每篇文章的属性保存到可以轻松分析的数据框中。但是,我的 XML 文档有一个我不完全理解的嵌套结构。
这是我的具体问题。 根据 MR.FLICK 的建议编辑
我想访问 XML 文件中子节点的所有属性——例如,文章标题 (btl)、发布日期 (pubinfo)、作者 (au) 等。当我应用函数 @987654322 @ 到根节点,它只返回一项。正如 MrFlick 在评论中所建议的那样,我需要设置某种形式的递归下降来提取这些其他属性。然后将这些其他属性保存在数据框中。
下面提供的是我一直在使用的代码,然后是我希望实现的具体示例。
library(XML)
library(RCurl)
read.url <- function(url, ...)
tmpFile <- tempfile()
download.file(url, destfile = tmpFile, method = "curl")
url.data <- xmlParse(tmpFile, ... )
return(url.data)
这是 Gist 上数据的完整路径。 (尝试使用 bit.ly 进行缩短会导致无法正确阅读。任何有关解决此次要问题的建议都会有所帮助!)
DF https://gist.githubusercontent.com/beperron/e75a17e653ed668211bd/raw/2c4c31e0200c080094353d318e8e0ee59dce60fa/PsychInfo")
以下代码首先检查它是否属于 XML 文档类。随后的代码提取根节点和子节点。
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)
如前所述,xmlAttrs
仅返回一项,即 resultID。我需要的信息嵌套在每个孩子中。我正在寻求基于以下标签提取的数据框:rec resultID、btl、jtl、pubinfo、doi。我想提取更多信息,但这肯定足以让我朝着正确的方向前进。
ID 1
title "Development and evaluation of the Arabic Filial Piety Scale"
journal "Research on Social Work Practice"
pubdate "2010-07-01"
doi "10.1177/1049731510369495"
【问题讨论】:
正如所写的这个问题似乎过于广泛。目前还不清楚你的问题到底是什么。pietyScale
节点是第一个 <rec>
节点,它只有一个属性 (resultID="1"
)。如果您还想提取子节点的所有属性,则必须设置某种形式的递归下降。 xmlAttrs
仅访问您作为参数传递的特定节点的属性。也许创建一个较小的示例输入并给出您想要的显式输出会有所帮助。
@MrFlick 感谢您的评论。我将按照您的建议编辑我的问题...
【参考方案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 之前检查节点集是否存在。
【讨论】:
以上是关于R中的XML解析 - 子节点属性的递归体面的主要内容,如果未能解决你的问题,请参考以下文章
GroovyXml 反序列化 ( 使用 XmlParser 解析 Xml 文件 | 获取 Xml 文件中的节点和属性 | 获取 Xml 文件中的节点属性 )