Cursillo de XPath

En este cursillo, se presentará una pequeña introducción a XPath, un lenguaje de consulta que se puede utilizar para seleccionar partes arbitrarias de documentos HTML en calibre. XPath es un estándar ampliamente utilizado, y una búsqueda a través de Google proporcionará gran cantidad de información. Este cursillo, sin embargo, se centra en el uso de XPath para tareas relacionadas con libros electrónicos, como la búsqueda de cabeceras de capítulos en un documento HTML sin estructura.

Seleccionar por nombre de etiqueta

La forma más simple de selección es seleccionar las etiquetas por su nombre. Por ejemplo, suponga que desea seleccionar todas las etiquetas <h2> en un documento. La consulta XPath para esto es simplemente:

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

El prefijo // significa buscar en cualquier nivel del documento. Supongamos que desea encontarar las etiquetas <span> que están dentro de etiquetas <a>. Esto se puede lograr con:

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

Si quiere buscar etiquetas en un nivel particular del documento, cambie el prefijo:

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

Esto coincidirá sólo con <p>A very short ebook to demonstrate the use of XPath.</p> en Libro de muestra, pero no con ninguna de las otras etiquetas <p>. El prefijo h: en los ejemplos anteriores se necesita para encontrar las etiquetas XHTML. Esto se debe a que internamente calibre representa todo el contenido como XHTML. En XHTML las etiquetas tienen un espacio de nombres, y h: es el prefijo de espacio de nombrs para las etiquetas HTML.

Ahora supongamos que desea seleccionar ambas etiquetas``<h1>`` y <h2>. Para hacer esto, necesitamos una construcción XPath llamada predicado. Un predicado es simplemente una comprobación que se utiliza para seleccionar etiquetas. Las comprobaciones pueden ser muy potentes y, según avance este cursillo, verá ejemplos más sofisticados. Un predicado se crea encerrando la expresión de comprobación entre corchetes:

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

Hay varias características nuevas en esta expresión XPath. La primera es el uso del comodín *. Significa cualquier etiqueta. Ahora observe la expresión de comprobación name()='h1' or name()='h2'. name() es un ejemplo de función predefinida. Simplemente evalúa el nombre de la etiqueta. Por lo tanto, mediante su uso, podemos seleccionar etiquetas cuyo nombre sea h1 o h2. Tenga en cuenta que la función name() ignora los espacios de nombres de modo que no hay necesidad del prefijo h:. XPath tiene varias funciones predefinidas. Se presentarán algunas más en este cursillo.

Seleccionar por atributos

Para seleccionar etiquetas según sus atributos, es necesario usar predicados:

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

Aquí, el operador @ se refiere a los atributos de la etiqueta. Puede utilizar algunas de las XPath built-in functions para realizar búsquedas más sofisticadas en los valores de los atributos.

Seleccionar por contenido de etiqueta

Utilizando XPath, puede incluso seleccionar etiquetas basadas en el texto que contienen. La mejor manera para para hacer esto es usar el poder de las expresiones regulares a través la función predefinida re:test():

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

Aquí el operador . se refiere a los contenidos de la etiqueta, igual que el operador @ se refiere a sus atributos.

Libro de muestra

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

Funciones XPath predefinidas

name()

El nombre de la etiqueta actual.

contains()

contains(s1, s2) devuelve true si s1 contiene s2.

re:test()

re:test(fuente, patrón, opciones) devuelve true si el texto fuente coincide con la expresión regular patrón. Una opción particularmente útil es i, que hace que no se distinga entre mayúsculas y minúsculas. Una buena introducción a la sintaxis de las expresiones regulares se puede encontrar en sintaxis de expresiones regulares (en inglés)