XPath
XPath, або XML Path Language — це мова запитів, для вибору вузлів з XML документів, або для обчислення величин (наприклад, рядкових, числових або булевих) на основі вмісту XML документа. XPath був розроблений World Wide Web Consortium (W3C).[1]
XPath | |
---|---|
Парадигма | Мова запитів |
Дата появи | 1999 |
Розробник | W3C |
Останній реліз | 3.0 (2014-04-08) |
Основні реалізації | C#, Java, JavaScript |
Під впливом від | XSLT, XPointer |
Вплинула на | XML Schema, XForms |
XPath у Вікісховищі |
Огляд
Мова XPath основана на представленні XML документа у вигляді дерева, і надає можливість навігації по дереву, та вибору його вузлів за різними критеріями.[2][3] Популярно (проте не в офіційній специфікації) XPath-вирази називають просто «XPath».
На початку покликаний надати загальний синтаксис і модель поведінки між XPointer та XSLT, XPath швидко здобув визнання розробників як мова малих запитів, і його підмножини використовуються в інших W3C специфікаціях. Це, наприклад, XML Schema, XForms і Internationalization Tag Set (ITS).
Версії
На сьогоднішній день є три версії мови XPath. Остання — версія 3.0 (10.04.2014), але XPath 1.0 все ще є найбільш вживаною.[1]
- XPath 1.0 стала рекомендацією 16 листопада 1999 року і широко впроваджена і використовується сама по собі (на зразок таких мов, як Java, C#, Python, JavaScript) або ж входить до інших мов (наприклад, XSLT, XProc, XML Schema, XForms).
- XPath 2.0 стала рекомендацією 23 січня 2007 року, була впроваджена значною мірою, але все ж не настільки широко використовувалася, як XPath 1.0. Специфікація цієї версії набагато більша ніж в XPath 1.0, змінено деякі фундаментальні концепції мови, як наприклад, система типізації.
- Найбільш помітною зміною є те, що XPath 2.0 побудована на основі XQuery and XPath Data Model, що має значно багатшу систему типізації.[4] Кожне значення тепер є послідовністю (одне атомарне значення або вузол розглядаються як послідовність одиничної довжини). Множини вузлів, характерні для XPath 1.0, замінено послідовностями вузлів, що можуть бути в будь-якому порядку.
- Щоб підтримати більші набори типів, XPath 2.0 пропонує неймовірно поширену сукупність функції та операторів.
- XPath 2.0 є насправді підмножиною XQuery 1.0. Вони використовують однакову модель даних (XDM). Це дозволяє виразу
for
, що є урізаною версією «FLWOR» виразів в XQuery. Можливо описати мову, перераховуючи частини XQuery, що не включає: головні приклади, які є прологами запиту, елемент та атрибут конструкторів, іншу частину «FLWOR» синтаксису, і виразtypeswitch
.
- XPath 3.0 стала рекомендацією 8 квітня 2014 року.[5] Найбільш значним нововведенням є підтримка функцій як значень першого класу. Щоб дізнатись більше про XPath 3.0, дивись[6]. XPath 3.0 є підмножиною XQuery 3.0, а також найсучаснішою реалізацією, що існує, як частина рушія XQuery станом на квітень 2014 року.
Синтаксис і семантика (XPath 1.0)
Найбільш важливий тип виразу в XPath є шлях до файлу. Шлях до файлу складається з послідовності каталогів. Кожен каталог містить три компоненти:
- вісь
- визначення вузла
- предикати (може бути декілька, або не бути взагалі).
Вираз XPath обчислюється по відношенню до контекстного вузла. Осі, такий як 'child' або 'descendant', описують шлях для навігації від контекстного вузла. Визначення вузла і предикати використовуються для фільтрування вузлів, означених віссю. Наприклад, визначення вузла 'A' вимагають від інших напрямлених вузлів мати позначку 'A'. Предикат може використовуватися з метою зазначити, що вибрані вузли мають певні властивості (самовизначені XPath виразами).
Синтаксис XPath поставляється в двох варіантах: скорочений синтаксис (що є більш компактним і дозволяє XPath виразам бути легко написаними і прочитаними, використовуючи інтуїтивні і в багатьох випадках звичні характеристики і конструктори. Розширений синтаксис є менш компактний, але дозволяє описати більше опцій, є більш наочний.
Скорочений синтаксис
Компактне позначення дозволяє багато за замовчуванням і скорочень для загальних випадків. Для даного XML документу
<A>
<B>
<C/>
</B>
</A>
найпростіший XPath вираз
/A/B/C
обирає ті елементи C, що є дітьми B, що в свою чергу є дітьми A, що є найбільш віддаленим елементом (в даному разі коренем) цього XML документу. Синтаксис XPath є розроблений, щоб імітувати URI і синтаксис шляху до файлу.
Більш складні вирази можуть бути сконструйовані вибором осі, відмінної від 'child' ('child' — вісь за замовчуванням), даних вузла (не просто імені) чи предикатів, що можуть бути записані в квадратних дужках на кожному кроці. Наприклад, вираз
A//B/*[1]
вибирає першу дитину ('*[1]
'), не зважаючи на ім'я, кожного елемента B, що в свою чергу є або дитиною, або більш дальнім нащадком ('//
') елемента A, що є дитиною поточного контекстного вузла (вираз не починається з '/
'). Зверніть увагу, що предикат [1]
пов'язує більш щільно, ніж оператор /
. Щоб вибрати перший вузол, вибраний виразом A//B/*
, напишіть (A//B/*)[1]
. Зверніть також увагу на те, що значення індексу в предикатах XPath (технічно, «позиції» близькість від XPath наборів вузлів) починається з 1, а не з 0, як прийнято в таких мовах, як C і Java.
Розширений синтаксис
У повному нескороченому синтаксисі два вищеописаних приклади буде записано
/child::A/child::B/child::C
child::A/descendant-or-self::node()/child::B/child::*[position()=1]
Тут на кожному кроці вісь(наприклад, child
or descendant-or-self
) вказується явно, потім пишуть ::
і потім визначення вузла, так як A
або node()
в розглянутих прикладах.
Осі
Осі вказують на напрям навігації по дереві XML документа. Є такі осі:
Розширений синтаксис | Скорочений синтаксис | Пояснення |
---|---|---|
ancestor | Вибирає всіх предків (батька, прабатька і т. д.) поточного вузла | |
ancestor-or-self | Вибирає всіх предків (батька, прабатька і т. д.) поточного вузла і його самого | |
attribute |
@ |
Вибирає всі атрибути поточного вузла |
child | Вибирає всіх дітей поточного вузла | |
descendant | Вибирає всіх нащадків (дітей, внуків і т. д.) поточного вузла | |
descendant-or-self |
// |
Вибирає всіх нащадків (дітей, внуків і т. д.) поточного вузла і його самого |
following | Вибирає все в документі після закриваючого тегу поточного вузла | |
following-sibling | Вибирає всіх «братів» після поточного вузла | |
namespace | Вибирає всі вузли простору імен поточного вузла | |
parent |
.. |
Вибирає всіх батьків поточного вузла |
preceding | Вибирає всі вузли, що з'являлись перед поточним вузлом у документі, крім предків, вузлів з атрибутами і вузлів простору імен | |
preceding-sibling | Вибирає всіх «братів» перед поточним вузлом | |
self |
. |
Вибирає поточний вузол |
Розглянемо приклад використання осі following-sibling на наступному XML документі:
<items>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</items>
XPath вираз
items/item/following-sibling::item[position()='2']
поверне '34' — значення третього і четвертого вузлів <item>, тобто тих, що йдуть після <item> на другій позиції.
Для демонстрації роботи descendant використаємо наступний XML документ:
<items>
<item>
<page>page1</page>
<page>page2</page>
<page>page3</page>
</item>
<item>2</item>
<item>3</item>
<item>4</item>
</items>
Написавши наступне
descendant::items/item[position()='1']
отримаємо 'page1 page2 page3', тобто значення всіх нащадків <item>, що стоїть на першій позиції.
Як приклад використання осі attribute в скороченому синтаксисі, //a/@href
вибирає атрибути з назвою href
в усіх a
елементах, що зустрічаються в документі.
Вираз . (скорочений запис від self::node()) найчастіше використовується в предикаті, щоб звернутись до поточного вузла.
Наприклад, h3[.='See also']
вибирає елемент в поточному контексті з назвою h3
із значенням See also
.
Визначення вузла
Визначення вузла може складатися з конкретних імен вузлів або більш загальних виразів. У разі, якщо в XML документі був визначений префікс простору імен gs
, //gs:enquiry
знайде всі enquiry
елементи в цьому просторі імен, і //gs:*
знайде всі елементи, незалежно від локальної назви, в цьому просторі імен.
Іншими форматами визначення вузла є:
- comment()
- знаходить XML вузол з коментарем (наприклад,
<!-- Comment -->
) - text()
- знаходить вузол з відповідним текстом (наприклад,
hello world
в<k>hello<m> world</m></k>
) - processing-instruction()
- знаходить інструкції з обробки XML документа, такі як
<?php echo $a; ?>
. В цьому випадкуprocessing-instruction('php')
збігатимуться. - node()
- знаходить будь-який вузол загалом
Предикати
Предикати, записані у вигляді виразів у квадратних дужках, можуть бути використані для обмеження набору вузлів, для вибору тільки тих вузлів, для яких виконується деяка умова. Наприклад, a[@href='help.php']
вибере ті a
елементи (з-поміж дітей контекстного вузла), що містять атрибут href
із значенням help.php
.
Нема обмеження на кількість предикатів, застосованих на одному кроці, і вони не повинні бути обмежені до останнього кроку в XPath виразі. Також вони можуть бути вкладені на будь-яку глибину. Шлях, визначений предикатами, починається в контексті поточного кроку і не змінює цей контекст. Всі умови повинні виконатися, щоб відбулась дія.
Коли значенням предиката є цифра, вона інтерпретується як тест на позицію (номер) вузла. Таким чином p[1]
вибирає перший p
елемент-дитину, в той час, як p[last()]
вибирає останню.
В іншим випадках значення предиката є автоматично конвертовані до булевих. Коли предикат оцінює множину вузлів, результат є true коли множина вузлів не є порожньою. Отже, p[@x]
вибирає ті p
елементи, котрі мають атрибут x
.
Більш складний приклад:
a[/html/@lang='en'][@href='help.php'][1]/@target
вибирає значення атрибута target
першого a
елемента з-поміж дітей контекстного вузла, що має свій власний атрибут href
із значенням help.php
, за умови, що елемент верхнього рівня html
також має атрибут lang
із значенням en
. Посилання на атрибут елемента верхнього рівня в першому предикаті не впливає ні на контекст інших предикатів, ні на місцезнаходження його самого на даному кроці.
Порядок предикатів є важливий, якщо предикати перевіряються позицію вузла. Кожен предикат «фільтрує» місцезнаходження вибраного набору вузлів на даному кроці по черзі. Отже, a[1][@href='help.php']
знайде відповідність, лише якщо перша a
дитина контекстного вузла відповідає умові @href='help.php'
, в той час, як a[@href='help.php'][1]
знайде першу a
дитину, що задовільняє умові.
Функції та оператори
XPath 1.0 визначає чотири типи даних: множини вузлів, рядки, числа, логічні типи.
Доступними є наступні оператори:
- «/», «//» і «[…]» оператори, що використовуються у XPath виразах, як це було описано раніше
- оператор об'єднання "|", що об'єднує дві множини вузлів
- булеві оператори «and» і «or», і функція «not()»
- арифметичні оператори «+», «-», «*», «div» (ділення), і «mod» (ділення за модулем)
- Оператори порівняння «=», «!=», «<», «>», «<=», «>=»
Бібліотека включає стандартні функції (більше 100):
- для маніпулювання рядками: concat(), substring(), contains(), substring-before(), substring-after(), translate(), normalize-space(), string-length()
- для маніпулювання числами: sum(), round(), floor(), ceiling()
- для отримання властивостей вузлів: name(), local-name(), namespace-uri()
- для отримання інформації про контекст обробки: position(), last()
- для конвертування: string(), number(), boolean()
Системні функції
- node-set document(object, node-set?)
- Повертає документ, вказаний у параметрі object.
- string format-number(number, string, string?)
- Форматує число згідно зразку, заданому в другому параметрі, третій параметр вказує на іменний формат числа, що повинен бути врахований.
- string generate-id(node-set?)
- Повертає рядок, який є унікальним ідентифікатором.
- node-set key(string, object)
- Повертає множину з вказаним ключем (аналогічно функції id для ідентифікатора).
- string unparsed-entity-uri(string)
- Повертає непроаналізований URI, а якщо такого немає, то повертає пустий рядок.
- boolean element-available(string)
- Перевіряє, чи вказаний в параметрі елемент, чи набір елементів є доступним (параметр розглядається, як XPath вираз).
- boolean function-available(string)
- Перевіряє, чи доступна функція, вказана в параметрі (параметр розглядається, як XPath вираз).
- object system-property(string)
- Параметри, що повертають системні змінні, можуть бути:
- * xsl: version — повертає версію XSLT процесора.
- * xsl: vendor — повертає виробника XSLT процесора.
- * xsl: vendor-url — повертає URL, що ідентифікує виробника.
- Якщо використовується невідомий параметр, то функція повертає пустий рядок.
- boolean lang(string)
- Повертає true, якщо або в даний тег, або його батько мають атрибут xml: lang, і в ньому вказаний відповідний рядку символ.
Функції над множиною вузлів
- node-set node()
- Повертає всі вузли (використовують замість '*' у випадках, коли стоїть завдання повернути і текстові вузли).
- string text()
- Повертає набір текстових вузлів
- node-set current()
- Повертає множину з одного елемента, який є поточним (якщо робимо обробку множини з умовами, то єдиним способом дотягнутись з цієї умови до поточного елемента є дана функція).
- number position()
- Повертає позицію елемента в множині (працює в циклі
<xsl:for-each/>
). - number last()
- Повертає позицію останнього елемента в множині (працює в циклі
<xsl:for-each/>
). - number count(node-set)
- Повертає кількість елементів у множині.
- string name(node-set?)
- Повертає повне ім'я першого тегу в множині.
- string namespace-uri(node-set?)
- Повертає посилання на URL, що визначає простір імен.
- string local-name(node-set?)
- Повертає ім'я першого тегу в множині (без простору імен).
- node-set id(object)
- Находить елемент з унікальним ідентифікатором
Функції над рядками
- string string(object?)
- Повертає текстовий зміст елемента (насправді повертає об'єднану множину текстових елементів на один рівень нижче).
- string concat(string, string, string*)
- Об'єднує два і більше рядки.
- number string-length(string?)
- Повертає довжину рядка
- boolean contains(string, string)
- Повертає true, якщо перший рядок містить другий, в іншому випадку — false.
- string substring(string, number, number?)
- Повертає рядок, вирізаний із рядка, починаючи з вказаного номера і, якщо вказаний другий номер — кількість символів.
- string substring-before(string, string)
- Якщо другий рядок знайдений в першому, то повертає перший рядок до першого входження другого.
- string substring-after(string, string)
- Якщо другий рядок знайдений в першому, то повертає перший рядок після першого входження другого.
- boolean starts-with(string, string)
- Повертає true, якщо другий рядок входить в початок першого, інакше — false.
- boolean ends-with(string, string)
- Повертає true, якщо другий рядок входить в кінець першого, інакше — false.
- string normalize-space(string?)
- Забирає зайві пробіли, а так само керуючі символи, заміняючи їх пробілами.
- string translate(string, string, string)
- Замінює символи першого рядка, які зустрічаються в другому, на відповідні позиції символами із другого рядка символи третього(наприклад,
translate(«bar», «abc», «ABC»
) повернеBAr
.
Логічні функції
- boolean boolean(object)
- Приведе об'єкт до логічного типу.
- boolean true()
- Повертає true.
- boolean false()
- Повертає false.
- boolean not(boolean)
- Заперечення (поверне true, якщо аргумент false і навпаки).
Числові функції
- number number(object?)
- Переводить об'єкт в число.
- number sum(node-set)
- Верне суму множини (кожен тег буде перетворений в рядок і з нього вийде число).
- number floor(number)
- Повертає найбільше число, але не більше, ніж аргумент.
- number ceiling(number)
- Повертає найменше число, але не менше, ніж аргумент.
- number round(number)
- Заокруглює число за математичними правилами.
Приклади використання
Вирази можуть створюватися всередині предикатів з використанням операторів: =, !=, <=, <, >=
і >
. Булеві вирази можуть комбінуватися з дужками ()
і булеві оператори and
і or
, як і функція not()
(описані вище). Числові розрахунки можуть використовувати *, +, -, div
і mod
. Рядки можуть складатися з будь-яких [Юнікод|Unicode]] характеристик.
Наприклад, вираз
//item[@price > 2*@discount]
вибирає <item>, атрибут price яких є більший числового значення їх атрибуту discount, помноженому на два.
Безліч вузлів можна 'об'єднати ', використовуючи вертикальну риску |. Множини вузлів, що задовольняють одному або більше з декількох умов можуть бути знайдені шляхом об'єднання умов всередині предиката з використанням 'or
'
Наступний вираз
v[x or y] | w[z]
повернеться один набір вузлів, що складається з усіхv
елементів, таких що маютьx
абоy
дітей-елементів, так само, як і зі всіхw
елементів, що маютьz
дітей-елементів, що були знайдені в даному контексті.
Приклади
Даний простий XML документ:
<?xml version="1.0" encoding="utf-8"?>
<wikimedia>
<projects>
<project name="Wikipedia" launch="2001-01-05">
<editions>
<edition language="English">en.wikipedia.org</edition>
<edition language="German">de.wikipedia.org</edition>
<edition language="French">fr.wikipedia.org</edition>
<edition language="Polish">pl.wikipedia.org</edition>
<edition language="Spanish">es.wikipedia.org</edition>
</editions>
</project>
<project name="Wiktionary" launch="2002-12-12">
<editions>
<edition language="English">en.wiktionary.org</edition>
<edition language="French">fr.wiktionary.org</edition>
<edition language="Vietnamese">vi.wiktionary.org</edition>
<edition language="Turkish">tr.wiktionary.org</edition>
<edition language="Spanish">es.wiktionary.org</edition>
</editions>
</project>
</projects>
</wikimedia>
XPath вирази:
/wikimedia/projects/project/@name
повертає атрибут name для всіх <project>;
/wikimedia//editions
вибирає всі <edition> всіх <project>;
/wikimedia/projects/project/editions/edition[@language="English"]/text()
вибирає адреси всіх <project> з англійської Вікіпедії (текст всіх edition елементів, де значення атрибута language є English);
/wikimedia/projects/project[@name="Wikipedia"]/editions/edition/text()
вибирає адреси всіх Вікіпедій (текст всіх edition елементів, що існують під project елементом із значенням Wikipedia атрибута name).
Реалізації
- Інструменти командного рядка
- XMLStarlet
- xmllint (libxml2)
- RaptorXML Server від Altova, що підтримує XPath 1.0, 2.0, і 3.0
- XPath є включений в бібліотеку за замовчуванням
- Реалізації для двигунів баз даних
- Virtuoso Universal Server|OpenLink Virtuoso
- Saxon XSLT підтримує XPath 1.0, XPath 2.0 і XPath 3.0 (так само, як і XSLT 2.0, XQuery 3.0)
- BaseX (також підтримує XPath 2.0 and XQuery)
- VTD-XML
- Sedna XML Database (XML: DB і патентований).
- QuiXPath реалізація потокової політики відкритого коду (Innovimax)
Пакет Java був частиною Java стандартної версії, починаючи з Java 5. Технічно це XPath API, а не реалізація XPath, і це дозволяє програмісту можливість вибрати конкретну реалізацію, що відповідає інтерфейсу.
- В просторах імен System.Xml і System.Xml.XPath[7]
- Sedna XML Database
- XML::LibXML (libxml2)
- Sedna XML Database
- ElementTree XML API в Python Standard Library включає обмежену підтримку для XPath виразів
- libxml2
- Amara
- Sedna XML Database
- lxml
- libxml2[8]
- Nokogiri
- Sedna XML Database
- MySQL підтримує частину XPath з версії 5.1.5 і далі[9]
- PostgreSQL підтримує XPath і XSLT з версії 8.4 і далі[10]
- Пакет tdom забезпечує "дуже повне, сумісне і швидке впровадження XPath в C
Використання в мовах схем
XPath все частіше використовується, щоб показати обмеження мов схем для XML.
- (В даний момент стандарт ІСО) мова схем Schematron започаткувала підхід.
- Потокове підмножина XPath використовується в XML Schema (W3C) 1.0 для вираження унікальність і ключових обмежень. У XSD 1.1 використання XPath є розширеним для підтримки умовного присвоювання типу на основі значень атрибутів, і дозволу довільним логічним твердженням бути оціненими проти вмісту елементів.
- XForms використовує XPath, щоб пов'язати типи із значеннями.
- Підхід навіть знайшов застосування в не-XML-додатках, таких як обмежена мова для Java, названа PMD: як Java перетвориться в DOM-дереві розбору, то XPath правила будуть визначені над деревом.
Примітки
- XML and Semantic Web W3C Standards Timeline. 4 лютого 2012. Архів оригіналу за 24 квітня 2013. Процитовано 13 травня 2015.
- Bergeron, Randy (31 жовтня 2000). XPath—Retrieving Nodes from an XML Document. SQL Server Magazine. Архів оригіналу за 26 липня 2010. Процитовано 13 травня 2015.
- Pierre Geneves (October 2012). Course: The XPath Language.
- XPath 2.0 підтримує атомні типи, визначені в XML Schema як вбудовані, і також може імпортувати типи зі схеми, визначені користувачем.
- XPath 3.0 W3C Recommendation
- What's new in 3.0 (XSLT/XPath/XQuery) (plus XML Schema 1.1) by Michael Kay, Saxonica
- System.Xml Namespace
- http://xmlsoft.org/
- http://dev.mysql.com/doc/refman/5.1/en/xml-functions.html
- Online docs at postgresql.org
Посилання
- Специфікація XPath 1.0
- Російський переклад специфікації XML Path (XPath) версії 1.0
- Специфікація XPath 2.0
- Що нового в XPath 2.0
- Парсер сайтів на Xpath. Урок 1 (Українська)
- Втілення XPath у JavaScript
- Підручник з численними прикладами
- TinyXpath- Втілення XPath на c++
- XPath Підручник (Німецька)
- XSLT і XPath посилання (Німецька)
- [http://xn--rthschilling-dlb.info/web/openlab/cms/xpath/axis-specifier-overview%5Bнедоступне+посилання+з+червня+2019%5D XPath Achsen Diagramme][недоступне посилання з жовтня 2019] (Німецька)
- XPath в JavaScript (Російська)