Tutorial de Xpath para principiantes

Con la expansión de XML como lenguaje de marcado para el intercambio de datos multiplataforma, aumentó la necesidad de contar con un estándar que permitiese realizar consultas complejas en documentos XML a aplicaciones no basadas en XML.

Nota

El lenguaje de marcado extensible (XML, por sus siglas en inglés) es un lenguaje utilizado para la representación de datos estructurados de forma jerárquica en formato de texto. El lenguaje XML es legible tanto para humanos como para ordenadores y se emplea, entre otros, para intercambiar datos entre dos sistemas informáticos en Internet.

Con XQuery y XSLT, el W3C desarrolló los estándares necesarios para el acceso por software a documentos XML. Estos ponen a disposición interfaces de programación para que las aplicaciones accedan a los documentos XML y los transformen o consulten contenido. La condición necesaria en estos casos es un estándar que permita la localización de elementos en los documentos XML, esto es, un lenguaje de descripción de ruta: Xpath.

A continuación, explicamos el modelo de datos Xpath (XDM) y presentamos la sintaxis en la que se basan las expresiones Xpath para la localización de elementos XML.

¿Qué es Xpath?

XML Path Language (Xpath) es un lenguaje de descripción de rutas para documentos XML desarrollado por el W3C. Este lenguaje pone a disposición de los usuarios una sintaxis no basada en XML que permite encontrar elementos concretos en un documento XML.

Por lo general, Xpath viene integrado en un lenguaje host que permite el procesamiento de los elementos XML. XQuery, por ejemplo, sirve para extraer información de elementos XML localizados con Xpath. XSLT, por su parte, se sirve del lenguaje de consulta en la transformación de documentos XML.

  • Xpath: navegación en documentos XML
  • XQuery: consultas a documentos XML
  • XSLT: transformación de datos XML

La versión actual Xpath 3.1 está especificada en la recomendación de W3C del 21 de marzo de 2017.

Nota

A pesar de las actualizaciones, numerosos procesadores XSLT, buscadores web y aplicaciones soportan únicamente el estándar Xpath 1.0 del año 1999.

¿Cómo funciona Xpath?

Xpath se basa en un modelo de datos que interpreta el documento XML como una secuencia de elementos ordenados en una estructura de árbol. Esta estructura del modelo de datos Xpath es comparable a la del Modelo de Objetos del Documento (DOM), que opera como interfaz entre HTML y JavaScript en el buscador web.

La localización de elementos XML se realiza basándose en el sistema de registro Unix, en forma de expresiones de ruta. Los elementos básicos de estas rutas de localización son los nodos, los ejes, las pruebas de nodos y los predicados.

Tipos de nodos

Cada uno de los elementos de una estructura XML se denomina nodo. La clasificación de los nodos viene definida tanto por el orden de aparición en el documento como por el entrelazado de los elementos XML.

El modelo de datos Xpath distingue siete tipos de nodos con diferentes funciones:

  • Nodo de elemento (element node)
  • Nodo de documento (root node) (a partir de Xpath 2.0; antes denominado “nodo raíz”)
  • Nodo atributo (attribute node)
  • Nodo de texto (text node)
  • Nodo de espacio de nombres (namespace node)
  • Nodo de instrucción de procesamiento (processing instruction node)
  • Nodo de comentario (comment node)

Veamos los tipos de nodos del modelo de datos Xpath mediante un ejemplo. El siguiente documento XML sirve al intercambio de datos en el pedido de un libro y contiene los siete tipos de nodos.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Order SYSTEM "order.dtd">
<?xml-stylesheet type="text/css" href="style.css"?>

<!--That is a comment!-->

<order date="2019-02-01">
    <address xmlns:shipping="http://localhost/XML/delivery" xmlns:billing="http://localhost/XML/billing">
        <shipping:name>Ellen Adams</shipping:name>
        <shipping:street>123 Maple Street</shipping:street>
        <shipping:city>Mill Valley</shipping:city>
        <shipping:state>CA</shipping:state>
        <shipping:zip>10999</shipping:zip>
        <shipping:country>USA</shipping:country>
        <billing:name>Mary Adams</billing:name>
        <billing:street>8 Oak Avenue</billing:street>
        <billing:city>Old Town</billing:city>
        <billing:state>PA</billing:state>
        <billing:zip>95819</billing:zip>
        <billing:country>USA</billing:country>
    </address>
    <comment>Please use gift wrapping!</comment>
    <items>
        <book isbn="9781408845660">
            <title>Harry Potter and the Prisoner of Azkaban</title>
            <quantity>1</quantity>
            <priceus>22.94</priceus>
            <comment>Please confirm delivery date until Christmas.</comment>
        </book>
        <book isbn="9780544003415">
            <title>The Lord of the Rings</title>
            <quantity>1</quantity>
            <priceus>17.74</priceus>
        </book>
    </items>
