Qué es el lenguaje XPath

Rafa Morales 3 Marzo 2015
9min
0
XPath en BaseX

Introducción a XPath

XPath es un lenguaje XML que permite el acceso a información concreta de un documento XML, haciendo un recorrido a través de los elementos que lo compoe. Es decir, evaluar una expresión XPath consiste en buscar si hay elementos que satisfagan el recorrido indicado.

Este lenguaje se suele emplear en otras tecnologías o lenguajes y no en solitario. Por ejemplo, se utiliza en consultas XQuery o en transformaciones XSLT o XSL-FO.

XPath es una recomendación del W3C:

Utilizaremos la siguiente nomenclatura durante el artículo. Un documento XML está compuesto por nodos, también llamados elementos, los cuales se componentes de etiquetas y contenido, siendo este contenido texto y otros nodos. Los nodos se organizan en forma de árbol, existiendo un único nodo raíz. A partir de él, todos los nodos pueden o no tener nodos hijos. Leer más sobre XML.

Para todos los ejemplos siguiente vamos a tomar como referencia el siguiente documento XML:

<bib url="http://www.ticarte.com">
  <book id="1">
    <title>TCP/IP Illustrated</title>
    <author>Stevens</author>
    <publisher>Addison-Wesley</publisher>
    <year>2002</year>
  </book>
  <book id="2">
    <title>Advanced Programming in the Unix Environment</title> 
    <author>Stevens</author> 
    <publisher>Addison-Wesley</publisher>
    <year>2004</year>
  </book>
  <book id="3">
    <title>Data on the Web</title>
    <author>Abiteboul</author>
    <author>Buneman</author>
    <author>Suciu</author>
    <year>2006</year>
  </book>
</bib>

 

Herramientas para el manejo de XPath

Para probar XPath podemos utilizar el software libre BaseX o cualquier otro que comentamos aquí.

Y de manera online podemos utilizar:

 

Direccionamiento o localización

El direccionamiento o localización es una ruta o camino de nodos de un documento XML que nos permitirán seleccionar un conjunto de ellos.

 

El direccionamiento puede ser:

  • Absoluto: si siempre se incluye el nodo raíz.
  • Relativo: si se empieza a hacer referencia a los nodos desde un nodo diferente al nodo raíz.

 

Las expresiones que se pueden utilizar en un direccionamiento XPath son:

nodo Elemento de nombre nodo
/nodo El nodo se encuentra en la raíz del documento
nodo1/nodo2 El nodo2 es hijo directo de nodo1
nodo1//nodo2 El nodo2 es hijo del nodo1 pero puede haber nodos intermedios
//nodo El nodo está ubicado en cualquier nivel debajo del nodo raíz
@atributo Atributo de nombre atributo
* Cualquier elemento
@* Cualquier atributo
. Nodo actual
.. Nodo padre

 

Pongamos algunos ejemplos de su uso.

Para listar los títulos de los libros de la biblioteca:

/bib/book/author

Para listar los autores sin indicar de qué nodo son hijos:

//author

Para listar los identificadores de los libros:

/bib/book/@id

Para listar todos los atributos de cualquier nodo:

//@*

 

El acceso al contenido textual del nodo se puede realizar con la siguiente función:

  • text(): Devuelve el texto del nodo.

Por ejemplo, para listar sólo los títulos de los libros de la biblioteca sin las etiquetas:

/bib/book/author/text()

 

Filtrar el acceso a elementos

El direccionamiento de XPath también permite filtrar el conjunto de nodos o información a la que se accede mediante la consulta utilizando condiciones en nodos. El filtro se especifica mediante corchetes [ ] seguidos del nodo al que se le aplica dicho filtro.

Podemos utilizar los siguientes operadores:

and  
or  
not  
=  
!=  
<  
>  
<=  
>=  
to Rango
+ Suma
- Resta
* Multiplicación
div División
mod Resto de la división
| Unión de resultados

Podemos utilizar las siguientes funciones de XPath, como más importantes. La lista completa se puede ver aquí.

Funciones numéricas

round() Redondeo round(3.14) = 3
abs() Valor absoluto abs(-7) = 7
floor() Redondeo inferior floor(7.3) = 7
ceiling Redondeo superior ceiling(7.3) = 8

Funciones de cadena

substring() Subcadena substring('TicArte', 1, 4) = TicA
starts-with() Cadena comienza por starts-with('XML', 'X') = true
ends-with() Cadena finaliza por ends-with('XML', 'X') = false
contains() Cadena contiene contains('XML', 'ML') = true
normalize-space() Espacios normalizados normalize-space(' Doc XML ') = 'Doc XML'
translate() Cambia caracteres en una cadena translate('Doc XML', 'Doc', 'File') = 'File XML'
string-length() Longitud de una cadena string-length('TicArte') = 7
upper-case() Cadena a mayúsculas upper-case('xml') = 'XML'
lower-case() Cadena a minúsculas lower-case('XML') = 'xml'

Funciones de posición de elementos

position() = n Nodo que se encuentra en la posición 'n'
elemento[n] Nodo en la posición 'n' de los que se llaman nodo
last() El último nodo de un conjunto
last() - i El último menos i nodos

Funciones de nodos

name() Nombre del nodo actual
text() Contenido textual del nodo
root() Elemento raíz
node() Nodos descendientes del actual
comment() Comentarios del nodo
processing-instruction() Instrucciones de procesamiento
exists() Si existe el nodo o no
empty() Si el nodo está vacío o no

Funciones de agregado

count() Contar los nodos
avg() Media del contenido de los nodos
max() Valor máximo del contenido de los nodos
min() Valor mínimo del contenido nodos
sum() Suma del contenido de los nodos

