Guida di XPath¶
In questa guida ti sarà fornita un’introduzione graduale a XPath, un linguaggio per query che può essere utilizzato per selezionare parti arbitrarie di documenti HTML in calibre. XPath è uno standard ampiamente utilizzato e una ricerca su Google rivelerà parecchie informazioni. Questa guida, tuttavia, si concentra sull’utilizzo di XPath per compiti relativi agli e-book, come trovare le intestazioni dei capitoli in un documento HTML non strutturato.
Selezione per nome del tag¶
La forma più semplice di selezione è selezionare i tag per nome. Ad esempio, immagina di voler selezionare tutti i tag «<h2>» in un documento. La query di XPath per farlo è semplicemente:
//h:h2 (Selects all <h2> tags)
Il prefisso // significa cerca ad ogni livello del documento. Adesso immagina di dover cercare dei tag <span> che si trovano dentro tag <a>. Ciò si può ottenere con:
//h:a/h:span (Selects <span> tags inside <a> tags)
Se vuoi cercare dei tag in un livello particolare del documento, modifica il prefisso:
/h:body/h:div/h:p (Selects <p> tags that are children of <div> tags that are
children of the <body> tag)
Questo troverà solo <p>A very short e-book to demonstrate the use of XPath.</p> nel Libro di esempio, ma nessuno degli altri tag <p>. Il prefisso h: negli esempi precedenti è richiesto per trovare i tag XHTML. Questo è necessario perché, internamente, calibre rappresenta tutti i contenuti come XHTML. In XHTML i tag hanno un namespace e h: è il prefisso di namespace per i tag HTML.
Supponiamo ora di voler selezionare sia i tag <h1> che i tag <h2> tags. Per farlo, ci serve un costrutto XPath chiamato predicato. Un predicate è, in sostanza, un test utilizzato per selezionare dei tag. Tali test possono essere estremamente versatili e, nel corso di questa guida, ne vedremo esempi sempre più avanzati. Un predicato si crea racchiudendo l’espressione di test tra parentesi quadre:
//*[name()='h1' or name()='h2']
Ci sono diverse nuove funzionalità in questa espressione XPath. La prima è l’uso del carattere jolly *. Significa trova qualsiasi tag. Ora dai un’occhiata all’espressione di test name()='h1' or name()='h2'. name() è un esempio di funzione interna. Essa valuta semplicemente il nome del tag. Quindi, usandola, possiamo selezionare tag i cui nomi sono h1 o h2. Tieni presente che la funzione name() ignora gli spazi di nomi in modo che non sia necessario il prefisso h:. XPath ha diverse utili funzioni interne. Alcune di loro saranno introdotte in questa guida.
Selezione per attributi¶
Per selezionare i tag in base alle loro caratteristiche, è richiesto l’uso di predicati
//*[@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")
Qui, l’operatore @ si riferisce agli attributi del tag. È possibile utilizzare alcune delle funzioni incorporate di XPath per eseguire una corrispondenza più sofisticata sui valori degli attributi.
Nota
Quando le espressioni XPath vengono utilizzate per opzioni di conversione come il rilevamento dei capitoli o l’impostazione del punto di inizio della lettura, esse vengono valutate rispetto al documento di input, prima che calibre esegua l’appiattimento (flattening) del CSS. L’appiattimento del CSS comporta la riscrittura dei nomi delle classi; pertanto, i nomi delle classi che si riscontrano nell’output convertito (come, ad esempio, calibre1) non esistono ancora nel momento in cui l’espressione viene eseguita. È necessario utilizzare i nomi delle classi presenti nel documento di input, non quelli del libro convertito. In caso di dubbi, è preferibile basarsi sui nomi dei tag o sul contenuto testuale, poiché tali elementi non vengono modificati durante il processo di conversione.
Selezione per contenuto del tag¶
Usando XPath, puoi persino selezionare i tag in base al testo che contengono. Il modo migliore per farlo è usare la potenza delle espressioni regolari tramite la funzione integrata re: test():
//h:h2[re:test(., 'chapter|section', 'i')] (Selects <h2> tags that contain the words chapter or
section)
Qui l’operatore . si riferisce al contenuto del tag, proprio come l’operatore @ si riferiva ai suoi attributi.
Libro di esempio¶
<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>
Funzioni interne di XPath¶
- name()¶
Il nome del tag attuale
- contains()¶
contains(s1, s2)restituisce true se s1 contiene s2.- re:test()¶
`re:test(src, pattern, flags)restituisce true se la stringa src corrisponde all’espressione regolare pattern. Un flag particolarmente utile èi, che non considera la differenza MAIUSCOLE/minuscole. Un primo aiuto sulla sintassi per le espressioni regolari è disponibile in sintassi delle regexp<https://docs.python.org/library/re.html> _