</order>

Nodo de elemento (element node)

En el árbol de Xpath, cada uno de los elementos que conforman el documento XML constituye un nodo de elemento, con excepción de la declaración XML y la definición del tipo de documento, localizadas al principio del mismo.

Declaración XML:

<?xml version="1.0"? encoding="utf-8"?>

Definición del tipo de documento (DTD):

<!DOCTYPE Order SYSTEM "order.dtd">

Los nodos de elemento comienzan con una etiqueta de inicio y terminan con una etiqueta de cierre y, por lo general, se encuentran entrelazados.

El primer elemento del documento se denomina elemento raíz.

En el ejemplo anterior, el elemento raíz lo constituye el nodo order, que actúa de elemento padre del subconjunto de nodos address, comment y items, los cuales, a su vez, también contienen elementos hijo.

Nodo de documento (document node)

El documento es la raíz de la estructura de árbol. En el documento XML, este nodo no se manifiesta de forma visible ni está representado por texto; se trata, más bien, de un nodo conceptual que encierra todos los elementos del documento. Los elementos hijo del nodo de documento son tanto el elemento raíz como, dado el caso, el nodo de instrucción de procesamiento y el nodo de comentario.

Nodo atributo (attribute node)

El atributo de un elemento XML se representa en el modelo de datos Xpath como un nodo atributo. Cada uno de estos nodos consta de un identificador y de un valor subordinado.

En el código de ejemplo, el primer elemento book contiene el atributo isbn con el valor 9781408845660.

<book isbn="9781408845660">

El nodo atributo pertenece al nodo de elemento; no obstante, no se le considera un hijo.

Nodo de texto (text node)

Los caracteres encapsulados entre las etiquetas de un nodo de elemento se denominan nodo de texto.

En el ejemplo, el nodo de elemento title contiene el nodo de texto Harry Potter and the Prisoner of Azkaban.

Harry Potter and the Prisoner of Azkaban

Nodo de espacio de nombres

Los nombres de elementos y atributos de un documento XML correctamente constituido tienen asignado un espacio de nombre. Por lo general, esta asignación viene establecida por el DTD al principio del documento.

Si en un documento XML se emplean elementos o atributos con espacios de nombre diferentes, el espacio de nombre en cuestión se definirá explícitamente con ayuda del atributo xmlns o del prefijo xmlns en la etiqueta de inicio del elemento referido. El valor del atributo xmlns debe ser un Identificador Uniforme de recurso (URI) que indica a qué espacio de nombre se asigna un elemento. La asignación de un espacio de nombre a un prefijo xmlns puede realizarse tanto con el elemento como con todos los hijos. En la estructura de árbol, cada uno de los espacios de nombre se corresponde con un nodo de espacio de nombre.

En el código de ejemplo, se han definido para el elemento XML address dos espacios de nombre distintos: xmlns:shipping y xmlns:billing. Los hijos del elemento address cuentan con el prefijo correspondiente para su clasificación.

  <address xmlns:shipping="http://localhost/XML/delivery" xmlns:billing="http://localhost/XML/ billing">
        <shipping:name>Ellen Adams</shipping:name>
        <shipping:street>123 Maple Street</shipping:street>
        <shipping:city>Mill Valley</shipping:city>
        <shipping:state>CA</shipping:state>
        <shipping:zip>10999</shipping:zip>
        <shipping:country>USA</shipping:country>
        <billing:name>Mary Adams</billing:name>
        <billing:street>8 Oak Avenue</billing:street>
        <billing:city>Old Town</billing:city>
        <billing:state>PA</billing:state>
        <billing:zip>95819</billing:zip>
        <billing:country>USA</billing:country>
    </address>

