Localización

La localización es la expresión que permite al procesador seleccionar nodos o un conjunto de nodos. Esta localización se conoce como camino o ruta de localización y puede presentar diversas formas:

  • con sintaxis abreviada o completa
  • como ruta de localización relativa o absoluta.

Sintaxis abreviada o completa

En XPath existen dos formas de sintaxis, que en la práctica se pueden utilizar de manera combinada. La sintaxis abreviada se usa normalmente cuando se trata de nodos y ejes que son seleccionados con mucha frecuencia, mientras que la sintaxis completa se utiliza en caso de nodos y ejes a los que se accede con menor frecuencia. En los siguientes apartados se utilizará la sintaxis completa, recurriendo a la sintaxis abreviada cuando se trate de expresiones más frecuentes.

Un ejemplo de sintaxis completa:

/child::libro/child::autor/child::nombre/attribut::apellido

En sintaxis abreviada:

/libro/autor/nombre/@apellido

En la sintaxis abreviada se prescinde del nombre del eje child:: y el atributo se introduce anteponiendo el carácter @. En los próximos ejemplos se ofrecerán más detalles sobre la sintaxis abreviada.

Equivalencias entre sintaxis completa y abreviada

Sintaxis completaSintaxis abreviada
child:: Eje por defecto. Se puede omitir.
attribute:: @
descendant-or-self::node()/ //
self::node() .
parent::node() ..

Rutas relativas y absolutas

La ruta de localización XPath puede ser relativa o absoluta. Una ruta absoluta comienza por el nodo raíz, que es el nodo situado directamente sobre el elemento raíz. Esta distinción es necesaria, ya que desde el elemento raíz no sería posible acceder, por ejemplo, a comentarios o instrucciones que se encuentran fuera del mismo.
Las rutas de localización constan de pasos de localización separados por /.

Un ejemplo:

/child::Europa/child::pais/child::nombre

En este caso se trata de una ruta absoluta que parte del nodo raíz. El nodo raíz se indica mediante una barra diagonal. Desde ahí se selecciona el elemento raíz <Europa>. La expresión generará un resultado si el elemento raíz tiene un nodo hijo <pais> y éste a su vez contiene un nodo hijo <nombre>. Los ejes se definen mediante el nombre del eje seguido de dos signos de dos puntos. En el caso del eje child, puede omitirse la expresión child::. Así, la ruta de localización Europa/pais/nombre equivale a la ruta del ejemplo con sintaxis abreviada. Por el contrario, las rutas de localización relativas necesitan un nodo de contexto. La ruta se evaluará desde esta posición.

Ejemplo:

child::pais/child::nombre

De igual forma que en la ruta absoluta, en este caso se generará un resultado si el nodo de contexto tiene un nodo hijo <pais>, que a su vez posee un nodo hijo <nombre>.

La descripción aquí presentada de las rutas relativas es incompleta. Podrá encontrar más información sobre rutas relativas en literatura especializada sobre XPath.

Ejemplos de XPath en el contexto de una hoja de estilo XSLT

Nuestro ejemplo Europa.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>          
<Europa>
    <pais>
        <nombre>Alemania</nombre>
        <habitantes unidad="millones">82.4</habitantes>
        <capital>Berlín</capital>
        <sigla-pais>D</sigla-pais>
        <prefijo>0049</prefijo>
    </pais>
    <pais>
        <nombre>Francia</nombre>
        <habitantes unidad="millones">58.5</habitantes>
        <capital>Paris</capital>
        <sigla-pais>F</sigla-pais>
        <prefijo>0033</prefijo>
     </pais>
     <pais>
        <nombre>España</nombre>
        <habitantes unidad="millones">39.4</habitantes>
        <capital>Madrid</capital>
        <sigla-pais>E</sigla-pais>
        <prefijo>0034</prefijo>
     </pais>
</Europa> 

