Выражение XPath - PullRequest
       2

Выражение XPath

3 голосов
/ 13 сентября 2011

У меня есть XML-файл, подобный следующему:

<lib:library>    
    <lib:book> XML </lib:book>
    <lib:book> XPath </lib:book>
    <lib:book> XSLT </lib:book>
    <lib:book> Java </lib:book>
    <lib:book> C++ </lib:book>    
</lib:library>

, и я хочу пойти в книгу [2] ... Конечно, я могу сделать что-то вроде // lib: Book [2] ...и это работает.Может случиться, что в одном и том же XML-файле у меня есть, например, то же имя тега, но другое пространство имен;в этом случае мое выражение XPath не работает ...

Я могу заменить его следующим образом:

// * [local-name () = "book"]

Это выражение возвращает всю книгу, содержащуюся в файле XML ... но что, если я хочу получить число [2] ... как мне переписать выражение XPath, добавив условие о числе?Конечно, я не хочу рассматривать пространства имен, он должен быть действительным для каждого используемого пространства имен.

Спасибо, Лука

Ответы [ 2 ]

4 голосов
/ 14 сентября 2011

Текущий выбранный ответ неверен .

На самом деле //someExpression[2] может выбрать много узлов.

Например, если у нас есть следующий XML-документ :

<lib:library xmlns:lib="UNDEFINED!!!">
  <topic name="XML">
      <lib:book> XML </lib:book>
  </topic>
  <topic name="XPath">
      <lib:book> XPath </lib:book>
  </topic>
  <topic name="XSLT">
     <lib:book> XSLT1 </lib:book>
     <lib:book> XSLT2 </lib:book>
  </topic>
  <topic name="Imperative PLs">
     <lib:book> Java </lib:book>
     <lib:book> C++ </lib:book>
  </topic>
</lib:library>

При выражении :

   //*[local-name() = "book"][2]

сравнивается с указанным выше документом, выбраны два узла (и ни один из них не является вторым узлом в документе с требуемыми свойствами):

<lib:book xmlns:lib="UNDEFINED!!!"> XSLT2 </lib:book>
<lib:book xmlns:lib="UNDEFINED!!!"> C++ </lib:book>

Решение : Один из способов выбора N-го (скажем, 2-го) узла (скажем, lib:book) во всем документе:

   (//*[local-name() = "book"])[2]

Когда это выражение оценивается в приведенном выше документе, выбирается правильный единственный узел:

<lib:book xmlns:lib="UNDEFINED!!!"> XPath </lib:book>

Пояснение : Как определено в Рекомендациях W3C XPath :

// - это сокращение от /descendant-or-self::node()/

Таким образом:

//someName[2]

является сокращением для:

/descendant-or-self::node()/someName[2]

, и это выбирает любой элемент в документе с именем someName, который является вторым someName дочерним элементом его родителя.

Другими словами, оператор [] связывается сильнее (имеет более высокий приоритет), чем псевдо-оператор //. Вот почему нам нужны скобки, чтобы переопределить приоритет оператора по умолчанию.

0 голосов
/ 13 сентября 2011

А как насчет //*[local-name() = "book"][2]?это должно работать.

Как отмечается в комментариях, вам следует избегать использования //, если вы действительно не уверены в том, что делаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...