我正在使用 R 和 XML 包解析瑞典图书馆目录。使用库的 API,我从包含我的查询的 url 中获取 XML。
我想使用 xPath 查询来解析每条记录,但是我对 XML 包的 xPath 所做的一切都返回空白列表,除了“//*”之外的所有内容。我不是 xml 解析和 xPath 方面的专家,但我怀疑它与我的 API 返回给我的 xml 有关。
这是目录中单个帖子的简单示例:
library(XML)
example.url <- "http://libris.kb.se/sru/swepub?version=1.1&operation=searchRetrieve&query=mat:dok&maximumRecords=1&recordSchema=mods"
doc = xmlParse(example.url)
# Title
works <- xmlRoot(doc)[[4]][["record"]][["recordData"]][["mods"]][["titleInfo"]][["title"]][[1]]
doesntwork <- getNodeSet(doc, "//title")
# The only xPath that returns anything
onlythisworks <- getNodeSet(doc, "//*")
如果这与命名空间( as these answers sugests )有关,我所理解的只是 API 返回的数据似乎在初始标签中定义了命名空间,我可以使用它,但这对我没有帮助:
# Namespaces are confusing:
title <- getNodeSet(xmlRoot(doc), "//xsi:title", namespaces = c(xsi = "http://www.w3.org/2001/XMLSchema-instance"))
这是(再次)the example return data我正在尝试解析。
最佳答案
您必须使用正确的命名空间。
尝试以下
doesntwork <- getNodeSet(doc, "//mods:title")
#[[1]]
#<title>Horizontal Slot Waveguides for Silicon Photonics Back-End Integration [Elektronisk resurs]</title>
#
#[[2]]
#<title>TRITA-ICT/MAP AVH, 2014:17 \
# </title>
#
#attr(,"class")
#[1] "XMLNodeSet"
顺便说一句:我通常通过
nsDefs=xmlNamespaceDefinitions(doc,simplify = TRUE,recursive=TRUE)
但这会在您的情况下引发错误。它提示有
different URIs for the same name space prefix
.根据this site这似乎不是很好的编码风格。
根据OP的评论更新
我自己不是
xml
专家,但这是我的看法:您可以通过 <tag xmlns=URI>
定义默认命名空间.非默认命名空间的格式为 <tag xmlns:a=URI>
与 a
是各自的命名空间名称。您的文档的问题是有两个不同的默认命名空间。第一个在
<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/" ... >
.第二个在<mods xmlns="http://www.loc.gov/mods/v3" ... >
.此外,您会在第一个标记中找到第二个默认命名空间 URI,即 xmlns:mods="http://www.loc.gov/mods/v3"
。 (它是非默认的)。这似乎相当困惑。现在,<title>
标签位于 <mods>
内标签。我认为 <mods>
中定义的默认命名空间被 searchRetrieveResponse
的非默认命名空间覆盖(因为它们具有相同的 URI)。所以虽然<mods>
并且所有以下标签(如 <title>
)似乎都有默认命名空间,它们实际上具有 xmlns:mods
命名空间。但这不适用于标签 <numberOfRecords>
(因为它在 <mods>
之外)。您可以通过以下方式访问此节点getNodeSet(doc, "//ns:numberOfRecords",
namespaces = c(ns="http://www.loc.gov/zing/srw/"))
在这里,您提取
<searchRetrieveResponse>
中定义的默认命名空间并给它一个名字(在我们的例子中是 ns
)。然后,您可以在 xPath 查询中显式使用默认命名空间名称。
关于r - 为什么 "//*"是我使用 XML 包在 R 中解析此 XML 时唯一有效的 xPath 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34749655/