En definitiva, el prefijo xmlns permite diferenciar claramente elementos de distintos espacios de nombre, por lo que, en el ejemplo, el elemento street con el prefijo shipping contiene la información sobre la dirección de envío, mientras que el elemento street con el prefijo billing hace referencia a la dirección de facturación.

Nodo de instrucción de procesamiento (processing instruction node)

Las instrucciones de procesamiento de los documentos XML se encuentran fuera del árbol del documento y se denominan nodos de instrucción de procesamiento. El nodo de instrucción de procesamiento comienza por <? y termina con ?>.

En el ejemplo de arriba, encontramos la siguiente instrucción de procesamiento:

<?xml-stylesheet type="text/css" href="style.css"?>

La construcción sintáctica de la declaración XML al principio del archivo es similar a la de una instrucción de procesamiento, aunque no se considera un nodo de instrucción de procesamiento en el sentido del modelo de datos Xpath.

Nodo de comentario (comment node)

En un documento XML, Xpath procesa el contenido marcado como comentario como un nodo de comentario. Este nodo engloba únicamente los caracteres destacados y no el marcado (Markup).

En el ejemplo anterior, encontramos el siguiente nodo de comentario:

That is a comment!

Rutas de localización

La búsqueda de nodos se realiza con ayuda de las denominadas rutas de localización. Una ruta de localización es una expresión Xpath empleada para navegar a través del árbol y seleccionar el conjunto deseado de nodos.

Las rutas de localización se analizan de izquierda a derecha y pueden ser absolutas o relativas. Una ruta absoluta comienza en el nodo de documento y viene especificada por la barra diagonal (/). Por el contrario, las rutas de localización relativas pueden comenzar en cualquier otro nodo dentro de la estructura de árbol, en cuyo caso, el punto de partida recibe el nombre de nodo de contexto.

La expresión de ruta consta de pasos separados por barras diagonales (/), de forma similar al direccionamiento de ficheros en un sistema de registro.

Cada uno de los pasos de una expresión de ruta consta de hasta tres partes: eje, prueba de nodo y un número cualquiera de predicados.

  • Eje: el eje determina la dirección de la navegación en la estructura de árbol a partir de los nodos de contexto o los nodos de documento.
  • Prueba de nodo: la prueba de nodo es un filtro con el que se delimita a un conjunto de nodos entre todos los que se sitúan en el eje.
  • Predicados: los predicados brindan la oportunidad de filtrar de nuevo los nodos seleccionados por los pasos de eje y la prueba de nodo.

Los pasos de localización de una expresión Xpath se definen conforme a la siguiente sintaxis:

Eje::prueba de nodo[predicado1][predicado2]…
Notación Función
/ Actúa como separador de los pasos de una ruta
:: Actúa como separador entre el eje y la prueba de nodo

Ejes

La sintaxis Xpath permite navegar por medio de los siguientes ejes.

Eje Denominación en español Nodos seleccionados
child hijo Todos los nodos hijo directamente subordinados
parent nodo padre Los nodos padre inmediatamente por encima
descendant descendiente Todos los nodos descendientes del nodo de contexto
ancestor* ancestro Todos los nodos por encima del nodo de contexto
following nodos siguientes Todos los nodos que aparecen después del nodo de documento, con excepción de los nodos descendientes
preceding* nodos anteriores Todos los nodos que se encuentran antes del nodo de contexto, con excepción de los ancestros
following-sibling hermanos menores Son todos los nodos del documento XML que proceden de un mismo nodo padre
preceding-sibling* hermanos mayores Son todos los nodos precedentes del documento XML que proceden de un mismo nodo padre
attribute atributo Todos los nodos atributo de un nodo de elemento
namespace espacio de nombre Todos los nodos de espacio de nombre de un nodo de elemento; este eje no se encuentra en las especificaciones a partir de la versión 2.0.
self nodo en curso El nodo de contexto en curso
descendant-or-self descendientes y el nodo en curso Todos los nodos descendientes del nodo de contexto y el nodo de contexto
ancestor-or-self* El nodo de contexto y sus ancestros Todos los nodos antecesores al nodo de contexto y el nodo de contexto
Nota

Los ejes marcados con asterisco (*) son aplicaciones regresivas que, de conformidad con la versión 1.0 de la especificación Xpath, constituyen un elemento opcional que no deben soportar obligatoriamente las aplicaciones estándares.

