Как я могу использовать запрос xpath с помощью XML-библиотеки R?

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 ответов


поскольку пространство имен по умолчанию является 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"))

или иначе!--5-->

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

поскольку последний обходит пространства имен.

только потому, что XML-документ объявляет пространство имен NIH по умолчанию, не означает, что процессор XPath будет знать это. В информационной модели XML префиксы пространства имен не имеют значения. поэтому, когда я анализирую XML-документ, не должно иметь значения, связано ли пространство имен NIH с префиксом" nih: "или префиксом" snizzlefritz: "или префиксом "" (по умолчанию). Синтаксический анализатор XML или Процессор XPath не должен знать, какой префикс привязан к какому пространству имен в XML-документе. Тем более, что в одном документе может быть несколько разных префиксов, привязанных к одному пространству имен в разных местах... и наоборот. Поэтому, если вы хотите, чтобы выражение XPath соответствовало элементу в пространстве имен, вы должны объявить это пространство имен процессору XPath.

Edit: есть несколько предостережений, внесенных @Jim Pivarski:

  • "doc "должен быть узлом xml, а не документом (класс" XMLNode "или" XMLInternalElementNode", а не" XMLDocument "или"XMLInternalDocument").
  • по крайней мере, в версии Джима (XML_3.93-0), именованный аргумент - "пространства имен", а не "ns".

поэтому, если " doc " является экземпляром класса документа, правильным решением является:

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

это FAQ.

Это: //PC-XRefData_pmid

означает: любой PC-XRefData_pmid в документе ни пустого пространства имен

это не значит никаких PC-XRefData_pmid в документе под пространством имен по умолчанию

кроме того, ваш образец документа не завершен, но он выглядит как ваш PC-XRefData_pmid элемент под http://www.ncbi.nlm.nih.gov пространство имен