Учебник по XPath¶
Этот учебник — введение в XPath, язык запросов, который можно использовать для выбора произвольных частей HTML в calibre. XPath — широко используемый стандарт, и поиск Google выдаст тонну информации. Однако этот учебник сосредотачивается на решении с помощью XPath задач, связанных с электронными книгами, например поиске заголовков разделов в неструктурированном HTML-документе.
Выбор по имени тега¶
Простейшая форма выбора — выбор тегов по имени. Предположим, что вы хотите выбрать все теги <h2>
в документе. Запрос XPath для этого прост:
//h:h2 (Selects all <h2> tags)
Префикс // означает поиск на любом уровне документа. Теперь предположим, что вы хотите искать теги <span>
, которые находятся внутри тегов <a>
. Этого можно достичь с помощью:
//h:a/h:span (Selects <span> tags inside <a> tags)
Если вы хотите искать теги на определённом уровне в документе, измените префикс:
/h:body/h:div/h:p (Selects <p> tags that are children of <div> tags that are
children of the <body> tag)
Это будет соответствовать только <p>A very short e-book to demonstrate the use of XPath.</p>
в разделе «Образец электронной книги», а не каким-либо другим тегам <p>
. Префикс h:
в вышеприведённых примерах необходим для соответствия тегам XHTML. Потому что внутри calibre всё содержимое представлено как XHTML. В тегах XHTML есть пространство имён, а h:
— префикс пространства имён для HTML-тегов.
Теперь предположим, что вы хотите выбрать теги <h1>
и <h2>
. Для этого нам нужна конструкция XPath, называемая предикат. A предикат — это просто тест, который используется для выбора тегов. Тесты могут быть сколь угодно мощными, и по мере продвижения по этому учебнику вы увидите более мощные примеры. Предикат создаётся путём заключения тестового выражения в квадратные скобки:
//*[name()='h1' or name()='h2']
В этом выражении XPath имеется несколько новых функций. Во-первых, это использование подстановочного символа *
. Это означает соответствие любому тегу. Теперь посмотрим на тестовое выражение name()='h1' or name()='h2'
. name() — пример встроенной функции. Она просто вычисляет имя тега. Таким образом, с её помощью мы можем выбрать теги, имена которых либо h1, либо h2. Обратите внимание, что функция name () игнорирует пространства имён, поэтому нет необходимости в префиксе h:
. XPath имеет несколько полезных встроенных функций. Некоторые из них будут показаны в этом учебнике.
Выбор по атрибутам¶
Чтобы выбрать теги на основе их атрибутов, необходимо использовать предикаты:
//*[@style] (Select all tags that have a style attribute)
//*[@class="chapter"] (Select all tags that have class="chapter")
//h:h1[@class="bookTitle"] (Select all h1 tags that have class="bookTitle")
Здесь оператор @
ссылается на атрибуты тега. Вы можете использовать некоторые из XPath built-in functions (встроенных функций XPath) для выполнения более сложных сопоставлений значений атрибутов.
Выбор по содержимому тега¶
Используя XPath, вы можете выбирать теги даже на основе содержащегося в них текста. Лучший способ сделать это — призвать силу регулярных выражений с помощью встроенной функции re:test ():
//h:h2[re:test(., 'chapter|section', 'i')] (Selects <h2> tags that contain the words chapter or
section)
Здесь оператор .
ссылается на содержимое тега, так же как оператор @
ссылается на его атрибуты.
Образец электронной книги¶
<html>
<head>
<title>A very short e-book</title>
<meta name="charset" value="utf-8" />
</head>
<body>
<h1 class="bookTitle">A very short e-book</h1>
<p style="text-align:right">Written by Kovid Goyal</p>
<div class="introduction">
<p>A very short e-book to demonstrate the use of XPath.</p>
</div>
<h2 class="chapter">Chapter One</h2>
<p>This is a truly fascinating chapter.</p>
<h2 class="chapter">Chapter Two</h2>
<p>A worthy continuation of a fine tradition.</p>
</body>
</html>
Встроенные функции XPath¶
- name()¶
Имя текущего тега.
- contains()¶
contains(s1, s2)
возвращает true, если s1 содержит s2.- re:test()¶
re:test(src, pattern, flags)
возвращает true, если строка src соответствует регулярному выражению pattern. Особенно полезен флагi
: он отвечает за нечувствительность к регистру. Хороший учебник синтаксиса регулярных выражений для начинающих можно найти по ссылке regexp syntax.