Xpath. Базовый синтаксис
Xpath - декларативный язык запросов к элементам xml или (x)html документа и xslt преобразований.
Полезные источники:
Полная спецификация по Xpath 1.0 на русском здесь - http://citforum.ru/internet/xpath/xpath.shtml.
Xpath Online Tester - http://www.xpathtester.com/xpath/
Использование Xpath в Firebug
Для поиска DOM элементов по Xpath в Firebug есть встроенная ф-ция:
$x(xpath [, contextNode [, resultType]])
Тип результата:
XPathResult.NUMBER_TYPE
XPathResult.STRING_TYPE
XPathResult.BOOLEAN_TYPE
XPathResult.FIRST_ORDERED_NODE_TYPE
XPathResult.UNORDERED_NODE_ITERATOR_TYPE
Пример использования XPATH запросов в Firebug:
$x('//tr[@data-place]/@data-place')[0].value
$x('string(//tr[@data-place][1]/@data-place)')
Примеры
Примеры запросов:
//*[@id="container"]
//div[contains(@class, 'CLASS') and normalize-space(text())='TEXT']
//a[normalize-space(text())='TEXT']
//*[normalize-space(text())='Купить']/ancestor-or-self::button
Пример JavaScript запроса XPath в браузере:
let modelName = '';
let xpath = '//*[@id="mod-detail-attributes"]//*[normalize-space(text())="Номер статьи"]//ancestor-or-self::td/following-sibling::td[contains(@class, "de-value")][1]';
let modelFromParamsNode = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (modelFromParamsNode) {
modelName = modelFromParamsNode.textContent.trim();
}
Базовый синтаксис
Пути
. # текущий контекст
.// # рекурсивный спуск (на ноль или более уровней от текущего контекста)
/html/body # абсолютный путь
table//a # относительный путь
a # путь относительно текущего контекста
//* # все в текущем контексте
li/*/a # ссылки, являющиеся "внуками" для li
//a|//button # ссылки и кнопки (объединение двух множеств узлов)
Отношения
a/i/parent::p # непосредственный родитель, <p>
p/ancestor::* # все родители (http://bit.ly/1ta7mh9)
p/following-sibling::* # все следующие братья
p/preceding-sibling::* # все предыдущие братья
p/following::* # все следующие элементы кроме потомков (http://bit.ly/1ta83H5)
p/preceding::* # все предыдущие элементы кроме предков
p/descendant-or-self::* # контекстный узел и все его потомки
p/ancestor-or-self::* # контекстный узел и все его предки
Получение узлов
/div/text() # получить текстовые узлы
/div/text()[1] # получить первый текстовый узел
Позиция элемента
a[1] # первый элемент
a[last()] # последний элемент
a[i][2] # вторая ссылка, которая содержит элемент <i>
a[position() <= 3] # Первые 3 ссылки
ul[li[1]="OK"] # список (UL), первый элемент которого содержит значение 'OK'
tr[position() mod 2 = 1] # не четные элементы
tr[position() mod 2 = 0] # четные элементы
p/text()[2] # второй текстовый узел
Атрибуты и фильтры
[] - указывает на фильтрацию элементов
input[@type=text] # атрибуты задаются с префиксом @
input[@class='OK'] #
p[not(@*)] # параграфы без атрибутов
*[@style] # все элементы с атрибутом style
a[. = "OK"] # ссылки со значением "OK"
a/@id # идентификаторы ссылок
a/@* # все атрибуты ссылок
a[@id and @rel] # ссылки, которые содержат атрибуты id и rel
a[@id][@rel] # то же самое
a[i or b] # ссылки содержат элемент <i> или <b>
Функции
Базовые функции Xpath - http://www.w3.org/TR/xpath/#corelib
name() [name()='a'] # возвращает имя элемента
string(val) string(a[1]/@id) # получить значение атрибута
substring(val, from, to) substring(@id, 1, 6) # вырезать часть строки
substring-after(val, from) substring-after(@id, 'FROM')
substring-before
string-length() [string-length(text()) > 5] # возвращает число символов в строке
count() # возвращает количество элементов
concat()
normalize-space() [normalize-space(text())='SEARCH'] # аналог trim, удаляет пробелы Пример:
starts-with() [starts-with(text(), 'SEARCH')]
contains() [contains(name(), 'SEARCH')]
translate("bar","abc","ABC") # BAr
Математика
//p[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]
//tr[position() mod 2 = 0]
position() #
div # деление
mod # остаток от деления
ceiling() # минимальное целое
floor() # максимальное целое
round()
sum()
Группирование
(table/tbody/tr)[last()] # последняя строка <tr> из всех таблиц
(//h1|//h2)[contains(text(), 'Text')] # заголовок первого или второго уровня, который содержит "Text"
Составные условия фильтрации
Все ссылки у которых атрибут data-id совпадает с этим же атрибутом у строки таблицы:
a[//tr/@data-id=@data-id]