A continuación se muestra un ejemplo de XSLT con expresiones XPath:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">                                                (1)
      <html>
         <title></title>
         <body>
            <h3>
                <xsl:apply-templates/>
            </h3>
         </body>
      </html>
   </xsl:template>
   <xsl:template match="Europa">                                           (2)                    
   <xsl:if test="pais/nombre">                                             (2)
    RESULTADO : /Europa/pais/nombre
    <br/>
   </xsl:if>
   <xsl:if test="pais/habitantes">                                         (3)
    RESULTADO : /Europa/pais/habitantes
    <br/>
   </xsl:if>
   <xsl:if test="pais/capital">                                            (4)        
    RESULTADO : /Europa/pais/capital
    <br/>
   </xsl:if>
   <xsl:if test="child::habitantes">                                       (5)
    RESULTADO : /Europa/habitantes
    <br/>
   </xsl:if>
   <xsl:if test="descendant::habitantes">                                  (6)
    RESULTADO : /Europa/descendant::habitantes
    <br/>
   </xsl:if>
   <xsl:if test="pais/nombre/following-sibling::habitantes">               (7)
    RESULTADO : /Europa/pais/nombre/following-sibling::habitantes
    <br/><br/><br/><br/>
   </xsl:if>
   <xsl:if test="pais/nombre/following-sibling::habitantes/                (8)  
    parent::pais/descendant::capital">
    RESULTADO : /Europa/pais/nombre/following-sibling::habitantes/
    parent::pais/descendant::capital
    <br/><br/><br/><br/>
   </xsl:if>
   <xsl:apply-templates/> 
   </xsl:template> 
   <xsl:template match="pais">                                             (9)
   <xsl:if test="capital"> RESULTADO : /Europa/pais/capital                (9)
       <br/>
   </xsl:if> 
   <xsl:if test="parent::Europa"> RESULTADO : /Europa/pais/parent::Europa  (10)
       <br/>
   </xsl:if>
   </xsl:template>
</xsl:stylesheet>
 

(1) El carácter / indica el nodo raíz.

(2) El elemento <xsl:template> se refiere al elemento raíz <Europa>. En los siguientes elementos <xsl:if> se trata en cada caso del nodo de contexto. Esto significa que todas las rutas de localización siguientes partirán desde este punto. En el primer ejemplo la condición son los pasos de localización pais/nombre. Puesto que existe un nodo hijo de <Europa> con el elemento <pais>, que a su vez posee un nodo hijo con el elemento <nombre>, se copiará el contenido de <xsl:if> en el resultado. En el resultado generado aparecerá la ruta absoluta /Europa/pais/nombre.

(3) Otro ejemplo que muestra la posición del nodo de contexto.

(4) Otro ejemplo que muestra la posición del nodo de contexto.

(5) En este caso no se generará ningún resultado, ya que, partiendo del nodo de contexto <Europa>, no existe ningún nodo hijo con el elemento <habitantes>. En esta expresión hubiera sido suficiente escribir "habitantes", que se correspondería con la sintaxis abreviada de "child::habitantes".

(6) Aquí se genera de nuevo un resultado, ya que el elemento <Europa> posee un descendiente <habitantes>.

(7) En este punto el procesador busca en un nodo hermano (following-sibling::) un elemento <habitantes> situado tras el elemento <nombre>. Ambos tienen como padre al elemento <pais>. Puesto que el elemento <habitantes> está situado tras <nombre>, se genera un resultado.

(8) A través de este patrón de búsqueda se muestra cómo es posible aumentar la complejidad de las expresiones. Aquí se busca un elemento <pais> que es hijo del nodo de contexto <Europa>. El elemento <pais> tendrá a su vez un hermano posterior <habitantes>. Hasta aquí la consulta se corresponde con las anteriores, por lo que sabemos que se cumplen estas condiciones. El elemento <habitantes> deberá tener además un descendiente <capital>. Como puede comprobarse en el resultado, se cumplen todas las condiciones.

(9) La nueva plantilla hace que se cambie el nodo de contexto. Los patrones de búsqueda ahora tendrán como nodo contextual el elemento <pais>. Aquí se realiza la consulta, si el elemento <pais> tiene un elemento hijo <capital>.

(10) Aquí se busca el elemento padre <Europa> del nodo de contexto <pais>.

A continuación se muestra el resultado obtenido:

