domingo, 25 de enero de 2015

XML Schemas y Xpath (Parte III)

Xpath

Xpath nos permite seleccionar de un documento XML elementos, atributos, texto, y todo lo relativo al propio documento. En Xpath, los elementos y propiedades se establecen en forma de árbol, como si se tratase de un sistema de archivos unix. Así pues, partiremos de un elemento raíz representado por “/”, y se bajarán niveles poniendo de nuevo “/”. Por ejemplo, para el siguiente documento XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<liga>
  <equipo nombre="Real Madrid" estadio="Santiago Bernabeu">
    <jugador extranjero="no">
      <nombre>Iker Casillas</nombre>
      <posicion>Portero</posicion>
      <edad>28</edad>
      <patrocinador marca="adidas"/>
    </jugador>
    <jugador>
      <!-- Esto es un comentario -->
      <nombre>Xabi Alonso</nombre>
      <posicion>Medio</posicion>
      <edad>27</edad>
      <patrocinador marca="nike"/>
    </jugador>
    <jugador extranjero="si">
      <nombre>Cristiano Ronaldo</nombre>
      <posicion>Delantero</posicion>
      <edad>24</edad>
      <patrocinador marca="nike"/>
    </jugador>
  </equipo>

  <equipo nombre="FC Barcelona" estadio="Camp Nou">
    <jugador extranjero="no">
      <nombre>Valdés</nombre>
      <posicion>Portero</posicion>
      <edad>22</edad>
      <patrocinador marca="adidas"/>
    </jugador>
    <jugador>
      <nombre>Xavi</nombre>
      <posicion>Medio</posicion>
      <edad>29</edad>
      <patrocinador marca="Kappa"/>
    </jugador>
    <jugador extranjero="si">
      <nombre>Lionel Messi</nombre>
      <posicion>Delantero</posicion>
      <edad>23</edad>
      <patrocinador marca="kappa"/>
    </jugador>
  </equipo>
</liga>


Para seleccionar todos los equipos, emplearemos:

/liga/equipo

También es posible seleccionar elementos desde cualquier nivel del árbol. Para ello, se empleará “//”:

//equipo

Xpath nos permite además seleccionar elementos sin necesidad de conocer su nombre. Esta forma es muy parecida a la de un sistema Unix, y seleccionaría todos los subelementos dentro de equipo:

            //equipo/*

También podemos hacer selecciones que no sean a etiquetas. Por ejemplo, lo siguiente seleccionará el texto que hay entre los elementos de equipo:
            //equipo/text()

Los comentarios del documento también se pueden seleccionar. Para ello, puede hacerse uso de lo siguiente:

//equipo/jugador/comment()


Lo siguiente seleccionaría tanto texto, comentarios como elementos:

//equipo/node()

No hay que olvidar, que los anteriores ejemplos toman únicamente los hijos directos, y no seleccionará aquello que se encuentre dentro de los subelementos. Lo siguiente, seleccionaría TODO lo que se encuentra dentro de equipo, siendo tanto texto, comentarios como elementos, de forma individual:

            //equipo//node()

Ejes o hachas

Los ejes (o también llamados hachas) complementan el método de selección de elementos y atributos.  Por ejemplo, para la selección de un atributo podemos emplear:

            //patrocinador/attribute::marca

Todos los ejes se establecen mediante una palabra clave, seguida de “::”. Lo anterior, que nos permite seleccionar el valor del atributo marca, es un sinónimo de:

            //patrocinador/@marca

También podríamos usar un eje para seleccionar el elemento padre:

            //patrocinador/parent::*

Lo cual sería equivalente a:

            //patrocinador/../*
Existen un total de 13 ejes disponibles, los cuales nos permiten seleccionar elementos y propiedades de los mismos.

Predicados

Los predicados nos permiten delimitar los resultados que se nos mostrarán. Se definen entre paréntesis y pueden establecerse sobre cualquier elemento. El siguiente predicado tomaría únicamente aquellos jugadores que posean el atributo extranjero:

            //jugador[@extranjero]

En cambio, el siguiente tomaría únicamente los que no lo tengan:

            //jugador[not(@extranjero)]

En el siguiente caso, se tomaría únicamente el primer jugador (de cada equipo):

            //jugador[1]

En el siguiente caso, obtendríamos únicamente el primer resultado de la operación “//jugador”:

            (//jugador)[1]

Los predicados permiten operadores lógicos. Por ejemplo, en el siguiente caso, se tomarán únicamente aquellos jugadores que sean mayores a 25 años:

            //jugador[edad > 25]

En el anterior predicado, se ha tomado en cuenta un elemento dentro de jugador, partiendo de este mismo. Esto es posible porque en los predicados, se introduce el mismo concepto de enlace relativo de los sistemas Unix. Esto quiere decir, que es como partiésemos del “directorio jugador”.

Los predicados son acumulativos, debiéndose cumplir la condición de todos los predicados, como si se tratasen de operadores and. En el siguiente predicado, se limitará a mayores de 25 años, y que además, el elemento padre de “jugador” tenga atributo nombre = “FC Barcelona”.

            //jugador[edad > 25][../@nombre = "FC Barcelona"]

Lo anterior será equivalente a:

            //jugador[edad > 25 and ../@nombre = "FC Barcelona"]

Los operadores aritméticos son:

Símbolo
Operación
+
Suma
-
Resta
div
División
idiv
Disión entera
mod
Módulo
*
Multiplicación

Los operadores lógicos son:
     and
     or
     not

Los operadores relacionales son: =, !?, <, >, <= y >=.

Funciones

Las funciones en Xpath tienen un comportamiento parecido al de cualquier lenguaje de programación, devolviendo un resultado en función a los argumentos entregados a la misma. Las funciones son ejecutadas mediante la sintaxis <nombre función>(). Por ejemplo, position().






Algunas de las funciones más comunes son:

Función
Descripción
not(<condición>)
Niega una condición.
position()
índice de elemento en resultados (índice 1).
last()
Último número de elemento esperado en resultados.
name()
Devuelve el nombre de la etiqueta del nodo actual.
name(<elemento>)
Devuelve el nombre de la etiqueta del elemento.
concat(*args)
Concatenar elementos en una cadena de texto.
starts-with(<orig>, <comp>)
Devuelve true si el primer argumento comienza por el segundo argumento.
ends-with(<orig>, <comp>)
Igual que starts-with, pero terminando.
substring(<cadena>, <start>, <end>)
Obtener la cadena de texto entre las posiciones <start> y <end>.
avg(<elementos>)
Obtener la media entre los valores de los elementos.
count(<elementos>)
Obtener el número de elementos.
sum(<elementos>)
Suma total de los valores de los elementos.
min(<elementos>)
La máxima de los valores de los elementos.
max(<elementos>)
La mínima de los valores de los elementos.
string-length(<elemento>)
Longitud de texto del elemento.

Algunos ejemplos de su uso podrían ser:

El elemento no posee atributo alguno:

//*[not(@*)]

El jugador no pertenece al primer equipo del documento:

            //equipo[not(position() = 1)]/jugador

Todos los elementos del tercer jugador del documento, salvo el patrocinador:

            (//jugador)[3]/*[name() != “patrocinador”]

Suma, máxima, mínima y media de las edades de los jugadores:

concat("De ", count(//jugador), " jugadores que tenemos, la edad mínima es ", min(//edad), " la máxima es ", max(//edad), " la suma es ", max(//edad), " y la media es ", avg(//edad))



No hay comentarios:

Publicar un comentario

¡Danos tu opinión!