XPath-Tutorial

In dieser Anleitung bekommen Sie eine einfache Einführung in XPath, einer Abfragesprache, zum Auswählen von beliebigen Teilen innerhalb eines HTML Dokuments in Calibre. XPath ist ein weit verbreiteter Standard der, wenn Sie danach googeln, viele Anwendungsbeispiele aufzeigt. Diese Anleitung wird sich auf die Verwendung von XPath für Aufgaben rund um eBooks konzentrieren, wie z. B. um Kapitelüberschriften in einem unstrukturierten HTML-Dokument zu finden.

Auswahl über Tag-Name

Die einfachste Form einer Auswahl ist die Auswahl von Tags durch deren Namen. Wenn man z. B. alle <h2>-Tags in einem Dokument finden möchte, ist die dazu passende XPath-Abfrage:

//h:h2        (Selects all <h2> tags)

Das Präfix // bedeutet suche auf jeder Ebene des Dokuments. Angenommen, Sie möchten nun nach <span>-Tags suchen, die sich innerhalb von <a>-Tags befinden. Dies wird durch den folgenden Ausdruck erreicht:

//h:a/h:span    (Selects <span> tags inside <a> tags)

Wenn Sie nach Tags einer bestimmten Ebene im Dokument suchen möchten, ändern Sie das Präfix wie folgt ab:

/h:body/h:div/h:p (Selects <p> tags that are children of <div> tags that are
             children of the <body> tag)

Dieser wird <p>Ein sehr kleines eBook, um die Verwendung von XPath zu demonstrieren.</p> im Ein Beispiel e-Book finden und keine anderen <p>-Tags. Das Präfix h: in den obigen Beispielen ist zum Finden von XHTML-Tags erforderlich. Der Grund hierfür liegt in der internen Verarbeitung von Calibre, da alle Inhalte als XHTML-Code interpretiert werden. In XHTML haben Tags einen Namensraum und h: ist der Namensraum-Präfix für HTML-Tags.

Nehmen wir nun an, Sie möchten sowohl <h1> als auch <h2> Tags auswählen. Um dies zu erreichen, brauchen wir ein XPath-Konstrukt, welches Prädikat genannt wird. Ein Prädikat ist ein Test, um gesuchte Tags zu finden. Tests können beliebig umfangreich sein. Mit den weiteren Beispielen werden diese umfangreicher. Man erstellt ein Prädikat, indem der Testausdruck in eckigen Klammern eingeschlossen wird:

//*[name()='h1' or name()='h2']

In diesem XPath-Ausdruck gibt es einige neue Eigenschaften. Die erste ist die Verwendung des Platzhalters *. Dieser bedeutet finde jeden Tag. Nun schauen wir uns den Testausdruck name()='h1' or name()='h2' an. name() ist ein Beispiel für eine integrierte Funktion. Hierbei wird der Name des angegebenen Tags ausgewertet. Wendet man dies wie in unserem Beispiel an, werden alle Tags mit dem Namen h1 oder h2 gefunden. Beachten Sie, dass die Funktion name() Namensräume ignoriert. Es besteht daher keine Notwendigkeit für die Anwendung des Präfix h:. XPath hat einige nützliche Funktionen integriert. Weitere werden in dieser Anleitung vorgestellt.

Auswahl über Attribute

Um Tags nach ihren Attributen auszuwählen, ist die Verwendung von Prädikaten erforderlich:

//*[@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")

Der @-Operator bezieht sich auf die Attribute eines Tags. Sie können einige der XPath built-in functions nutzen, um anspruchsvollere Abfragen auf Attributwerte auszuführen.

Auswahl nach Tag-Inhalt

Mithilfe von XPath können Sie auch Tags auswählen, die sich auf einen im Tag enthaltenen Text beziehen. Der beste Weg ist die Verwendung der Fähigkeiten von regulären Ausdrücken über die integrierte Funktion re:test():

//h:h2[re:test(., 'chapter|section', 'i')] (Selects <h2> tags that contain the words chapter or
                                          section)

Der .-Operator bezieht sich auf den Inhalt eines Tags, sowie sich der @-Operator auf seine Attribute bezieht.

Ein Beispiel e-Book

<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>

Integrierte XPath-Funktionen

name()

Der Name des aktuellen Tags.

contains()

contains(s1, s2) gibt true zurück wenn s1 s2 beinhaltet.

re:test()

re:test(src, pattern, flags) gibt true zurück, wenn der String src dem regulären Ausdruck pattern entspricht . Ein möglich anzufügendes Flag ist i, das verzichtet auf Groß- und Kleinschreibung. Ein gutes Beispiel dafür finden Sie unter regexp syntax