El siguiente gráfico muestra una representación esquemática de los ejes más importantes en el modelo de datos Xpath, partiendo del nodo de contexto (en rojo).

El eje child::, por ejemplo, devuelve todos los elementos hijo del nodo de contexto D: el conjunto de nodos comprende los nodos E, H e I.

Prueba de nodo

Con la prueba de nodo, se filtra el conjunto de nodos seleccionados por el eje. Conforme a la especificación Xpath, existen dos criterios posibles.

  • Nombre de nodo: filtrar los nodos en el eje que tengan un determinado nombre.
  • Tipo de nodo: seleccionar todos los nodos en un eje que compartan el mismo tipo.

Nombre de nodo como criterio de filtro

En el código de ejemplo anterior, podrían seleccionarse, con la siguiente expresión de ruta, todos los descendientes del nodo de documento que cuenten con el nombre book.

/descendant::book

No obstante, si entre todos los nodos de elemento con el nombre book, deseas filtrar únicamente aquellos con el atributo isbn, necesitas una expresión de ruta con dos pasos.

/descendant::book/attribute::isbn

Tipo de nodo como criterio de filtro

Si deseas definir un tipo de nodo como criterio de filtro para seleccionar un conjunto de nodos, emplea las siguientes funciones:

Función Nodos seleccionados
node() La función node() devuelve todos los nodos del eje seleccionado.
text() La función text() devuelve todos los nodos de texto del eje seleccionado.
comment() La función comment() devuelve todos los nodos de comentario del eje seleccionado.
processing-instruction() La función processing-instruction() devuelve todos los nodos de instrucción de procesamiento del eje seleccionado.
Nota

Xpath 1.0 define 25 funciones y, a partir de Xpath 2.0, se dispone de 111 funciones para la descripción de rutas de localización. Encontrarás un compendio en la recomendación W3C Xpath and XQuery Functions and Operators 3.1 del 21 de marzo de 2017.

Prueba de nodo con carácter comodín

Si, en lugar de las pruebas de nodo, empleas el espaciador * (asterisco), se devuelven todos los nodos que correspondan al tipo de nodo principal del eje seleccionado. Esto es, si un eje contiene un nodo de elemento, este será el tipo de nodo principal del eje. Esto se aplica a todos los ejes, con excepción de los atributos y los espacios de nombre, puesto que el tipo de nodo principal en estos casos sería el nodo atributo y el nodo de espacio de nombre, respectivamente.

La siguiente expresión de ruta, por ejemplo, devuelve todos los atributos del nodo de contexto en curso:

attribute::*

Notación abreviada

Para los ejes empleados con frecuencia y los pasos de localización, se han definido abreviaturas que pueden ser utilizadas en lugar de la expresión de ruta completa en inglés.

Notación estándar Abreviatura Ejemplo
child:: vacío child es el eje estándar y su descripción se puede suprimir. Por tanto, la expresión de ruta child::book/child::title quedaría abreviada en book/title.
attribute:: @ El eje attribute, incluidos los puntos, se puede abreviar con el símbolo @.
La expresión de ruta book/attribute::isbn devuelve el nodo atributo isbn del elemento book y se representa con notación abreviada como: book/@isbn.
/descendant-or-self::node()/ // El paso de localización /descendant-or-self::node()/ devuelve el nodo de documento y todos los descendientes; su forma abreviada es //. En lugar de /descendant-or-self::node()/child::item, escribe //item y la ruta de localización devuelve todos los nodos item del documento.
parent::node() .. El paso parent::node() devuelve el nodo padre del nodo de contexto y se abrevia con .. .
self::node() . El paso self::node() devuelve el nodo de contexto en curso y se abrevia con . .

Predicados

Los predicados permiten afinar la búsqueda de nodos realizada mediante el eje y la prueba de nodo.

Constituyen la tercera parte de un paso de localización, son opcionales y se incluyen utilizando corchetes. Los criterios de filtro entre corchetes se formulan como expresiones que contienen, entre otros, expresiones de ruta, funciones, operadores y cadenas.

Xpath soporta tanto predicados generales como numéricos.

Predicados generales

