XPath-introduktion¶
I den här handledningen får du en lättillgänglig introduktion till XPath, ett frågespråk som kan användas för att välja valfria delar av HTML-dokument i calibre. XPath är en etablerad standard och det finns mycket information om språket på internet. Den här handledningen fokuserar på hur XPath används för e-boksrelaterade uppgifter, till exempel för att hitta kapitelrubriker i ett ostrukturerat HTML-dokument.
Välja efter taggnamn¶
Det enklaste är att välja taggar efter namn. Anta till exempel att du vill välja alla <h2>-taggar i ett dokument. XPath-uttrycket är då helt enkelt:
//h:h2 (Selects all <h2> tags)
Prefixet // betyder sök på valfri nivå i dokumentet. Anta nu att du vill söka efter <span>-taggar som finns inuti <a>-taggar. Det kan göras med:
//h:a/h:span (Selects <span> tags inside <a> tags)
Om du vill söka efter taggar på en viss nivå i dokumentet ändrar du prefixet:
/h:body/h:div/h:p (Selects <p> tags that are children of <div> tags that are
children of the <body> tag)
Detta matchar endast <p>A very short e-book to demonstrate the use of XPath.</p> i Exempel-e-bok, inte någon av de andra <p>-taggarna. Prefixet h: i exemplen ovan krävs för att matcha XHTML-taggar. Det beror på att calibre internt representerar allt innehåll som XHTML. I XHTML tillhör taggar ett namnområde, och h: är namnrymdsprefixet för HTML-taggar.
Anta nu att du vill välja både <h1>- och <h2>-taggar. Då behöver vi en XPath-konstruktion som kallas predikat. Ett predikat är ett villkor som används för att välja taggar. Villkoren kan vara godtyckligt avancerade, och längre fram i handledningen visas kraftfullare exempel. Ett predikat skapas genom att omge villkorsuttrycket med hakparenteser:
//*[name()='h1' or name()='h2']
Det finns flera nya delar i XPath-uttrycket. Den första är jokertecknet *, som betyder matcha valfri tagg. Titta sedan på villkorsuttrycket name()='h1' or name()='h2'. name() är en inbyggd funktion som returnerar taggens namn. Med den kan vi välja taggar vars namn är antingen h1 eller h2. Funktionen name() ignorerar namnrymder, så prefixet h: behövs inte. XPath har flera användbara inbyggda funktioner. Några fler presenteras i den här handledningen.
Välja efter attribut¶
För att välja taggar utifrån deras attribut krävs predikat:
//*[@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")
Här hänvisar operatorn @ till taggens attribut. Du kan använda några av XPaths inbyggda funktioner för att göra mer avancerade matchningar av attributvärden.
Välja efter tagginnehåll¶
Med XPath kan du även välja taggar utifrån den text de innehåller. Det bästa sättet är att använda reguljära uttryck via den inbyggda funktionen re:test():
//h:h2[re:test(., 'chapter|section', 'i')] (Selects <h2> tags that contain the words chapter or
section)
Här hänvisar .-operatören till innehållet i taggen, precis som @-operatören avser dess attribut.
Exempel-e-bok¶
<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>
XPaths inbyggda funktioner¶
- name()¶
Namnet på den aktuella taggen.
- contains()¶
contains(s1, s2)returnerar true om s1 innehåller s2.- re:test()¶
re:test(src, pattern, flags)returnerar true om strängen src matchar det reguljära uttrycket pattern. En särskilt användbar flagga äri, som gör matchningen skiftlägesokänslig. En bra introduktion till syntaxen finns i Python-dokumentationen.