<html>
<title></title>
<body>
   <h3> 
       RESULTADO : /Europa/pais/nombre                                         (2)
       <br/> 
       RESULTADO : /Europa/pais/habitantes                                     (3)
       <br/>
       RESULTADO : /Europa/pais/capital                                        (4)
       <br/> 
       RESULTADO : /Europa/descendant::habitantes                              (6)
       <br/> 
       RESULTADO : /Europa/pais/nombre/following-sibling::habitantes           (7)
       <br/><br/><br/><br/> 
       RESULTADO : /Europa/pais/nombre/following-sibling::habitantes/          (8)
       parent::pais/descendant::capital 
       <br/><br/><br/><br/> 
       RESULTADO : /Europa/pais/capital                                        (9)
       <br/> 
       RESULTADO : /Europa/pais/parent::Europa                                 (10)
       <br/> 
       RESULTADO : /Europa/pais/capital                                        (9)
       <br/> 
       RESULTADO : /Europa/pais/parent::Europa                                 (10)
       <br/> 
       RESULTADO : /Europa/pais/capital                                        (9)
       <br/> 
       RESULTADO : /Europa/pais/parent::Europa                                 (10)
       <br/>
  </h3>
</body>
</html>

Vista del navegador

En determinadas composiciones tipográficas se desea sangrar la primera línea de cada párrafo, con la exceción de las líneas que siguen directamente a los títulos sangrados a la izquierda. La primera de las plantillas presentadas a continuación define la composición de los párrafos en general, mientras que la segunda lo hace para aquellos párrafos se encuentran directamente tras el encabezamiento. El elemento para los párrafos se denomina <para> y para los títulos <title>.

<xsl:template match="para">
   <fo:block text-indent="6mm"><xsl:apply-templates/></fo:block>
</xsl:template>
<xsl:template match="para[preceding-sibling::*[1][self::title]]">
   <fo:block text-indent="0mm"><xsl:apply-templates/></fo:block>
</xsl:template>

Como apoyo ofrecemos aquí otros ejemplos de rutas:

  • child::Europa devuelve los elementos hijo de <Europa>.
  • child::node() devuelve los nodos hijo del nodo de contexto.
  • attribute::unidad es la sintaxis completa de la expresión abreviada @unidad y devuelve el contenido del atributo unidad del nodo de contexto.
  • descendant::Europa devuelve los descendientes del elemento <Europa> .
  • self::Europa devuelve el elemento <Europa> en caso de que él mismo sea el nodo de contexto.
  • / devuelve el elemento raíz.
  • //*/@* devuelve todos los atributos de todos los elementos.
  • /child::comment() devuelve todos los nodos comentario que sean hijos del nodo raíz.

Localización de distintos tipos de nodos

Hasta ahora nos hemos ocupado sobre todo con los nodos elemento. No obstante, existen otros tipos de nodo que pueden ser seleccionados para su posterior análisis y procesamiento. La siguiente tabla muestra ejemplos de cómo se realiza tal selección.

nombre/text() En caso de que se quiera acceder al nodo de texto del elemento nombre se deberá usar la prueba de nodo text().
direccion/comment() En caso de que se quiera acceder al nodo de comentario del elemento direccion se deberá usar la prueba de nodo coment().
localidad/processing-instruction() En caso de que se quiera acceder al nodo de instrucción de procesamiento del elemento localidad se deberá usar la prueba de nodo processing-instruction().
dirección/node() Si se quiere acceder a todos los tipos de nodos (con excepción de los atributos) se deberá usar la prueba de nodo node().
<< anterior siguiente >>

© Derechos de autor 2007, dpunkt.verlag GmbH
El usuario podrá imprimir la versión online. La copia será exclusivamente para uso personal. Por lo demás el presente capítulo del libro publicado en lengua alemana "Professionelle XML-Verarbeitung mit Word" está sometido a los mismos términos y condiciones que la versión impresa. La presente obra está protegida en su totalidad por la ley de propiedad intelectual. Reservados todos los derechos, incluyendo los derechos de reproducción, traducción, microfilmación, así como el almacenamiento y procesamiento en sistemas electrónicos.

dpunkt.verlag GmbH, Ringstraße 19B, 69115 Heidelberg, téléfono +49 (0) 6221-14830, fax +49 (0) 6221-148399, hallo(at)dpunkt.de