XPath - это фундаментальная стандартная технология W3C, которую можно использовать для выбора различных элементов в XML-документе. Он также широко используется в XSLT, XQuery и других. В этом кратком руководстве мы рассмотрим, как извлекать данные из XML-документов с помощью XPath.

Для тестирования вы можете использовать любые онлайн-тестеры XPath. Есть несколько хороших из них, которые вы можете найти, когда загуглите "тестировщики XPath". Некоторые IDE, такие как Eclipse, также имеют плагины, которые можно использовать для тестирования XPath с исходным XML.

Хорошо, давайте начнем со следующего образца XML.

<?xml version="1.0" encoding="UTF-8"?>
<records>
 <contact>
  <name>Steve</name>
  <city>San Francisco</city>
  <state>California</state>
  <phone type="work">+1 675 657-8765</phone>
  <phone type="home">+1 675 123-8865</phone>
  <relatives>
   <relative>
    <name>Julia</name>
    <relationship>Spouse</relationship>
   </relative>
   <relative>
    <name>Peter</name>
    <relationship>Father</relationship>
   </relative>
   <relative>
    <name>Diana</name>
    <relationship>Mother</relationship>
   </relative>
  </relatives>
 </contact>
 <contact>
  <name>Tom</name>
  <city>New York City</city>
  <state>New York</state>
  <phone type="work">+1 875 637-0765</phone>
  <phone type="home">+1 855 777-9965</phone>
  <relatives>
   <relative>
    <name>Ed</name>
    <relationship>Father</relationship>
   </relative>
   <relative>
    <name>Catherine</name>
    <relationship>Mother</relationship>
   </relative>
  </relatives>
 </contact>
 <contact>
  <name>Mark</name>
  <city>Boston</city>
  <state>Massachussets</state>
  <phone>+1 655 727-9217</phone>
  <relatives>
   <relative>
    <name>Stephanie</name>
    <relationship>Spouse</relationship>
   </relative>
  </relatives>
 </contact>
</records>

Все выражения XPath для выбора узла принимают формат имя оси :: nodetest [предикат].

имена осей могут иметь одно из следующих значений: self, parent, ancestor, ancestor-or-self, предшествующий, предыдущий-sibling, дочерний, дочерний, потомок-or-self, following, following-sibling, attribute, namespace.

По умолчанию дочерняя ось применяется относительно текущего узла.

/ - соответствует всему документу. Таким образом будет возвращен весь документ из корневого элемента
/ records - соответствует тегу records. В данном случае это корневой тег, он будет таким же, как указано выше
/ records / contact - вы получите весь набор контактов. Поскольку дочерняя ось является осью по умолчанию, последний XPath такой же, как / child :: records / child :: contact.

. - (символ точки) относится к текущему контексту узла. Таким образом, / records и / records /. дадут одинаковые результаты
.. - (две точки) относятся к родительскому контексту. текущего контекста. Попробуйте / records / contact / name / .. то же самое, что / records / contact (также равно / records / contact / name / parent :: *

Теперь вы можете понять, как применить к узлу другую ось.

/ records / contact / name - соответствует всем ‹name› в разделе ‹contact› в ‹records›.

<name>Steve</name>
<name>Tom</name>
<name>Mark</name>

/ records / contact / name / text () - получает текстовое содержимое совпадающих элементов.

SteveTomMark

Чтобы получить только элемент имени, вы можете использовать ниже

(/ records / contact / name) [1]

<name>Steve</name>

Чтобы получить последний

(/ записи / контакт / имя) [последняя ()]

<name>Mark</name>

Чтобы получить текст фамилии

(/ записи / контакт / имя) [последняя ()] / текст ()

Mark

Чтобы получить все теги ‹name›

// имя - обратите внимание, что // используется для дерева поиска. Это то же самое, что и потомок :: имя.

<name>Steve</name>
<name>Julia</name>
<name>Peter</name>
<name>Diana</name>
<name>Tom</name>
<name>Ed</name>
<name>Catherine</name>
<name>Mark</name>
<name>Stephanie</name>

// * [local-name () = ‘name’] эквивалентно // name

// name [contains (text (), ‘er’)] - // Находит все имена, содержащие текст ‘er’

// телефон - выберите все телефонные теги.

<phone type=”work”>+1 675 657–8765</phone>
<phone type=”home”>+1 675 123–8865</phone>
<phone type=”work”>+1 875 637–0765</phone>
<phone type=”home”>+1 855 777–9965</phone>
<phone>+1 655 727–9217</phone>

// phone [@ type] - найти все телефоны с типом атрибута
Подробный формат, указанный выше, такой же, как // phone [attribute :: type]
@ - это сокращение от attribute ::

<phone type=”work”>+1 675 657–8765</phone>
<phone type=”home”>+1 675 123–8865</phone>
<phone type=”work”>+1 875 637–0765</phone>
<phone type=”home”>+1 855 777–9965</phone>

// phone [@ type = 'work'] - получать телефоны только с атрибутом 'work'
То же, что и // phone [attribute :: type ['work' ]]
attribute :: - это ось, тип - это nodetest, а работа - это предикат.

<phone type=”work”>+1 675 657–8765</phone>
<phone type=”work”>+1 875 637–0765</phone>

/ records / contact / relative / relative [Relationship = ’Spouse’] / name - получите имена всех контактных супругов.

Немного арифметики

count (/ records / contact) +1 - количество контактных узлов + 1
/ records / contact [last () - 1] - контактный узел перед последний контактный узел

Это ни в коем случае не исчерпывающее руководство по XPath. Но я считаю, что это поможет освежить основы XPath. В качестве полного руководства я рекомендую несколько книг по XPath (и XSLT), которые более подробно относятся к этой теме.