Учебник по 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 predicate — это просто тест, который используется для выбора тегов. Тесты могут быть сколь угодно мощными, и по мере продвижения по этому учебнику вы увидите более мощные примеры. Предикат создаётся путём заключения тестового выражения в квадратные скобки:
//*[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) для выполнения более сложных сопоставлений значений атрибутов.
Примечание
When XPath expressions are used for conversion options such as chapter
detection or the start reading at position, they are evaluated against the
input document, before calibre flattens the CSS. CSS flattening rewrites
class names, so the class names you see in the converted output (things like
calibre1) do not exist yet when your expression runs. Copy
class names from the input document, not from the converted book. If in
doubt, match on tag names and text content instead, as these are not changed
by the conversion.
Выбор по содержимому тега¶
Используя 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.
