r - 为什么 "//*"是我使用 XML 包在 R 中解析此 XML 时唯一有效的 xPath 查询?

标签 r xpath xml-parsing xml-namespaces

我正在使用 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/

相关文章:

r - R中的历史分解

r - 如何使用 dplyr 中的累积函数在 R 中按行重现数据帧或 tibble?

javascript - 获取 HTML/DOM 的所有元素的 XPATH

Oracle xmltable解析返回LPX-00209

python - 从xml文件中检索数据到mysql数据库

java - 使用 DOM4J 将 XML 子元素添加到 ArrayList

r - SuperImpose 直方图适合一张图 ggplot

r - 无法在 Debian Wheezhy 上编译简单的 JNI 程序

python - xpath:如何在 <strong> 元素之前、之中和之后提取文本

java - 寻找 JDOM2 XPath 示例