如何使用R的XML库使用xpath查询?

时间:2010-10-06 20:25:26

标签: xml r xpath xquery

xml文件包含以下代码段:

<?xml version="1.0"?>
<PC-AssayContainer
    xmlns="http://www.ncbi.nlm.nih.gov"
    xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
    xs:schemaLocation="http://www.ncbi.nlm.nih.gov ftp://ftp.ncbi.nlm.nih.gov/pubchem/specifications/pubchem.xsd"
>
....
    <PC-AnnotatedXRef>
      <PC-AnnotatedXRef_xref>
        <PC-XRefData>
          <PC-XRefData_pmid>17959251</PC-XRefData_pmid>
        </PC-XRefData>
      </PC-AnnotatedXRef_xref>
    </PC-AnnotatedXRef>

我尝试使用xpath的全局搜索解析它,并尝试使用一些命名空间:

library('XML')
doc = xmlInternalTreeParse('http://s3.amazonaws.com/tommy_chheng/pubmed/485270.descr.xml')
>xpathApply(doc, "//PC-XRefData_pmid")
list()
attr(,"class")
[1] "XMLNodeSet"
> getNodeSet(doc, "//PC-XRefData_pmid")
list()
attr(,"class")
[1] "XMLNodeSet"
> xpathApply(doc, "//xs:PC-XRefData_pmid", ns="xs")
list()
> xpathApply(doc, "//xs:PC-XRefData_pmid", ns= c(xs = "http://www.w3.org/2001/XMLSchema-instance"))
list()

xpath不应该匹配:

<PC-XRefData_pmid>17959251</PC-XRefData_pmid>

2 个答案:

答案 0 :(得分:9)

由于默认命名空间是NIH(其URI是“http://www.ncbi.nlm.nih.gov”),<PC-XRefData_pmid>(以及XML文档中没有命名空间的所有其他元素)前缀)在NIH名称空间中。

因此,要将它们与XPath匹配,您需要告诉XPath处理器您将使用哪个前缀作为NIH名称空间,并且需要在XPath中使用该前缀。

所以,在不知道R的情况下,我会尝试

xpathApply(doc, "//nih:PC-XRefData_pmid",
   ns= c(nih = "http://www.ncbi.nlm.nih.gov"))

或者

getNodeSet(doc, "//*[local-name() = 'PC-XRefData_pmid']")

因为后者绕过名称空间。

仅仅因为XML文档将NIH名称空间声明为默认名称并不意味着XPath处理器会知道这一点。在XML信息模型中,名称空间前缀并不重要。因此,当我解析XML文档时,NIH名称空间是否绑定到“nih:”前缀或“snizzlefritz”并不重要:“前缀或”“(默认)前缀。 XML解析器或XPath处理器不应该知道什么前缀绑定到XML文档中的哪个命名空间。特别是因为在同一文档中的不同位置可能有几个不同的前缀绑定到同一名称空间...反之亦然。因此,如果您希望让XPath表达式与命名空间中的元素匹配,则必须将该命名空间声明为XPath处理器。

编辑:有一些警告,由@Jim Pivarski提供:

  • “doc”必须是xml节点,而不是文档(类“XMLNode”或“XMLInternalElementNode”,而不是“XMLDocument”或“XMLInternalDocument”)。
  • 至少在Jim的版本(XML_3.93-0)中,命名参数是“名称空间”,而不是“ns”。

因此,如果“doc”是文档类的实例,那么正确的解决方案是:

xpathApply(xmlRoot(doc), "//nih:PC-XRefData_pmid",
   namespaces = c(nih = "http://www.ncbi.nlm.nih.gov"))

答案 1 :(得分:1)

这是常见问题。

这://PC-XRefData_pmid

意味着:文档中没有名称空间或空名称空间的任何PC-XRefData_pmid

这并不代表默认命名空间

下的文档中的任何PC-XRefData_pmid

另外,您的文档示例未完成,但看起来您的PC-XRefData_pmid元素位于http://www.ncbi.nlm.nih.gov命名空间