Los predicados generales filtran el conjunto de nodos seleccionados a través del eje y de la prueba de nodo, asignando un valor booleano (verdadero o falso) a cada nodo, de modo que solo los nodos que cumplen con la condición y tienen un valor verdadero se incluyen en el resultado.

La formulación de expresiones para predicados generales se realiza por medio de operadores. Estos se utilizan para seleccionar nodos con contenido o características específicas, como, por ejemplo, todos los nodos con unos determinados caracteres, un atributo o un elemento hijo preestablecido (a poder ser, en una determinada posición).

En las tablas siguientes, puede verse un resumen de los operadores disponibles, los cuales se clasifican en operadores aritméticos, lógicos y de comparación.

Operadores aritméticos Función
+ suma
- resta
* multiplicación
div resultado entero de la división
mod módulo
Operadores de comparación Función
= igual
!= no igual
< menor que; en XSLT, se necesita el operador &lt;
> mayor que; en XSLT, se recomienda usar el operador &gt;
<= menor que o igual; en XSLT, se necesita el operador &lt;
>= Mayor que o igual; en XSLT, se recomienda usar el operador &gt;
Operadores lógicos Función
and Operador Y lógico
or Operador O lógico

En el siguiente ejemplo, el predicado [title="Harry Potter and the Prisoner of Azkaban"] limita los resultados a un nodo de elemento llamado book, cuyo elemento hijo title contiene la cadena de caracteres Harry Potter and the Prisoner of Azkaban.

Nota

El ejemplo emplea la sintaxis de Xpath 3, que, dado el caso, podría no ser soportada por todas las herramientas online. Los ejemplos de consulta que presentamos aquí se ven fácilmente con el siguiente tester online: http://videlibri.sourceforge.net/cgi-bin/xidelcgi.

/order/items/book[title="Harry Potter and the Prisoner of Azkaban"] 

Aquí, hemos seleccionado el nodo de elemento book, que contiene los datos para el libro de Harry Potter.

<book isbn="9781408845660">
            <title>Harry Potter and the Prisoner of Azkaban</title>
            <quantity>1</quantity>
            <priceus>22.94</priceus>
            <comment>Please confirm delivery date until Christmas.</comment>
        </book>

Otro elemento hijo de este nodo de elemento es comment. La expresión de ruta solo tendría que prolongarse con dos pasos más si queremos seleccionar su contenido.

/order/items/book[title="Harry Potter and the Prisoner of Azkaban"]/comment/text()

Con el paso comment (abreviación de child::comment) navegamos hasta el hijo del elemento book del mismo nombre y seleccionamos su nodo de texto con la función text(). Esto corresponde a la siguiente cadena de caracteres:

Please confirm delivery date until Christmas.

Cuando se emplea una única expresión de ruta en un predicado, se habla de una prueba de existencia. Con la expresión de ruta que se muestra a continuación, se comprobó si el documento XML de arriba contiene uno o más nodos con el nombre de comment.

Notación abreviada:

//book[comment]

Notación estándar:

/descendant-or-self::node()/child::book[child::comment]

La ruta //book[comment] devuelve todos los nodos con el nombre book que tienen un elemento hijo llamado comment.

Predicados numéricos

Los predicados numéricos permiten localizar nodos indicando su posición. La expresión de ruta a continuación devuelve el segundo nodo en base a su posición en el documento; el nombre del nodo es book.

//book[2]

En sentido estricto, el predicado [2] es una abreviación de [position()=2]. Con ello, Xpath selecciona en primer lugar todos los nodos con el nombre book y filtra seguidamente los nodos en los que la función position()=2  tiene valor booleano verdadero.

Nota

Al contrario que con otros lenguajes de programación, las enumeraciones en Xpath comienzan con 1.

Información adicional sobre XML Path Language

En el sitio web de W3C, encontrarás una vista general de los niveles de desarrollo en los que se encuentra XML Path Language, así como de todos los estándares y borradores.

De igual modo, encontrarás herramientas e información gratuitas para la utilización de Xpath con aplicaciones web en MDN Web Docs y en Microsoft Developer Network.


¡No te vayas! ¡Tenemos algo para ti!
Consigue tu dominio .es un año gratis.

Introduce el dominio que deseas en la barra de búsqueda para comprobar su disponibilidad.
12 meses desde 0€/año IVA incl.
después 10 €/año IVA incl.