A continuación exponemos una serie de ejemplos que ayuden a clarificar el uso de filtros.

Mostrar todos los autores y publicadores. Utilizaremos el operador unión para unir los dos conjuntos de nodos:

/bib/book/author|/bib/book/publisher

Suponiendo que el documento XML tiene libros y diccionarios, podemos ver todos los autores:

/bib/(book|dictionary)/author

Mostrar el libro número 2:

/bib/book[position()=2]
/bib/book[2]

Mostrar del libro número 2 al número 3:

/bib/book[position()=2 to 3]

Mostrar el último libro:

/bib/book[last()]

Mostrar los libros anteriores al año 2003. Los números no necesitan comillas.

/bib/book[year<2003]

Mostrar los libros cuyo autor sea Stevens. Las cadenas deben ir siempre entre comillas. Se muestran diferentes formas de conseguir lo mismo.

/bib/book[author="Stevens"]
/bib[book/author="Stevens"]/book
//author[.="Stevens"]/..

Mostrar el título de los libros cuyo autor sea Stevens. Hay que fijarse que la condición va en el nodo book pero luego mostramos el nodo title que contiene.

/bib/book[author="Stevens"]/title

Se podría hacer la condición también en title, pero puede ser más lioso:

/bib/book/title[../author="Stevens"]

Mostrar los títulos de los libros cuyo identificador sea el 2:

/bib/book[@id="2"]/title

Mostrar los títulos de los libros de Stevens publicados en el 2002. Podemos utilizar el operador and.

/bib/book[author="Stevens" and year=2002]/title

Mostrar los títulos de los libros de Stevens publicados en el 2002. Podemos concatenar diferentes condiciones, cada una en sus corchetes, que es el mismo significado que el operador and.

/bib/book[author="Stevens"][year=2002]/title

Mostrar los títulos de los libros que comienzan por 'T':

/bib/book[starts-with(title,"T")]/title

Mostrar los títulos de los libros que tengan una longitud de más de 10 caracteres:

/bib/book[string-length(title)>10]/title

 

Consultas XPath anidadas

Las consultas XPath anidadas consisten en incluir una consulta XPath que devuelta un cierto valor dentro de la condición de otra consulta XPath.

Por ejemplo, mostrar todos los títulos de los libros del autor que escribió "TCP/IP Illustrated". Si nos fijamos, en ningún caso nos están diciendo el nombre del autor, por lo que tendremos que hacer una consulta previa para localizarlo. Los pasos serían los siguientes:

1) Encontrar primero al autor del libro "TCP/IP Illustrated", pero mostrando sólo el texto sin las etiquetas. Esta consulta nos devolverá Stevens.

/bib/book[title="TCP/IP Illustrated"]/author/text()

2) A continuación debemos encontrar todos los libros que escribió dicho autor, en nuestro caso Stevens.

/bib/book[author="Stevens"]/title

3) Pero claro, la consulta anterior no es la correcta, porque no podemos usar el nombre de Stevens. Tendremos que sustuir la consulta 1 dentro de la consulta 2, pero eliminando las comillas dobles:

/bib/book[author=/bib/book[title="TCP/IP Illustrated"]/author/text()]/title

 

Sintaxis abreviada y compleja

Existen dos sintaxis diferentes a la hora de escribir consultas XPath:

  • Sintaxis abreviada: más sencilla y fácil de leer. Todos los ejemplos anteriores corresponden a esta sintaxis.
  • Sintaxis compleja: más larga y compleja de leer. Utiliza los ejes para nombrar los elementos.

 

Ejes

Los ejes son expresiones que permiten acceder a trozos del árbol XML apoyándose en las relaciones de parentesco entre los nodos. En las siguientes definiciones, el nodo de contexto se refiere al nodo al que se le está aplicando el eje.

self:: Devuelve el propio nodo de contexto. Equivale a .
child:: Devuelve los nodos hijo del nodo de contexto.
parent:: Devuelve el nodo padre del nodo de contexto. Equivale a ..
ancestor:: Devuelve los nodos antepasados (padre, abuelo, ...) del nodo de contexto.
ancestor-or-self:: Devuelve los nodos anteasados (padre, abuelo, ...) además del propio nodo de contexto.
descendant:: Devuelve los nodos descendientes (hiejo, nieto, ...) del nodo de contexto.
descendant-or-self:: Devuelve los nodos descendientes (hijo, nieto, ...) además del propio nodo de contexto. Equivale a //
following:: Devuelve los nodos que aparezcan después del nodo de contexto en el documento, excluyendo a los nodos descendientes, los atributos y los nodos de espacio de nombres.
preceding:: Devuelve los nodos que aparezcan antes del nodo de contexto en el documento, exluyendo a los nodos ascendientes, los atributos y los nodos de espacio de nombres.
following-sibling:: Devuelve los hermanos menores del nodo de contexto.
preceding-sibling:: Devuelve los hermanos mayores del nodo de contexto.
attribute:: Atributos del nodo de contexto.
namespace:: Espacio de nombres del nodo de contexto.

 

Ejemplos de sintaxis compleja

Para listar todos los títulos de los libros:

/child::bib/child::book/child::title

/bib/book/title

Para listar los hermanos menores del segundo autor:

/bib/book/author[2]/following-sibling::*

Para listar los descendientes de elemento ráiz en los que el nodo se llame year:

/bib/descendant::year

/bib//year

 

Bibliografía

  • Lenguajes de marcas y sistemas de gestión de información. J. M. Castro Ramos, J. R. Rodríguez Sánchez. Garceta 2012. ISBN 978-84-1545-217-1.
  • XPath - Tecnologías XML. Data2type GmbH
  • XPath: XML Path language. Sintes Marcos, Bartolomé. MCLibre