Está en la página 1de 74

Unidad10.XSLT.

Unidad 10. XSLT.


ndice de contenido
Unidad 10. XSLT.............................................................................................................................1 1. Transformacin de documentos (XSLT)......................................................................................1 2. Elementos Bsicos.......................................................................................................................9 <xsl:attribute> y <xsl:element> ......................................................................................15 <xsl:comment> y <xsl:text> ...........................................................................................18 <xsl:copy> ......................................................................................................................18 5. Las plantillas..............................................................................................................................39 6. Java y XML...............................................................................................................................42 7. Ejemplo Cooperativa Agraria....................................................................................................68

1. Transformacin de documentos (XSLT)


Se puede aplicar una Hoja de estilos CSS a un documento XML con un comportamiento semejante a las hojas de estilos en HTML. Cada uno las etiquetas particulares del documento XML se comporta como una etiqueta HTML. Partimos de un documento que almacena datos sobre facturas con la siguiente estructura:
datatypes xsd = "http://www.w3.org/2001/XMLSchema-datatypes" start=element facturacion { element clientes {CLIENTE*}, element facturas {FACTURA*}} CLIENTE= element cliente { element nif {xsd:string}, element nombre {xsd:string}, element direccion {xsd:string}, element poblacion {xsd:string}, element telefono {xsd:string} } FACTURA= element factura {element numero {xsd:integer}, element nif {xsd:string}, element fecha {xsd:date}, element lineas {LINEA*}} LINEA= element linea { element descripcion {xsd:string}, element unidades {xsd:decimal}, element precio {xsd:decimal}}

Sobre este documento se construye un fichero XML con datos con una estructura como la que podemos observar a continuacin:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="file:/media/Datos/Curso11-12/proyecto1/facturacion.rnc" type="application/relax-ng-compactsyntax"?>
EnriqueMoraMoral.Pag: 1/74

Unidad10.XSLT.

<facturacion> <clientes> <cliente> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion>calle1</direccion> <poblacion>pueblo1</poblacion> <telefono>111-111-111</telefono> </cliente>

............................
</clientes> <facturas> <factura> <numero>1</numero> <nif>nif5</nif> <fecha>2012-01-01</fecha> <lineas> <linea> <descripcion>linea1</descripcion> <unidades>10</unidades> <precio>0.5</precio> </linea> <linea> <descripcion>linea2</descripcion> <unidades>20</unidades> <precio>1</precio> </linea> <linea> <descripcion>linea3</descripcion> <unidades>30</unidades> <precio>1.5</precio> </linea> </lineas> </factura>

............................
</facturas> </facturacion>

Este documento es visible desde el navegador y se visualiza ms o menos correctamente. Si se quiere aplicar una hoja de estilos donde los clientes vean en azul y las facturas en rojo comenzamos modificando la cabecera del documento donde se indica el fichero que contiene la hoja de estilos CSS en este caso facturacion.css:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="file:/media/Datos/Curso11-12/proyecto1/facturacion.rnc" type="application/relax-ng-compactsyntax"?> <?xml-stylesheet type="text/css" href="facturas.css"?>

Se ha aadido a la cabecera del documento XML la lnea:


<?xml-stylesheet type="text/css" href="facturacion.css"?>
EnriqueMoraMoral.Pag: 2/74

Unidad10.XSLT.

Ahora se puede disear el documentos facturacion.css con el siguiente contenido visto desde Google Chrome:

Se puede ajustar cada una de las reglas, por ejemplo que cada cliente y cada factura se muestre en una linea deferente:

Para este modificacin hemos modificado la hoja de estilos facturacion.css al siguiente formato:
cliente { color : blue; display : block; } factura { color : red; display : block; }

Se pueden aplicar todas las reglas vistas en XHTML/CSS para los elementos de los documentos XML con un comportamiento semejante al de este entorno. Es posible construir un documento XML que incorpore su propia hoja de estilos en un nodo interno que afecte al resto de los nodos. Como se puede apreciar en el siguiente ejemplo: <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/css" href="#estilo"?> <documento> <amarillo> texto en color amarillo por estar en amarillo </amarillo> <rojo> texto en color rojo por estar en rojo </rojo> <azul>
EnriqueMoraMoral.Pag: 3/74

Unidad10.XSLT.

texto en color azul por estar en azul </azul> <estilos id="estilo"> documento {} amarillo { color : yellow; display : block;} rojo { color : red; display : block;} azul { color : blue; display : block;} estilos { display : none; } </estilos> </documento> La aplicacin de los estilos es en principio normal salvo ligeros problemas. El primero es el uso de xpointer junto don id para seleccionar el nodo que contiene las descripciones de las hojas de estilo: <?xml-stylesheet type="text/css" href="#estilo"?> La sintaxis es semejante a la usada en la construccin de enlaces dentro del documento que se vio en XHTML. El nodo donde se incluye el cdigo CSS en este caso <estilos> identificado con id=estilo presenta un pequeo error al no ejecutar la primera regla, por lo que se ha introducido un regla vaca no necesaria para evitar este problema, en este caso: documento {} Quedando el siguiente cdigo CSS dentro del nodo: <estilos id="estilo"> documento {} amarillo { color : yellow; display : block;} rojo { color : red; display : block;} azul { color : blue; display : block;} estilos { display : none; } </estilos> En Mozilla muestra la siguiente transformacin al abrir el fichero de forma directa:

Las hojas de estilo XSLT tienen un comportamiento semejante a las hojas de estilo CSS. Transforman un documento XML (no funciona sobre XHTML, y si funciona con un comportamiento no deseado), pero las hojas de estilos XSLT no slo cambian ciertos aspectos visuales del documento si no que lo convierten en otro que puede ser un documento HTML, otro documento XML y un documento PDF (XSLT-FO), para realizar estas tareas XSLT incorpora
EnriqueMoraMoral.Pag: 4/74

Unidad10.XSLT.

elementos de programacin que nos permite recorrer, filtrar, ordenar, etc... documentos XML a partir de Xpath sobre el documento donde se enlazan pudiendo seleccionar elementos o partes de este a procesar y aplicar diferentes y complejas transformaciones. Al igual que las hojas de estilo CSS ya que se incluyen de forma semejante las hojas de estilo funcionan directamente desde el navegador aunque se pueden utilizar con otras tecnologas desde el lado del servidor por ejemplo el paquete PHPReports que incorpora Ubuntu, existen otras versiones para otras tecnologas semejantes como Python y Perl. Para enlazar una hoja de estilos XSLT basta con cambiar el tipo del documento de la hoja de estilos en la cabecera del documento como se puede observar en el siguiente cdigo:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="file:/media/Datos/Curso11-12/proyecto1/facturacion.rnc" type="application/relax-ng-compactsyntax"?> <?xml-stylesheet type="text/xsl" href="facturacion.xsl"?>

Exactamente se ha modificado la terceralinea:


<?xml-stylesheet type="text/xsl" href="facturacion.xsl"?>

Donde se ha cambiado el tipo type="text/css" por el tipo type="text/xsl" , en la etiqueta href se ha cambiado el fichero facturacion.css por facturacion.xsl con el siguiente contenido:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 4, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> Enrique Mora Moral</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <head></head> <body> <table border="3px"> <xsl:for-each select="facturacion/clientes/cliente"> <tr> <td> <xsl:value-of select="nombre"></xsl:value-of></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
EnriqueMoraMoral.Pag: 5/74

Unidad10.XSLT.

Esta hojas de estilos XSLT transforma el documento XML en un documento HTML mostrndose las siguiente ventana en el navegador:

Si se accede al cdigo fuente del documento se puede observar que es un documento que contiene nuestro documento XML original:

Incluso la apertura del documento anterior de forma directa desde Google Chrome no muestra ningn resultado. Pero Oxygen incorpora un mecanismo que simula a aplicacin de una hoja de estilos XSLT desde un entorno servidor devolviendo un documento HTML con cdigo HTML (XML, PDF, etc...) de forma directa y visible sin problemas en cualquier navegador como Google Chrome. Se comienza creando un Escenario de transformacin desde el siguiente Icono:

El escenario de Transformacin va a construir el documento HTML y abre el navegador sobre ese documento. Nada ms acceder a esta herramienta se abre la siguiente ventana:

EnriqueMoraMoral.Pag: 6/74

Unidad10.XSLT.

Si hubiera otros escenarios de transformacin se pueden borrar porque vamos a comenzar desde cero, se comienza desde el botn New creando un nuevo escenario de transformacin. El tipo de escenario puede ser:

XSLT transformation: cuando aplico el escenario en la hoja XSLT XML transformation with XSLT: cuando se define desde el documento XML valido para el documento XSLT.

Se escoge este ltimo y se pulsa New. Partimos del documento facturacion.xml. Se le da un nombre Faturacion y rellenamos la primera pestaa con la siguiente informacin:

De estos valores se ha fijado:


Name: en este caso facturacion. XML URL: documento de inicio para comenzar a trabajar. Se puede poner el nombre del fichero o una ruta de bsqueda por defecto Oxygen como este caso que corresponde con el fichero actual. XSL URL: documento XSLT. Transformer: librera que se va a utilizar para procesar el documento XML. En este caso una librera Saxon XX 9.3.0.5 porque la hoja XSLT utiliza la versin 2.0.

Una vez configurada esta pestaa pasamos a la segunda, que no se va a configurar porque corresponde con XSL-FO para la generacin de documento PDF que no vamos a tratar en este curso:
EnriqueMoraMoral.Pag: 7/74

Unidad10.XSLT.

Por ltimo pasamos a pestaa donde se configura la salida del documento donde se configura:

Donde:

Save as: guarda la transformacin en un fichero. Open in browser: nos abre el fichero que acabamos de crear con el navegador. Show As: nos permite visualizar nuestro documento en la parte inferior de Oxygen en la ventana de resultados. En este casi XML nos muestra el resultado en modo Codigo, HTML en modo navegador y SVG en modo grfico si hubiramos construido un grfico SVG

Se puede ejecutar la transformacin desde la ventana de transformaciones pulsando el botn Transform now o directamente pulsando el icono:

Una vez ejecutada la transformacin se mostrar la siguiente pantalla:

EnriqueMoraMoral.Pag: 8/74

Unidad10.XSLT.

Donde se puede observar:


Ejecucin de Google Chrome abriendo el fichero facturacion.html El contenido de la transformacin en cdigo HTML en la parte inferior de la ventana.

2. Elementos Bsicos.
Antes de comenzar a trabajar con el entorno XSLT es preciso indicar que se puede trabajar con dos tcnicas una en la se usan plantillas que recorren un rbol Xpath y que de forma automtica se expanden sobre otras plantillas que recorren sub-arboles de la plantilla original, o mediante bucles for-each que recorren de forma manual un rbol Xpath con un comportamiento en su programacin semejante a Xquery y a los entornos de programacin clsicos como Java. La gran ventaja de las plantillas, aunque utilice una especie de programacin funcional, es que nos permite dividir nuestro diseo en partes independiente y modulares que se activan de forma automtica o manual. Las plantillas se tratarn en un apartado especfico al final de la unidad. Vamos a comenzar con la estructura bsica si utilizar plantillas. Como se ha comentado anteriormente utiliza Xpath para recorrer el documento actual y es posible incluso acceder a otros documentos que no sean el que tiene la hoja XSLT teniendo un comportamiento semejante a Xquery. Continuando con el ejemplo de facturacin se va a construir una hoja XSLT denominada mostrarCliente.xsl que nos lista los clientes. Se modifica la cabecera del fichero facturacion.xml enlazando a la nueva hoja XSLT:
<?xml version="1.0" encoding="UTF-8"?> <?xml-model href="file:/media/Datos/Curso11-12/proyecto1/facturacion.rnc" type="application/relax-ng-compactsyntax"?>
EnriqueMoraMoral.Pag: 9/74

Unidad10.XSLT.

<?xml-stylesheet type="text/xsl" href="mostrarClientes.xsl"?> <facturacion>

Se procede a la creacin de mostrarClientes.xsl utilizando la versin 2.0, aunque con la versin 1.0 debera de funcionar, obteniendo el siguiente documento:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 8, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> </xsl:stylesheet>

Para mostrar los cliente es necesario obtener completar el siguiente cdigo:


<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 8, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <table> <xsl:for-each select="facturacion/clientes/cliente"> <tr> <td> <xsl:value-of select="nif"></xsl:value-of></td> <td> <xsl:value-of select="nombre"></xsl:value-of></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>

Se comienza introduciendo una plantilla genrica que enlaza al inicio del documento con el siguiente cdigo:
<xsl:template match="/"> </xsl:template>

Enr iqueMoraMoral.Pag: 10/74

Unidad10.XSLT.

Esta plantilla marca el inicio de recorrido de nuestro rbol Xpath, dentro de la platilla se introduce el cdigo HTML que no se repite por cada uno de los clientes. En este caso:
<html> <body> <table> </table> </body> </html>

Ahora se esta listo para comenzar a procesar cada uno de los clientes que vamos a realizarlo mediante xsl:foreach. En este caso, es necesario completar el rbol Xpath desde el inicio de la plantilla
<xsl:for-each select="facturacion/clientes/cliente"> <tr> <td> <xsl:value-of select="nif"></xsl:value-of></td> <td> <xsl:value-of select="nombre"></xsl:value-of></td> </tr> </xsl:for-each>

El xsl:foreach recorre cada uno de los elementos de nuestro sub-rbol y le aplica el contenido interior. En este caso crear una fila de la tabla y una columna para el nif y el nombre. En acceso a los valores de los elementos se realiza mediante xsl:value-of y el atributo select que nos permite acceder al nombre.

Parametros.
Existen varias tcnicas para acceder a un determinado elemento, una de ellas es el uso de los parmetros. Los parmetros nos permite seleccionar determinado elemento desde el navegador. Primero comenzamos modificando la hoja XSLT anterior aadiendo los elementos comentados anteriormente:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 8, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:param name="nif"></xsl:param> <xsl:template match="/"> <html> <body> <table> <xsl:for-each select="facturacion/clientes/cliente[nif=$nif]"> <tr> <td> <xsl:value-of select="nif"></xsl:value-of></td> <td> <xsl:value-of select="nombre"></xsl:value-of></td> </tr>
EnriqueMoraMoral.Pag: 11/74

Unidad10.XSLT.

</xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>

Donde se ha aadido la definicin de parmetro:


<xsl:param name="nif"></xsl:param>

Y se ha ajustado el parmetro como variable utilizando $ dentro de la expresin Xpath:


<xsl:for-each select="facturacion/clientes/cliente[nif=$nif]">

En nuestro caso funciona bajo Google Chrome. Es preciso aadir un parmetro en el escenario de transformacin. Se edita el escenario de transformacin y desde la coleccin de Parameters accedemos a la ventana de configuracin de los parmetros, donde le asignamos un valor:

En este caso 'nif1'. Tras este proceso obtenemos el siguiente resultado:

Uso de Variables. Las variables tienen un comportamiento semejante a los parmetros pero nos permiten almacenar valores intermedios que poder utilizar posteriormente en un rbol Xpath. Como ejemplo, supongamos que se quiere mostrar una determinada factura por numero junto con los datos del cliente (nombre, direccin, telfono y poblacin). Comenzamos con una nueva hojas de estilos XSLT que se va a denominar facturaListado.xsl. Se comienza con la construccin de la hoja, con un parmetro que muestra la cabecera de la factura, el cambio de hoja de XSLT en el fichero XML y la creacin del nuevo escenario con el parmetro correspondiente. Partiremos de querer sacar la segunda factura. Con el siguiente cdigo:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"

EnriqueMoraMoral.Pag: 12/74

Unidad10.XSLT.

exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 8, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:param name="numero"></xsl:param> <xsl:template match="/"> <html> <body> <xsl:for-each select="facturacion/facturas/factura[numero=$numero]"> Numero: <xsl:value-of select="numero"></xsl:value-of> Nif: <xsl:value-of select="nif"></xsl:value-of> Fecha: <xsl:value-of select="fecha"></xsl:value-of> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

Se obtiene:

No se puede acceder de forma directa a los datos contenidos en el nodo clientes con nif1, para es necesario describir una variable que recoja el nif para realizar una bsqueda de dicho nif en la lista de clientes. Para ello se implementa el siguiente cdigo:
<xsl:for-each select="facturacion/facturas/factura[numero=$numero]"> Numero: <xsl:value-of select="numero"></xsl:value-of> Nif: <xsl:value-of select="nif"></xsl:value-of> <xsl:variable name="nif" select="nif"></xsl:variable> <xsl:for-each select="/facturacion/clientes/cliente[nif=$nif]"> Nombre: <xsl:value-of select="nombre"></xsl:value-of> Direccion: <xsl:value-of select="direccion"></xsl:value-of> Poblacion: <xsl:value-of select="poblacion"></xsl:value-of> Telefono: <xsl:value-of select="poblacion"></xsl:value-of> </xsl:for-each> Fecha: <xsl:value-of select="fecha"></xsl:value-of> </xsl:for-each>

Que presenta el siguiente resultado:

Del cdigo modificado es necesario recalcar la declaracin de la variable contra el contenido


Enr iqueMoraMoral.Pag: 13/74

Unidad10.XSLT.

de un nodo, en este caso el nif de la factura:


<xsl:variable name="nif" select="nif"></xsl:variable>

Es posible construir esta variable de la siguiente forma, aunque no se recomienda:


<xsl:variable name="nif" >nif</xsl:variable>

Y el uso de la variable precedida del smbolo $, dentro de un xsl:for-each para seleccionar el cliente de nuestra factura:
<xsl:for-each select="/facturacion/clientes/cliente[nif=$nif]">

Por ltimo, falta para completar la factura listar las lineas de esta. El proceso de listado de las lineas es tan simple como introducir un bucle dentro de otro y recorrer las lineas de esa factura. Para mejorar algo la visualizacin se utilizan etiquetas <br/> para introducir saltos de linea.
<xsl:for-each select="lineas/linea"> <br/> Descripcion: <xsl:value-of select="descripcion"></xsl:value-of> Unidades: <xsl:value-of select="unidades"></xsl:value-of> Precio: <xsl:value-of select="precio"></xsl:value-of> </xsl:for-each>

De este cdigo lo ms interesante es el mantenimiento del rbol Xpath entre las plantillas y bucles for-each, hecho que nos ha permitido simplificar una bsqueda relativa de las lineas como la que esta:
<xsl:for-each select="lineas/linea">

El cdigo completo de nuestra hoja XSLT con parmetros, variables y bucles dobles queda:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 8, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:param name="numero"></xsl:param> <xsl:template match="/"> <html> <body> <xsl:for-each select="facturacion/facturas/factura[numero=$numero]"> Numero: <xsl:value-of select="numero"></xsl:value-of> Nif: <xsl:value-of select="nif"></xsl:value-of> <xsl:variable name="nif" select="nif"></xsl:variable> <xsl:for-each select="/facturacion/clientes/cliente[nif=$nif]"> Nombre: <xsl:value-of select="nombre"></xsl:value-of> Direccion: <xsl:value-of select="direccion"></xsl:value-of> Poblacion: <xsl:value-of select="poblacion"></xsl:value-of>
EnriqueMoraMoral.Pag: 14/74

Unidad10.XSLT.

Telefono: <xsl:value-of select="poblacion"></xsl:value-of> </xsl:for-each> Fecha: <xsl:value-of select="fecha"></xsl:value-of> <xsl:for-each select="lineas/linea"> <br/> Descripcion: <xsl:value-of select="descripcion"></xsl:value-of> Unidades: <xsl:value-of select="unidades"></xsl:value-of> Precio: <xsl:value-of select="precio"></xsl:value-of> </xsl:for-each> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

<xsl:attribute> y <xsl:element> El elemento <xsl:attribute> y <xsl:element> puede ser empleado para definir atributos y elementos en un XML a ser transformado mediante un Stylesheet, esto se puede usar cuando deseamos conseguir un nuevo documento XML a partir de otro: Vamos a obtener un documento XML de los clientes de facturacin donde nif se comporta como atributo en clientes. Para ello, se puede disear la siguiente hoja de estilos clientesXML.xsl:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 9, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <clientes> <xsl:for-each select="facturacion/clientes/cliente"> <cliente> <xsl:attribute name="nif"> <xsl:value-of select="nif"/> </xsl:attribute> <nombre> <xsl:value-of select="nombre"></xsl:value-of> </nombre> </cliente> </xsl:for-each> </clientes> </xsl:template> </xsl:stylesheet>

Dando como resultado el siguiente documento XML:


<?xml version="1.0" encoding="UTF-8"?> <clientes> <cliente nif="nif1">

EnriqueMoraMoral.Pag: 15/74

Unidad10.XSLT.

<nombre>nombre1</nombre> </cliente> <cliente nif="nif2"> <nombre>nombre2</nombre> </cliente> <cliente nif="nif3"> <nombre>nombre2</nombre> </cliente> <cliente nif="nif4"> <nombre>nombre4</nombre> </cliente>

</clientes> El uso del elemento atributo es bastante ms sutil, se puede usar para generar etiquetas o nodo cuyo nombre sea el contenido de una de otra etiqueta o de un atributo. Sobre el ejemplo anterior, vamos a definir una etiqueta con la poblacin del cliente y de contenido Villa de abolengo, para ello se modifica la hoja de estilos hasta obtener el siguiente diseo:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 9, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <clientes> <xsl:for-each select="facturacion/clientes/cliente"> <cliente> <xsl:attribute name="nif"> <xsl:value-of select="nif"/> </xsl:attribute> <nombre> <xsl:value-of select="nombre"></xsl:value-of> </nombre> <xsl:element name="{poblacion}"> Villa de abolento </xsl:element> </cliente> </xsl:for-each> </clientes> </xsl:template> </xsl:stylesheet>

Dando como resultado:


<?xml version="1.0" encoding="UTF-8"?> <clientes> <cliente nif="nif1"> <nombre>nombre1</nombre> <pueblo1>Villa de abolengo</pueblo1> </cliente> <cliente nif="nif2">
EnriqueMoraMoral.Pag: 16/74

Unidad10.XSLT.

<nombre>nombre2</nombre> <pueblo1>Villa de abolengo</pueblo1> </cliente> <cliente nif="nif3"> <nombre>nombre2</nombre> <pueblo2>Villa de abolengo</pueblo2> </cliente> <cliente nif="nif4"> <nombre>nombre4</nombre> <pueblo2>Villa de abolengo</pueblo2> </cliente> </clientes>

Se ha introducido un nuevo operador en esta hoja de estilos XSLT que es el operador {} que fuerza a una evaluacin de un elemento dentro de una cadena de caracteres, exactamente en la siguiente linea de cdigo:
<xsl:element name="{poblacion}">

<xsl:number>
<xsl:number> es una etiqueta que lleva un contador de los elementos que se van mostrando. Se puede utilizar en una tabla para numerar las filas. Por ejemplo, a partir de la hojas XSLT mostrarClientes.xsl donde eliminamos el prametro nif, se puede aadir una nueva columna a la tabla para mostrar un numero de orden de los clientes, con el siguiente cdigo:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 8, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:param name="nif"></xsl:param> <xsl:template match="/"> <html> <body> <table> <xsl:for-each select="facturacion/clientes/cliente"> <tr> <td> <xsl:number format="1"></xsl:number> </td> <td> <xsl:value-of select="nif"></xsl:value-of></td> <td> <xsl:value-of select="nombre"></xsl:value-of></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>

La aplicacin de esta hoja de estilos muestra el siguiente resultado:


EnriqueMoraMoral.Pag: 17/74

Unidad10.XSLT.

El mecanismo interno de <xsl:number> despliega en cada iteracin del template su nmero de ciclo, adems, mediante el atributo format="I" se indica que la enumeracin debe ser realizada con nmeros romanos (I,II,III,IV,V...), como alternativa a nmeros romanos pueden ser empleadas las variantes: format="1"(Nmeros), format="a" (Letras minsculas), format="A" (Letras maysculas) o format="i" (Nmeros romanos sin capitalizar).

<xsl:comment> y <xsl:text>
Otra situacin que suele presentarse en el diseo de un "XSL Stylesheet" es la inclusin de comentarios o bloques de texto en el contenido generado por el "XSL Stylesheet", para estas circunstancias se emplean los elementos <xsl:comment> y <xsl:text> respectivamente.
<xsl:template match="/"> <xsl:comment> No edite este documento, fue generado automticamente por un "XSL Stylesheet" </xsl:comment> </xsl:template>

El bloque anterior generara el siguiente contenido al ser procesado dentro de un "XSL Stylesheet".
<!-No edite este documento, fue generado automticamente por un "XSL Stylesheet" -->

El siguiente template que incluye <xsl:text> simplemente procesa el contenido como texto simple:
<xsl:template match="Nombre"> <xsl:text> Nombre de usuario </xsl:text> </xsl:template>

Una variacin del elemento <xsl:text> es que ste incluya el atributo disable-outputescaping="yes", mediante este atributo se indica que todo elemento reservado en XML no sea procesado como un carcter de escape, esto es, los elementos como < y > son procesados por el "XSL Stylesheet" sin conversin alguna, si este atributo es omitido en <xsl:text> dichos caracteres seran convertidos a &lt y &gt respectivamente como indica la especificacin XML. <xsl:copy> Otro elemento empleado en el diseo de "XSL Stylesheets" es <xsl:copy> que permite copiar automticamente el valor definido dentro de la salida. Por ejemplo, para obtener los datos completo de los clientes de pueblo1 puedo definir: Muestra ciertos problemas si no se procesa junto con
Enr iqueMoraMoral.Pag: 18/74

Unidad10.XSLT.

plantillas. Para pruebas ms normales y usndose dentro for-each se recomienda la variante <xsl:copy-of>. Para extraer un documento XML nicamente con los clientes de nuestro fichero XML clientes se podra definir el siguiente cdigo:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 9, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <xsl:copy-of select="facturacion/clientes" /> </xsl:template> </xsl:stylesheet>

El resultado es un fichero XML con la siguiente estructura:


<?xml version="1.0" encoding="UTF-8"?><clientes> <cliente> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion>calle1</direccion> <poblacion>pueblo1</poblacion> <telefono>111-111-111</telefono> </cliente> <cliente> <nif>nif2</nif> <nombre>nombre2</nombre> <direccion>calle2</direccion> <poblacion>pueblo1</poblacion> <telefono>222-222-222</telefono> </cliente> <cliente> <nif>nif3</nif> <nombre>nombre2</nombre> <direccion>calle3</direccion> <poblacion>pueblo2</poblacion> <telefono>333-333-333</telefono> </cliente> <cliente> <nif>nif4</nif> <nombre>nombre4</nombre> <direccion>calle4</direccion> <poblacion>pueblo2</poblacion> <telefono>444-444-444</telefono> </cliente> </clientes>

Podemos aadir parametros a la hoja anterior para seleccionar un determinado cliente de


Enr iqueMoraMoral.Pag: 19/74

Unidad10.XSLT.

forma aleatoria. Bastara como modificar aadir el parmetro al escenario de transformacin:

y ajustar el cdigo hasta obtener el siguiente diseo:


<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 9, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:param name="p1"></xsl:param> <xsl:template match="/"> <xsl:copy-of select="facturacion/clientes/cliente[position() = $p1]" /> </xsl:template> </xsl:stylesheet>

Obteniendo como resultado, segn los valores fijados en tercer cliente del fichero que en nuestro caso es:
<?xml version="1.0" encoding="UTF-8"?><cliente> <nif>nif3</nif> <nombre>nombre2</nombre> <direccion>calle3</direccion> <poblacion>pueblo2</poblacion> <telefono>333-333-333</telefono> </cliente>

3. Operadores y funciones en XSL.


Los operadores y funciones XSL son los mismos que los vistos para el entorno Xpath. Siguiendo las recomendaciones W3C se van a tratar de forma particular algunas funciones especificas o de ms uso dentro de XSL
EnriqueMoraMoral.Pag: 20/74

Unidad10.XSLT.

current()
Esta funcin devuelve el nodo actual. <xsl:value-of select="current()"/> puede sustituirse por la siguiente expresin xpath: <xsl:value-of select="."/> Ejemplo de transformacin que nos devuelva los datos del cliente en modo texto, debido al efecto de value-of:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 9, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:param name="p1"></xsl:param> <xsl:template match="/"> <xsl:for-each select="facturacion/clientes"> <xsl:value-of select="."></xsl:value-of> </xsl:for-each> </xsl:template> </xsl:stylesheet>

Para devolver los nodos completos es nesario usar <xsl:copy-of> dentro del siguiente cdigo:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 9, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:param name="p1"></xsl:param> <xsl:template match="/"> <xsl:for-each select="facturacion/clientes"> <xsl:copy-of select="current()" /> </xsl:for-each> </xsl:template> </xsl:stylesheet>

document()
Enr iqueMoraMoral.Pag: 21/74

Unidad10.XSLT.

Esta funcin presenta un comportamiento semejante al visto en en Xquery. Se puede acceder a cualquier elemento externo contenido en un fichero. Incluso se puede definir variables con document() para acceder a elementos externos. Por ejemplo, usaremos document() para mostrar los datos de las facturas junto con los datos de sus clientes:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 9, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:param name="p1"></xsl:param> <xsl:template match="/"> <xsl:for-each select="facturacion/facturas/factura"> <xsl:value-of select="numero"/> <xsl:value-of select="nif"/> <xsl:variable name="nif" select="nif"/> <xsl:variable name="cliente" select="document('facturacion.xml')/facturacion/clientes/cliente[nif=$nif]"/> <xsl:value-of select="$cliente/nombre"/> <xsl:value-of select="$cliente/direccion"/> <xsl:value-of select="$cliente/poblacion"/> </xsl:for-each> </xsl:template>

Obsrvese, la declaracin de las variables como elementos auxiliares para almacenar el nif y el uso de la funcin document() en la siguiente declaracin de variables:
<xsl:variable name="cliente" select="document('facturacion.xml')/facturacion/clientes/cliente[nif=$nif]"/>

En este caso no hubiera sido necesario el uso de document(). Se podra haber buscado una expresin Xpath que de forma directa acceda al elemento. En este caso:
<xsl:variable name="cliente" select="../../../facturacion/clientes/cliente[nif=$nif]"/>

En el caso de que el acceso a un elemento sea del mismo fichero, con un poco de suerte podemos ajustar la ruta Xpath. No queda otro remedio de uso de document() cuando tenemos que acceder a otro documento externo. Con este comportamiento XSL se comporta como las consultas en Xquery aumentando bastante la potencia expresiva del lenguaje.

element-available()
La funcin devuelve un valor de tipo Boolean. Tiene como parmetro un string que en principio contiene un elemento o sentencia del lenguaje. Esta funcin slo se usa para comprobar que elementos o sentencias pertenecen al lenguaje XSLT. La lista de elementos(sentencias) disponibles son:

xsl:apply-imports
EnriqueMoraMoral.Pag: 22/74

Unidad10.XSLT.

xsl:apply-templates xsl:attributes xsl:call-template xsl:choose xsl:comment xsl:copy xsl:copy-of xsl:element xsl:fallback xsl:for-each xsl:if xsl:message xsl:number xsl:processing instruction xsl:text xsl:value-of xsl:variable

Ejemplo:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <xsl:choose> <xsl:when test="element-available('xsl:comment')"> <p>xsl:comment esta soportado.</p> </xsl:when> <xsl:otherwise> <p>xsl:comment no esta soportado.</p> </xsl:otherwise> </xsl:choose> <xsl:choose> <xsl:when test="element-available('xsl:delete')"> <p>xsl:delete esta soportado.</p> </xsl:when> <xsl:otherwise> <p>xsl:delete no esta soportado.</p> </xsl:otherwise> </xsl:choose> </body> </html> </xsl:template>
EnriqueMoraMoral.Pag: 23/74

Unidad10.XSLT.

Dando como resultado el siguiente fichero HTML:


<html> <body> <p>xsl:comment esta soportado.</p> <p>xsl:delete no esta soportado.</p> </body> </html>

format-number()
Esta funcin transforma numeros en cadenas de caracteres aplicndole un formato bsico de conversin. Sintaxis: string format-number(number,format,[decimalformat]) Parmetros Parameter number format Description Es el valor numrico a formatear Especifica el modelo o plantilla por el que voy a convertir el numero a String:

0 (Dgito, se completa con ceros cuando falta) # (Dgito) . (punto decimal, ejemplo: ###.##) , (separador de miles, ejemplo: ###,###.##) % (Muestra el tanto por ciento, al final del numero. Ejemplo: ##%) ; (Separador de Formatos. El primer formato se aplica a los numeros positivos y el segundo formato a los numeros negativos.)

decimalformat Opcional Ejemplo:


<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <p> Numero: <xsl:value-of select="format-number(234,'####.##')"/></p> <p> Numero: <xsl:value-of select="format-number(234,'000.00')"/></p> <p> Numero: <xsl:value-of select="format-number(23,'##.##')"/></p> <p> Numero: <xsl:value-of select="format-number(23,'00.00')"/></p>
Enr iqueMoraMoral.Pag: 24/74

Unidad10.XSLT.

<p> Numero: <xsl:value-of select="format-number(234.2,'####.##;[###.##]')"/></p> <p> Numero: <xsl:value-of select="format-number(234.2,'000.00;[000.00]')"/></p> <p> Numero: <xsl:value-of select="format-number(-234.2,'####.##;[###.##]')"/></p> <p> Numero: <xsl:value-of select="format-number(-234.2,'0000.00;[000.00]')"/></p> </body> </html> </xsl:template> </xsl:stylesheet>

Resultado:
<html> <body> <p> Numero: 234</p> <p> Numero: 234.00</p> <p> Numero: 23</p> <p> Numero: 23.00</p> <p> Numero: 234.2</p> <p> Numero: 234.20</p> <p> Numero: [234.2]</p> <p> Numero: [234.20]</p> </body> </html>

function-available()
Parecida a la funcin elemente-avaible() pero que comprueba si existe o no una determinada funcin. El valor que devuelve es verdadero o falso (true, false) y tiene como parmetro una cadena de caracteres o String. Ejemplo:
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <xsl:choose> <xsl:when test="function-available('sum')"> <p>sum() esta soportada.</p> </xsl:when> <xsl:otherwise> <p>sum() is no esta soportada</p> </xsl:otherwise> </xsl:choose> <xsl:choose> <xsl:when test="function-available('current')"> <p>current() esta soportada.</p> </xsl:when> <xsl:otherwise> <p>current() no esta soportada.</p> </xsl:otherwise> </xsl:choose> <xsl:choose> <xsl:when test="function-available('patata')"> <p>patata() esta soportada.</p> </xsl:when> <xsl:otherwise>
EnriqueMoraMoral.Pag: 25/74

Unidad10.XSLT.

<p>patata() no esta soportada.</p> </xsl:otherwise> </xsl:choose> </body> </html> </xsl:template> </xsl:stylesheet>

Resultado:
<html> <body> <p>sum() esta soportada.</p> <p>current() esta soportada.</p> <p>patata() no esta soportada.</p> </body> </html>

generate-id()
Esta funcin genera un identificador nico por cada nodo que encuentre. Este identificador se puede considerar pseudo aleatorio. Por ejemplo, generate-id() aplicado a los clientes del fichero facturacin:
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <xsl:for-each select="facturacion/clientes/cliente"> <p> <xsl:value-of select="generate-id(current())"/></p> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

Que nos devuelve la siguiente pgina WEB:


html> <body> <p>d1e7</p> <p>d1e25</p> <p>d1e43</p> <p>d1e61</p> </body> </html>

Un ejemplo ms complejo de esta funcin puede ser su aplicacin dentro de una pgina HTML ms compleja donde se utiliza esta funcin para aplicarlos en el atributo id dentro de etiquetas HTML:
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
EnriqueMoraMoral.Pag: 26/74

Unidad10.XSLT.

<xsl:template match="/"> <html> <body> <h3>Indice de Clientes:</h3> <ul> <xsl:for-each select="facturacion/clientes/cliente"> <li> <a href="#{generate-id(current())}"> <xsl:value-of select="nif" /></a> </li> </xsl:for-each> </ul> <h3>Datos de Clientes:</h3> <xsl:for-each select="facturacion/clientes/cliente"> <div id="{generate-id(current())}"> <h3> Nif: <xsl:value-of select="nif" /> </h3> <p> Nombre: <xsl:value-of select="nombre" /> </p> <p> Direccin: <xsl:value-of select="direccion" /> </p> <p> Poblacin: <xsl:value-of select="poblacion" /> </p> </div> </xsl:for-each> </body> </html> </xsl:template>

Para realizar el ejercicio se han realizado dos pasadas sobre los mismos elementos. En la primera pasada se ha construido el ndice y en la segunda pasada se han introducido los datos de cada cliente. Cuando se realiza la transformacin se genera el siguiente cdigo HTML:
<html> <body> <h3>Indice de Clientes:</h3> <ul> <li><a href="#d1e7">nif1</a></li> <li><a href="#d1e25">nif2</a></li> <li><a href="#d1e43">nif3</a></li> <li><a href="#d1e61">nif4</a></li> </ul> <h3>Datos de Clientes:</h3> <div id="d1e7"> <h3> Nif: nif1</h3> <p> Nombre: nombre1</p> <p> Direccin: calle1</p> <p> Poblacin: pueblo1</p> </div> <div id="d1e25"> <h3> Nif: nif2</h3> <p> Nombre: nombre2</p> <p> Direccin: calle2</p> <p> Poblacin: pueblo1</p> </div> <div id="d1e43"> <h3> Nif: nif3</h3> <p> Nombre: nombre2</p>
EnriqueMoraMoral.Pag: 27/74

Unidad10.XSLT.

<p> Direccin: calle3</p> <p> Poblacin: pueblo2</p> </div> <div id="d1e61"> <h3> Nif: nif4</h3> <p> Nombre: nombre4</p> <p> Direccin: calle4</p> <p> Poblacin: pueblo2</p> </div> </body> </html>

key()
La funcin key() que devuelve un conjunto de nodos, al estilo de las expresiones Xpath que se utilizan sobre la plantilla base. Se utiliza junto con la sentencia o elemento <xsl:key>. El elemento <xsl:key> prepara un filtro o seleccin de un grupo de nodos en funcin de una condicin de igualdad. Por ejemplo, para seleccionar los clientes de una determinada poblacin partimos de la construccin del objeto key con la siguiente estructura:
<xsl:key name="clnPbl" match="facturacion/clientes/cliente" use="poblacion" />

Donde:

clnPbl: es el nombre del objeto key match: es el patrn de bsqueda base Xpath use: es el nodo o elemento interno que se va a comparar.

Una vez construido el objeto KEY podemos utilizarlo con la funcin key() dentro de un <xls:foreach> para obtener los clientes de una determinada poblacin:
<xsl:for-each select="key('clnPbl', 'pueblo1')">

La funcin key() tiene dos parmetros el objeto key a evaluar y el valor por el cual filtro los nodos. El siguiente ejemplo crea un listado con los clientes de una determinada poblacin, en este caso pueblo1:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:key name="clnPbl" match="facturacion/clientes/cliente" use="poblacion" /> <xsl:template match="/"> <html>
EnriqueMoraMoral.Pag: 28/74

Unidad10.XSLT.

<body> <xsl:for-each select="key('clnPbl', 'pueblo1')"> <p> Nif: <xsl:value-of select="nif" /> <br /> Nombre: <xsl:value-of select="nombre" /> <br /> Direccion: <xsl:value-of select="direccion" /> </p> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

system-property()
Esta funcin devuelve una serie de valores relacionados con el procesador XSLT. Normalmente son las conocidas variables del sistema. Los valores que se pueden estudiar son:

xsl:version Versin de XSLT xsl:vendor Fabricante del procesador o herramienta XSLT xsl:vendor-url - La URL del fabricante

Por ejemplo, de estas funciones se pude ejecutar el siguiente cdigo en Oxygen:


<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <div> <p>Version: <xsl:value-of select="system-property('xsl:version')" /> </p> <p> Vendor: <xsl:value-of select="system-property('xsl:vendor')" /> </p> <p> Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" /> </p> </div> </body> </html> </xsl:template>

Que devuelve el siguiente cdigo HTML:


<html> <body> <div> <p>Version: 2.0 </p> <p> Vendor: SAXON 9.3.0.5 from Saxonica
EnriqueMoraMoral.Pag: 29/74

Unidad10.XSLT.

</p> <p> Vendor URL: http://www.saxonica.com/ </p> </div> </body> </html>

unparsed-entity-uri() Esta funcin se utiliza para obtener la URI de una entidad que se defina en los DTD como una constante que se define para ser usada dentro del documento. Si el DTD del documento XML contiene por ejemplo la siguiente linea: <!ENTITY pic SYSTEM "http://www.w3schools.com/picture.jpg" NDATA JPEG> la siguiente expresin: unparsed-entity-uri('pic') devolver la URI del fichero "picture.jpg".

4. Elementos o sentencias XSL. <xsl:attribute>


Aade atributos a un nodo que se acaba de construir. Sintaxis: <xsl:attribute name="nombreDelAtributo" namespace="uri"> <!-- Content:template --> </xsl:attribute> Atributos Atributo name namespace Valor Descripcin nombreDelAtributo Nombre que se le asigna al atributo. URI Opcional. Define el espacio de nombres URI para el atributo.

Ejemplo 1: Se puede cambiar el elmento nif del cliente como un atributo. Para ello, implementamos el siguiente cdigo:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <clientes>
EnriqueMoraMoral.Pag: 30/74

Unidad10.XSLT.

<xsl:for-each select="facturacion/clientes/cliente"> <cliente> <xsl:attribute name="nif"> <xsl:value-of select="nif"></xsl:value-of> </xsl:attribute> <nombre> <xsl:value-of select="nombre"/></nombre> <direccion><xsl:value-of select="direccion"/></direccion> <poblacion><xsl:value-of select="poblacion"/></poblacion> </cliente> </xsl:for-each> </clientes> </xsl:template> </xsl:stylesheet>

<xsl:attribute-set>
Define un conjunto de atributos que puede ser usado por cualquier elemento. Sintaxis: <xsl:attribute-set name="nombre" use-attribute-sets="listaDeNombres"> <!-- Content:xsl:attribute* --> </xsl:attribute-set> Atributos Descricin Es el nombre de nuestro grupo de atributos Opcional. Una lista de nombres de grupos de atributos separados por espacio en blanco cuyos atributos se incluyen en este grupo. Ejemplo 1: Grupo de atributos denominado grupo1 con tres atributos que se aade a los distintos elementos de cliente.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:attribute-set name="grupo1"> <xsl:attribute name="at1">valor1</xsl:attribute> <xsl:attribute name="at2">valor2</xsl:attribute> <xsl:attribute name="at3">valor3</xsl:attribute> </xsl:attribute-set> <xsl:template match="/">
Enr iqueMoraMoral.Pag: 31/74

Atributo name use-attribute-sets

Valor nombre listaDeNombres

Unidad10.XSLT.

<clientes> <xsl:for-each select="facturacion/clientes/cliente"> <cliente xsl:use-attribute-sets="grupo1"> <xsl:attribute name="nif"> <xsl:value-of select="nif"></xsl:value-of> </xsl:attribute> <nombre xsl:use-attribute-sets="grupo1"> <xsl:value-of select="nombre"/></nombre> <direccion xsl:use-attribute-sets="grupo1"><xsl:value-of select="direccion"/></direccion> <poblacion xsl:use-attribute-sets="grupo1"><xsl:value-of select="poblacion"/></poblacion> </cliente> </xsl:for-each> </clientes> </xsl:template> </xsl:stylesheet>

En esta Hoja se puede observar la declaracin del grupo de atributos:


<xsl:attribute-set name="grupo1"> <xsl:attribute name="at1">valor1</xsl:attribute> <xsl:attribute name="at2">valor2</xsl:attribute> <xsl:attribute name="at3">valor3</xsl:attribute> </xsl:attribute-set

Y su posterior uso dentro un elemento:


<xsl:if> element contains a template that will be applied only if a specified condition is true.

<xsl:choose> y <xsl:if>
Estos dos elementos nos permite evaluar operaciones condicionales y realizar determinadas operaciones en funcin de que se cumplan o no determinadas condiciones. Sintaxis: <xsl:if test="expression"> <!-- Content: template --> </xsl:if> <xsl:choose> <!-- Content:(xsl:when+,xsl:otherwise?) --> </xsl:choose> Ejemplo 1: Utilizando xsl:if poner un mensaje en aquellas facturas que sean impares.
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet">

EnriqueMoraMoral.Pag: 32/74

Unidad10.XSLT.

<xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <xsl:for-each select="facturacion/facturas/factura"> <p> Numero: <xsl:value-of select="numero"/></p> <xsl:if test="numero mod 2 = 0"> <p> La factura es par</p> </xsl:if> <xsl:if test="numero mod 2 = 1"> <p> La factura es impar</p> </xsl:if> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

Ejemplo 2: El cdigo anterior no es muy correcto al no disponer de la clausula else. Se puede sustituir por choose que nos permite elegir entre varias alternativas:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <xsl:for-each select="facturacion/facturas/factura"> <p> Numero: <xsl:value-of select="numero"/></p> <xsl:choose> <xsl:when test="numero mod 2 = 0" > <p> La factura es par</p> </xsl:when> <xsl:when test="numero mod 2 = 1"> <p> La factura es impar</p> </xsl:when> <xsl:otherwise> <p> Error en las operaciones de modulo</p> </xsl:otherwise> </xsl:choose> </xsl:for-each> </body>
EnriqueMoraMoral.Pag: 33/74

Unidad10.XSLT.

</html> </xsl:template> </xsl:stylesheet>

<xsl:comment>
Se utiliza para introducir comentarios. Presenta la siguiente sintaxis: <xsl:comment> <!-- Content:template --> </xsl:comment>

<xsl:decimal-format>
Permite definir un formato numerico generico que se utilizar con posterioridad dentro de la funcin format-numer(numero, plantilla,formato). Este formato especifico que complementa a esta funcin es el que se declara con este elemento. Presenta la siguiente sintaxis: <xsl:decimal-format name="name" decimal-separator="char" grouping-separator="char" infinity="string" minus-sign="char" NaN="string" percent="char" per-mille="char" zero-digit="char" digit="char" pattern-separator="char"/> Todos estos parmetros son opcionales, el parmetro que ms nos puede interesar es decimalseparator que puede cambiar el punto decimal por nuestra coma decimal, junto con el per-mille. Si se construye un formato decimal ajustado al llamado euro se puede usar al convertir valores numricos dentro de la funcin format-number: <xsl:value-of select="format-number(valorNumerico, '#,###.00', 'euro')"/> <xsl:element> Crea un nuevo elemento. La ventaja que presenta con respecto al uso de elementos escritos de forma directa es que los nombres de los elementos se pueden extraer de los datos almacenados en documentos XML funcionando como un generador de cdigo variable y automtico. Presenta la siguiente sintaxis: <xsl:element name="name" namespace="URI" use-attribute-sets="litaDeNombres">
Enr iqueMoraMoral.Pag: 34/74

Unidad10.XSLT.

<!-- Contenido (se pueden aadir atributos --> </xsl:element>

<xsl:fallback>
Este elemento funciona como un capturador de errores o excepciones, siendo parecido a las excepciones de Java. Cuando se produce un error en el elemento que lo contiene se ejecuta el cdigo de su interior. Ejemplo 1: Aadido a un ejemplo anterior:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <xsl:patata> <xsl:fallback> Error en patata </xsl:fallback> </xsl:patata> <xsl:for-each select="facturacion/facturas/factura"> <xsl:fallback> Error en for-eac </xsl:fallback> <p> Numero: <xsl:value-of select="numero"/></p> <xsl:choose> <xsl:when test="numero mod 2 = 0" > <p> La factura es par</p> </xsl:when> <xsl:when test="numero mod 2 = 1"> <p> La factura es impar</p> </xsl:when> <xsl:otherwise> <p> Error en las operaciones de modulo</p> </xsl:otherwise> </xsl:choose> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

En este caso se ejecuta fallback asociado a patata que no existe y no se produce el de for-each que es un sentencia correcta.
EnriqueMoraMoral.Pag: 35/74

Unidad10.XSLT.

<xsl:import> <xsl:include>
Import e include tienen la misma funcin, incluyen en nuestra Hoja XSLT cdigo de otro fichero. La diferencia entre import e include. Consiste en la diferente prioridad de los elementos que se importan e incluyen. Cuando importo un fichero estos elementos tienen menor prioridad que los definidos dentro del fichero. Cuando se incluye un fichero los elementos que si incluyen tienen la misma prioridad que los elementos del ficheros como si estuviesen all escritos. Sintasis: <xsl:import href="URI"/> <xsl:include href="URI"/>

<xsl:message>
Se utiliza para escribir un mensaje en la salida. Se usa normalmente para el aviso de errores y finalizar la transformacin XSLT. Sintaxis <xsl:message terminate="yes|no"> <!-- Contenido --> </xsl:message> Si fijo terminate a yes finalizo la ejecucin de la transformacin, si le asigno el valor no nicamente muestra el mensaje. Ejemplo: Al ejecutarse el siguiente cdigo:
<xsl:message terminate="yes"> Prueba del elemento message. </xsl:message>

Se finaliza la ejecucin de la transformacin y en la parte inferior de Oxygen aparece el siguiente contenido en la ventana de mensajes:

Adems en la ventana Errors:

La pgina Web o salida de esta transformacin no se muestra en Oxygen.

<xsl:number>
EnriqueMoraMoral.Pag: 36/74

Unidad10.XSLT.

Es utilizado para formatear la posicin de un elemento generando listas ordenadas por nmeros, letras, etc... mezclado con la funcin position() que devuelve la posicin del nodo. Tambin se usa par formatear nmeros. Sintaxis: <xsl:number count="expression" level="single|multiple|any" from="expression" value="expression" format="formatstring" lang="languagecode" letter-value="alphabetic|traditional" grouping-separator="character" grouping-size="number"/> Este elemento se ha visto anteriormente junto con la funcin number.

<xsl:output>
Este elemento en teora sera el primero de nuestra hoja XSLT y contendra a todos los dems. Se usa para definir el resultado o salida de la hoja XSLT que se esta construyendo. Sintaxis: <xsl:output method="xml|html|text|name" version="string" encoding="string" omit-xml-declaration="yes|no" standalone="yes|no" doctype-public="string" doctype-system="string" cdata-section-elements="namelist" indent="yes|no" media-type="string"/> De esta coleccin de atributos en ms importante es el primero: method="xml|html|text|name" donde se define el tipo de documento que genera la hojas XSLT. <xsl:processing-instruction> Genera instrucciones del tipo:
<?xml version="1.0" encoding="UTF-8"?>

Para ello introduzco al comienzo de la Hoja XSLT el cdigo: <xsl:processing-instruction name="xml-stylesheet"> href="style.css" type="text/css" </xsl:processing-instruction> <xsl:sort>
EnriqueMoraMoral.Pag: 37/74

Unidad10.XSLT.

Sort se usa normalmente con for-each para poder ordenar los elementos devueltos segn un elemento o atributo. Sintaxis: <xsl:sort select="expression" lang="language-code" data-type="text|number|qname" order="ascending|descending" case-order="upper-first|lower-first"/> De sus atributos aparte de la expresin por la cual se ordena que se escoge mediante el atributo select, interesa:

data-type: tipo de orden que se aplica. Order: ascending y descending case-order: el tratamiento entres maysculas y minsculas.

Ejemplo: para extraer los clientes de facturacin por orden descendiente de nif:
?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <xsl:for-each select="facturacion/clientes/cliente"> <xsl:sort select="nif" order="descending"/> <p> Nif: <xsl:value-of select="nif"/></p> <p> Nombre: <xsl:value-of select="nombre"/></p> <p> Direccin: <xsl:value-of select="direccion"/></p> <p> Poblacion: <xsl:value-of select="poblacion"/></p> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

En este caso es preciso observar el uso de sort como elemento que vaco y su funcionamiento junto con for-each:
<xsl:for-each select="facturacion/clientes/cliente"> <xsl:sort select="nif" order="descending"/>

<xsl:value-of>

EnriqueMoraMoral.Pag: 38/74

Unidad10.XSLT.

Se ha visto anteriormente para recuperar valores de elementos mediante sub-expresiones Xpath. Presenta la siguiente sintaxis: <xsl:value-of select="expression" disable-output-escaping="yes|no" /> El atributo disable-output-escaping que por defecto esta a yes dice que el carcter especial < aparezca tal cual dentro del valor devuelto. Con el valor no sustituye el carcter > por la constante asociada &lt;. <xsl:preserve-space> y <xsl:strip-space> Preserve-space dice que elementos(del sub-arbol Xpath) que construyo en la hojas XSLT mantienen los espacios en blanco que aparecen y strip-space que lista de elementos eliminan los espacios en blanco que se introducen. Sintaxis: <xsl:preserve-space elements="list-of-element-names"/> <xsl:strip-space elements="list-of-element-names"/> Ejemplo:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> Apr 14, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:strip-space elements="nif nombre"/> <xsl:preserve-space elements="direccion poblacion"/> <xsl:template match="/"> <html> <body> <xsl:for-each select="facturacion/clientes/cliente"> <p><xsl:value-of select="nif"/></p> <p><xsl:value-of select="nombre"/></p> <p><xsl:value-of select="direccion"/></p> <p><xsl:value-of select="poblacion"/></p> </xsl:for-each> </body></html> </xsl:template> </xsl:stylesheet>

Aunque no se aprecia diferencia en el comportamiento los distintos elementos Xpath.

5. Las plantillas.
Las plantillas permiten recorrer el rbol Xpath de nuestro documento XML rama a rama. Y
EnriqueMoraMoral.Pag: 39/74

Unidad10.XSLT.

lanzar automticamente su ejecucin o como en el siguiente ejemplo elemento a elemento. Se recomienda lanzar la plantilla elemento a elemento como la siguiente hoja XSLT que obtiene un fichero XML con los nombres de los clientes:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <listado> <xsl:apply-templates select="facturacion"></xsl:apply-templates> </listado> </xsl:template> <xsl:template match="facturacion" name="facturacion"> <xsl:apply-templates select="clientes"></xsl:apply-templates> </xsl:template> <xsl:template match="clientes" name="clientes"> <nombres> <xsl:apply-templates select="cliente"></xsl:apply-templates> </nombres> </xsl:template> <xsl:template match="cliente" name="cliente"> <nombre> <xsl:value-of select="nombre"></xsl:value-of> </nombre> </xsl:template>

La ventaja que tiene sobre el <for-each> es que los cdigos que se generan no estn anidados y cada una de las plantillas definida es independiente de las otras y puede utilizar las plantillas hijas como cdigo de funciones o procedimientos que se declaran independientemente. El cdigo al igual, que con for-each, comienza con:
<xsl:template match="/"> </xsl:template>

Que en este caso comienza con el elemento raz del rbol Xpath. Dentro de esta declaracin de platilla se puede introducir cdigo relacionado con el inicio del documento. Por ejemplo, para el cdigo HTML se puede introducir <html> <head>...... <head> <body> .... </body> <html>. Dentro de <body>, normalmente en el <head> tambin, aplicaremos las plantillas de los elemtos hijos en este caso facturacin con:
<xsl:apply-templates select="facturacion"></xsl:apply-templates>

Incluso sera valido con, que aplica todas las plantillas de elementos hijos del nodo actual:
<xsl:apply-templates></xsl:apply-templates>

Pero es mejor la primera solucin porque podemos abrir uno de los posibles hijos. Aunque en este caso y como elemento inicial slo hay uno. La bajada a partes inferiores del rbol Xpath se realiza de forma semejante. Por ejemplo, en facturacion podemos acceder a las plantillas de clientes y facturas en este caso slo nos interesa clientes y la aplicamos explcitamente.
<xsl:template match="facturacion" name="facturacion"> <xsl:apply-templates select="clientes"></xsl:apply-templates>
EnriqueMoraMoral.Pag: 40/74

Unidad10.XSLT.

</xsl:template>

Para poder aplicar la clausula select en xsl:apply-templates:


<xsl:apply-templates select="clientes"></xsl:apply-templates>

Es necesario declarar la plantilla con el atributo name, que es donde se le asigna el nombre. En este caso clientes que se aplica desde facturacion, aunque ignora este atributo, se recomienda

denominarla igual que el elemento del rbol Xpath, el nombre se utiliza con el elemento call-template, se utiliza para manejar plantillas que no tienen relacin con el rbol XPath:
xsl:template match="clientes" name="clientes"> <nombres> <xsl:apply-templates select="cliente"></xsl:apply-templates> </nombres> </xsl:template>

Aply-imports
Aplica las platillas importadas de una Hoja XSLT introducida con el elemento impor. Call-template: Aplica las plantillas por nombre. Se puede usar para separar plantillas que no tienen que ver con el rbol Xpath:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:template match="/"> <listado> <xsl:call-template name="factu"></xsl:call-template> </listado> </xsl:template> <xsl:template name="factu"> <factura> factura de prueba</factura> </xsl:template> </xsl:stylesheet>

With-param
Sobre las las plantillas se pueden declarar parmetros que se ajustan cuando estas se llaman. En el ejemplo anterior, se puede cambiar el texto factura de prueba por un texto parametrizado que se puede cambiar cada vez que se llame a la plantilla. Para ello es necesario usar with-param y param.
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:template match="/"> <listado>

EnriqueMoraMoral.Pag: 41/74

Unidad10.XSLT.

<xsl:call-template name="factu"> <xsl:with-param name="texto" select="'Cambio el texto'" /> </xsl:call-template> </listado> </xsl:template> <xsl:template name="factu"> <xsl:param name="texto" select="'no asignado'"></xsl:param> <factura> <xsl:value-of select="$texto"></xsl:value-of></factura> </xsl:template> </xsl:stylesheet>

Se precisa declarar el parmetro dentro de la plantilla:


<xsl:param name="texto" select="'no asignado'"></xsl:param>

Necesita de un nombre: name="texto" y de un valor por defecto: select="'no asignado'" . Es obligatorio usar comillas simples dentro de las comillas dobles a la hora de asignar un valor al parmetro. Esto aunque parezca un fallo permite de forma directar introducir cdigo de expresiones Xpath y variables XSLT. La asignacin del valor real a utilizar se hace con la misma tcnica en la llamada a la plantilla:
<xsl:call-template name="factu"> <xsl:with-param name="texto" select="'Cambio el texto'" /> </xsl:call-template>

6. Java y XML.
Java y XML se encuentran perfectamente integrados existiendo un gran conjunto de APIs que nos permiten manejar los documentos XML.

Libreria JAXB.
Es una librera de fcil manejo cuando se tiene un conocimiento bsico del manejo de las colecciones en Java. Una vez construidas las clases de apoyo el acceso al fichero XML se realiza mediante objetos ArrayList de Java permitiendo un manejo cmodo y rpido. El principal problema que presenta es a la hora de capturar la estructura del documento y pasarlo de forma correcta a las estructuras Java que lo soportan. Presenta un funcionamiento parecido a DOM al cargar el documento en memoria.

Ejemplo 01.
Como primer ejemplo vamos a intentar crear y luego leer un fichero con el siguiente formato: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <personas> <persona>
EnriqueMoraMoral.Pag: 42/74

Unidad10.XSLT.

<nifcambiado>nif1</nifcambiado> <nombre>nombre1</nombre> <direccion>calle1</direccion> <poblacion>pueblo1</poblacion> <telefono>1111</telefono> </persona> <persona> <nifcambiado>nif2</nifcambiado> <nombre>nombre2</nombre> <direccion>calle2</direccion> <poblacion>pueblo2</poblacion> <telefono>1112</telefono> </persona> <persona> <nifcambiado>nif3</nifcambiado> <nombre>nombre3</nombre> <direccion>calle3</direccion> <poblacion>pueblo3</poblacion> <telefono>1113</telefono> </persona> </personas> El documento presenta una lista de personas. Por ahora, slo vamos a trabajar con elementos descartando atributos. Se ha introducido <nifcambiado> en lugar del valor correcto de nif para mostrar como se puede cambiar el nombre de un elemento entre Java y XML. Partimos de la creacin de una clase Persona.java que nos permite almacenar los datos de una persona en funcin de los campos anteriores:
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; @XmlType(propOrder = { public class Persona { private String private String private String private String private String "nif", "nombre", "direccion", "poblacion", "telefono" }) nif; nombre; direccion; poblacion; telefono;

EnriqueMoraMoral.Pag: 43/74

Unidad10.XSLT.

// Cambia el nombre de un elemento por otro @XmlElement(name = "nifcambiado") public String getNif() { return nif; } public void setNif(String nif) { this.nif = nif; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getDireccion() { return direccion; } public void setDireccion(String direccion) { this.direccion = direccion; } public String getPoblacion() { return poblacion; } public void setPoblacion(String poblacion) { this.poblacion = poblacion; } public String getTelefono() { return telefono; } public void setTelefono(String telefono) { this.telefono = telefono; } }

La clase anterior nicamente tiene los mtodos set/get de cada una de los atributos privados de la clase. Adems de: Las importaciones:
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType;

Para el manejo de las anotaciones que hace la API el uso de las dos anotaciones:
@XmlType(propOrder = { "nif", "nombre", "direccion", "poblacion", "telefono" })

Esta primera anotacin anterior a la clase nos permite establecer el orden de aparicin de los elementos en el documento XML. El orden de acceso posterior se realiza como la clase que es de Java. La ltima anotacin que se ha introducido:
Enr iqueMoraMoral.Pag: 44/74

Unidad10.XSLT.

// Cambia el nombre de un elemento por otro @XmlElement(name = "nifcambiado") public String getNif() { return nif; }

Cambia el nombre por defecto de nif en la etiqueta, igual que el atributo, a nifcambiado. Por ahora, no es de mucha utilidad pero con estructuras ms complejas nos puede facilitar el manejo de los nombre de una forma cmoda. Ya esta definida una persona, ahora es preciso definir la lista de personas. Para ello se utiliza la clase AlmacenPersonas:
import import import import import import java.util.ArrayList; javax.xml.bind.annotation.XmlAccessType; javax.xml.bind.annotation.XmlAccessorType; javax.xml.bind.annotation.XmlElement; javax.xml.bind.annotation.XmlRootElement; javax.xml.bind.annotation.XmlType;

@XmlAccessorType( XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "listaPersona" }) @XmlRootElement(name = "personas") public class AlmacenPersonas { @XmlElement(name = "persona") private ArrayList<Persona> listaPersona; public ArrayList<Persona> getListaPersona() { return listaPersona; } public void setListaPersona(ArrayList<Persona> listaPersona) { this.listaPersona = listaPersona; } }

El cdigo base de la clase es bastante simple un atributo:


private ArrayList<Persona> listaPersona;

Y sus correspondientes mtodos get/set. Al igual que en el caso anterior lo que importa son las siguientes anotaciones:

@XmlAccessorType( XmlAccessType.FIELD)

Da el tipo de acceso a los elementos en la lista.

@XmlType(name = "", propOrder = { "listaPersona" })

Nos determina el orden de los atributos dentro del documento XML

@XmlRootElement(name = "personas")

EnriqueMoraMoral.Pag: 45/74

Unidad10.XSLT.

Realiza dos tareas, informa que es un nodo raz del documento y le asigna un nombre.

@XmlElement(name = "persona")

Cambia el nombre de listaPersonas por lo que es: una persona. Con estos dos ficheros tenemos la estructura base para trabajar con este documento XML y podemos empezar a cargar y a extraer valores del fichero, como se demuestra en el siguiente cdigo:
import import import import import import import import java.io.File; java.io.FileReader; java.io.IOException; java.util.ArrayList; javax.xml.bind.JAXBContext; javax.xml.bind.JAXBException; javax.xml.bind.Marshaller; javax.xml.bind.Unmarshaller;

public class Main { private static final String FICHERO_XML = "./personas.xml"; public static void main(String[] args) throws JAXBException, IOException { ArrayList<Persona> listaPersonas = new ArrayList<Persona>(); // carga de las personas. Persona p = new Persona(); p.setNif("nif1"); p.setNombre("nombre1"); p.setDireccion("calle1"); p.setPoblacion("pueblo1"); p.setTelefono("1111"); listaPersonas.add(p); p = new Persona(); p.setNif("nif2"); p.setNombre("nombre2"); p.setDireccion("calle2"); p.setPoblacion("pueblo2"); p.setTelefono("1112"); listaPersonas.add(p); p = new Persona(); p.setNif("nif3"); p.setNombre("nombre3"); p.setDireccion("calle3"); p.setPoblacion("pueblo3"); p.setTelefono("1113"); listaPersonas.add(p); // creacin de la estructura de almacenamiento que se pasa JAXB AlmacenPersonas ap = new AlmacenPersonas();
EnriqueMoraMoral.Pag: 46/74

Unidad10.XSLT.

ap.setListaPersona(listaPersonas); // crea JAXB contexto de trabajo e inicializa marshaller que es // el objeto que procesa la creacin del fichero XML JAXBContext context = JAXBContext.newInstance(AlmacenPersonas.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Escribe a partir de la lista de personas en la salida m.marshal(ap, System.out); // Hace lo mismo sobre un fichero m.marshal(ap, new File(FICHERO_XML)); // una vez escrito el fichero xml pasamos al proceso de lectura // cambiamos el objeto Marshaller por Unmarshaller System.out.println(); System.out.println("Lectura del fichero: "); // creacin del objeto de lectura Unmarshaller um = context.createUnmarshaller(); // obtenemos un objeto manejador que se lee del fichero AlmacenPersonas apl = (AlmacenPersonas) um.unmarshal(new FileReader(FICHERO_XML)); // se extrae la lista con los elementos ArrayList<Persona> lista = apl.getListaPersona(); // se procesa la lista con un iterador for (Persona per : lista) { System.out.println("nif: " + per.getNif() ); System.out.println("nombre: " + per.getNombre() ); System.out.println("direccion: " + per.getDireccion() ); } } }

Ejemplo 02.
Continuando con el ejemplo anterior vamos a desarrollar un ejemplo un poco ms complejo. Sobre el siguiente fichero XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <biblioteca> <libros> <libro> <isbn>Isbn1</isbn> <autor>autor1</autor> <titulo>titulo1</titulo>
EnriqueMoraMoral.Pag: 47/74

Unidad10.XSLT.

<editorial>editorial1</editorial> </libro> <libro> <isbn>Isbn3</isbn> <autor>autor3</autor> <titulo>titulo3</titulo> <editorial>editorial3</editorial> </libro> <libro> <isbn>Isbn3</isbn> <autor>autor3</autor> <titulo>titulo3</titulo> <editorial>editorial3</editorial> </libro> </libros> <personas> <persona> <nifcambiado>nif1</nifcambiado> <nombre>nombre1</nombre> <direccion>calle1</direccion> <poblacion>pueblo1</poblacion> <telefono>1111</telefono> </persona> <persona> <nifcambiado>nif2</nifcambiado> <nombre>nombre2</nombre> <direccion>calle2</direccion> <poblacion>pueblo2</poblacion> <telefono>1112</telefono> </persona> <persona> <nifcambiado>nif3</nifcambiado> <nombre>nombre3</nombre> <direccion>calle3</direccion> <poblacion>pueblo3</poblacion> <telefono>1113</telefono> </persona> </personas> </biblioteca>

En este caso es una biblioteca, que presenta una serie de ttulos (libros) y una serie de personas (lectores). Comenzamos por definir las dos estructuras bsicas del documentos libro y persona en las siguientes clases de Java Libro.java y Persona.java. Libro.java:
import javax.xml.bind.annotation.XmlType; @XmlType(propOrder = { "isbn", "autor", "titulo", "editorial" }) public class Libro { private String autor; private String titulo; private String editorial;
EnriqueMoraMoral.Pag: 48/74

Unidad10.XSLT.

private String isbn; public String getAutor() { return autor; } public void setAutor(String autor) { this.autor = autor; } public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; } public String getEditorial() { return editorial; } public void setEditorial(String editorial) { this.editorial = editorial; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; }

A destacar:

@XmlType(propOrder = { "isbn", "autor", "titulo", "editorial" })

para determinar el orden de aparicin de los campos en el documento XML. Persona.java:


import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; @XmlType(propOrder = { public class Persona { private String private String private String private String private String "nif", "nombre", "direccion", "poblacion", "telefono" }) nif; nombre; direccion; poblacion; telefono;

@XmlElement(name = "nifcambiado") public String getNif() { return nif; } public void setNif(String nif) { this.nif = nif; } public String getNombre() { return nombre;
EnriqueMoraMoral.Pag: 49/74

Unidad10.XSLT.

} public void setNombre(String nombre) { this.nombre = nombre; } public String getDireccion() { return direccion; } public void setDireccion(String direccion) { this.direccion = direccion; } public String getPoblacion() { return poblacion; } public void setPoblacion(String poblacion) { this.poblacion = poblacion; } public String getTelefono() { return telefono; } public void setTelefono(String telefono) { this.telefono = telefono; } E

Exactamente la misma clase que en el Ejemplo 01. Continuamos con la clase Almacn que ahora contiene una lista de personas y una lista de libros. Presentando la siguiente estructura:
import java.util.ArrayList; import import import import javax.xml.bind.annotation.XmlAccessType; javax.xml.bind.annotation.XmlAccessorType; javax.xml.bind.annotation.XmlElement; javax.xml.bind.annotation.XmlElementWrapper;

import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType;

@XmlAccessorType( XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "listaLibros", "listaPersona" }) @XmlRootElement(name = "biblioteca") public class AlmacenLibros { @XmlElementWrapper(name = "libros", required = true) @XmlElement(name = "libro") private ArrayList<Libro> listaLibros; @XmlElementWrapper(name = "personas", required = true) @XmlElement(name = "persona") private ArrayList<Persona> listaPersona;
EnriqueMoraMoral.Pag: 50/74

Unidad10.XSLT.

public void setListaLibros (ArrayList<Libro> p1 ) { listaLibros = p1; } public ArrayList<Libro> getListaLibros () { return listaLibros; } public ArrayList<Persona> getListaPersona() { return listaPersona; } public void setListaPersona(ArrayList<Persona> listaPersona) { this.listaPersona = listaPersona; } }

El cdigo introduce las dos ArrayList y sus metodos get/set. Como en los casos anteriores volvemos a repasar las anotaciones:

@XmlAccessorType( XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "listaLibros", "listaPersona" }) @XmlRootElement(name = "biblioteca")

Se fija el tipo de acceso para el elemento contenedor, se establece el orden de tratamiento de las listas en el documento XML y se dice que es un elemento raz y se le asigna el nombre biblioteca Existen otros dos grupos de anotaciones previos a la declaracin de las listas:

@XmlElementWrapper(name = "libros", required = true) @XmlElement(name = "libro") @XmlElementWrapper(name = "personas", required = true) @XmlElement(name = "persona")

Y:

La anotacin @XmlElement mantiene el mismo comportamiento de los casos anteriores, sustituyendo el nombre del atributo ArrayLista por un nombre ms significativo. La otra anotacin @XmlElementWrapper nos ahorra meter una clase intermedia que contenga un elemento de tipo lista creando la etiqueta <libros> </libros> y la etiqueta <personas> </personas> que contienen los libros y las personas. Se puede comprobar que ocurre si dichas etiquetas se comentan en la definicin del XML. Por ltimo, la clase Main.java que nos permite probar al estilo del caso anterior la ejecucin y prueba de las clases anteriores. Su funcionamiento es semejante al del ejemplo anterior:
import import import import java.io.File; java.io.FileReader; java.io.IOException; java.util.ArrayList;

Enr iqueMoraMoral.Pag: 51/74

Unidad10.XSLT.

import import import import import import

javax.xml.bind.JAXBContext; javax.xml.bind.JAXBException; javax.xml.bind.Marshaller; javax.xml.bind.Unmarshaller; javax.xml.bind.annotation.XmlElement; javax.xml.bind.annotation.XmlElements;

public class Main { private static final String FICHERO_XML = "./libros.xml"; public static void main(String[] args) throws JAXBException, IOException { ArrayList<Libro> listaLibros = new ArrayList<Libro>(); ArrayList<Persona> listaPersonas = new ArrayList<Persona>(); // creacion de libros Libro libro = new Libro(); libro.setAutor("autor1"); libro.setEditorial("editorial1"); libro.setTitulo("titulo1"); libro.setIsbn("Isbn1"); listaLibros.add(libro); libro = new Libro(); libro.setAutor("autor3"); libro.setEditorial("editorial3"); libro.setTitulo("titulo3"); libro.setIsbn("Isbn3"); listaLibros.add(libro); libro = new Libro(); libro.setAutor("autor3"); libro.setEditorial("editorial3"); libro.setTitulo("titulo3"); libro.setIsbn("Isbn3"); listaLibros.add(libro); Persona p = new Persona(); p.setNif("nif1"); p.setNombre("nombre1"); p.setDireccion("calle1"); p.setPoblacion("pueblo1"); p.setTelefono("1111"); listaPersonas.add(p); p = new Persona(); p.setNif("nif2"); p.setNombre("nombre2"); p.setDireccion("calle2"); p.setPoblacion("pueblo2"); p.setTelefono("1112"); listaPersonas.add(p);

EnriqueMoraMoral.Pag: 52/74

Unidad10.XSLT.

p = new Persona(); p.setNif("nif3"); p.setNombre("nombre3"); p.setDireccion("calle3"); p.setPoblacion("pueblo3"); p.setTelefono("1113"); listaPersonas.add(p); // creacin de la estructura de almacenamiento que se pasa JAXB AlmacenLibros al = new AlmacenLibros(); al.setListaLibros(listaLibros); al.setListaPersona(listaPersonas); // crea JAXB contexto de trabajo // e inicializa marshaller que es el objeto que proceso JAXBContext context = JAXBContext.newInstance(AlmacenLibros.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Escribe a partir de la lista de personas en la salida m.marshal(al, System.out); // Hace lo mismo sobre un fichero m.marshal(al, new File(FICHERO_XML)); // una vez escrito el fichero xml pasamos al proceso de lectura // cambiamos el objeto Marshaller por Unmarshaller System.out.println(); System.out.println("Lectura del fichero: "); // creacin dle objeto de lectura Unmarshaller um = context.createUnmarshaller(); AlmacenLibros all = (AlmacenLibros) um.unmarshal(new FileReader(FICHERO_XML)); ArrayList<Libro> lista = all.getListaLibros(); for (Libro lbr : lista) { System.out.println("autor: " + lbr.getAutor() ); System.out.println("titulo: " + lbr.getTitulo() ); System.out.println("editorial: " + lbr.getEditorial() ); System.out.println("isbn: " + lbr.getIsbn() ); } } }

Ejemplo 03.
En este ejemplo, siguiendo con el caso anterior se desea manejar un fichero XML con la siguiente
EnriqueMoraMoral.Pag: 53/74

Unidad10.XSLT.

estructura:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <biblioteca> <personas> <persona> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion>calle1</direccion> <poblacion>pueblo1</poblacion> <telefono>1111</telefono> <libros> <libro> <isbn>Isbn1</isbn> <autor>autor1</autor> <titulo>titulo1</titulo> <editorial>editorial1</editorial> </libro> <libro> <isbn>Isbn3</isbn> <autor>autor3</autor> <titulo>titulo3</titulo> <editorial>editorial3</editorial> </libro> <libro> <isbn>Isbn3</isbn> <autor>autor3</autor> <titulo>titulo3</titulo> <editorial>editorial3</editorial> </libro> </libros> </persona> <persona> <nif>nif2</nif> <nombre>nombre2</nombre> <direccion>calle2</direccion> <poblacion>pueblo2</poblacion> <telefono>1112</telefono> </persona> <persona> <nif>nif3</nif> <nombre>nombre3</nombre> <direccion>calle3</direccion> <poblacion>pueblo3</poblacion> <telefono>1113</telefono> </persona> </personas> </biblioteca>

En este caso suponemos que cada persona tiene una lista de libros. Comenzamos con las clases Persona.java y Libro.java. Libro.java es exactamente igual que la del ejemplo anterior, pudiendo comenzar por Persona.java:
import java.util.ArrayList; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType;
Enr iqueMoraMoral.Pag: 54/74

Unidad10.XSLT.

import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlType;

@XmlAccessorType( XmlAccessType.FIELD) @XmlType(propOrder = { "nif", "nombre", "direccion", "poblacion", "telefono", "listaLibro" }) public class Persona { private String nif; private String nombre; private String direccion; private String poblacion; private String telefono; @XmlElementWrapper(name = "libros", required = true) @XmlElement(name = "libro") private ArrayList<Libro> listaLibro;

public String getNif() { return nif; } public void setNif(String nif) { this.nif = nif; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getDireccion() { return direccion; } public void setDireccion(String direccion) { this.direccion = direccion; } public String getPoblacion() { return poblacion; } public void setPoblacion(String poblacion) { this.poblacion = poblacion; } public String getTelefono() { return telefono; } public void setTelefono(String telefono) { this.telefono = telefono; } public ArrayList<Libro> getListaLibro() { return listaLibro; }
EnriqueMoraMoral.Pag: 55/74

Unidad10.XSLT.

public void setListaLibro(ArrayList<Libro> listaLibros) { this.listaLibro = listaLibros; } }

Es prcticamente igual que la del ejemplo anterior pero introduciendo la lista de libros de dicha persona:
@XmlElementWrapper(name = "libros", required = true) @XmlElement(name = "libro") private ArrayList<Libro> listaLibro;

Se ha realizado los ajustes con @XmlElementWrapper para no tener que introducir una clase intermedia y con @XmlElement para cambiar el nombre del elemento. Pasamos al elemento contenedor de nivel superior, en este caso AlmacenLibros.java con el siguiente cdigo:
import java.util.ArrayList; import import import import import import javax.xml.bind.annotation.XmlAccessType; javax.xml.bind.annotation.XmlAccessorType; javax.xml.bind.annotation.XmlElement; javax.xml.bind.annotation.XmlElementWrapper; javax.xml.bind.annotation.XmlRootElement; javax.xml.bind.annotation.XmlType;

//This statement means that class "AlmacenLibros.java" is the root-element of our example @XmlAccessorType( XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "listaPersona" }) @XmlRootElement(name = "biblioteca") public class AlmacenLibros {

@XmlElementWrapper(name = "personas", required = true) @XmlElement(name = "persona") private ArrayList<Persona> listaPersona; public ArrayList<Persona> getListaPersona() { return listaPersona; } public void setListaPersona(ArrayList<Persona> listaPersona) { this.listaPersona = listaPersona; }

EnriqueMoraMoral.Pag: 56/74

Unidad10.XSLT.

De hecho es ms simple que el del ejemplo anterior. En este caso cabe destacar:
@XmlElementWrapper(name = "personas", required = true) @XmlElement(name = "persona") private ArrayList<Persona> listaPersona;

Que nos permite eliminar una estructura intermedia y cambiar el nombre de la etiqueta. Por ltimo, falta la clase Main.java con una estructura semejante a los dos ejemplos anteriores que se ajusta a este ejemplo:
import import import import import import import import import import java.io.File; java.io.FileReader; java.io.IOException; java.util.ArrayList; javax.xml.bind.JAXBContext; javax.xml.bind.JAXBException; javax.xml.bind.Marshaller; javax.xml.bind.Unmarshaller; javax.xml.bind.annotation.XmlElement; javax.xml.bind.annotation.XmlElements;

public class Main { private static final String FICHERO_XML = "./personas.xml"; public static void main(String[] args) throws JAXBException, IOException {

ArrayList<Libro> lb = new ArrayList<Libro>(); ArrayList<Persona> listaPersonas = new ArrayList<Persona>(); // creacion de libros Libro libro = new Libro(); libro.setAutor("autor1"); libro.setEditorial("editorial1"); libro.setTitulo("titulo1"); libro.setIsbn("Isbn1"); lb.add(libro); libro = new Libro(); libro.setAutor("autor3"); libro.setEditorial("editorial3"); libro.setTitulo("titulo3"); libro.setIsbn("Isbn3"); lb.add(libro); libro = new Libro(); libro.setAutor("autor3"); libro.setEditorial("editorial3");
Enr iqueMoraMoral.Pag: 57/74

Unidad10.XSLT.

libro.setTitulo("titulo3"); libro.setIsbn("Isbn3"); lb.add(libro); Persona p = new Persona(); p.setNif("nif1"); p.setNombre("nombre1"); p.setDireccion("calle1"); p.setPoblacion("pueblo1"); p.setTelefono("1111"); p.setListaLibro(lb);

listaPersonas.add(p); p = new Persona(); p.setNif("nif2"); p.setNombre("nombre2"); p.setDireccion("calle2"); p.setPoblacion("pueblo2"); p.setTelefono("1112"); listaPersonas.add(p); p = new Persona(); p.setNif("nif3"); p.setNombre("nombre3"); p.setDireccion("calle3"); p.setPoblacion("pueblo3"); p.setTelefono("1113"); listaPersonas.add(p);

// creacin de la estructura de almacenamiento que se pasa JAXB AlmacenLibros al = new AlmacenLibros(); al.setListaPersona(listaPersonas); // crea JAXB contexto de trabajo e inicializa marshaller // que es el objeto que proceso JAXBContext context = JAXBContext.newInstance(AlmacenLibros.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Escribe a partir de la lista de personas en la salida m.marshal(al, System.out); // Hace lo mismo sobre un fichero m.marshal(al, new File(FICHERO_XML)); // una vez escrito el fichero xml pasamos al proceso de lectura // cambiamos el objeto Marshaller por Unmarshaller
EnriqueMoraMoral.Pag: 58/74

Unidad10.XSLT.

System.out.println(); System.out.println("Lectura del fichero: "); // creacin dle objeto de lectura Unmarshaller um = context.createUnmarshaller(); AlmacenLibros all = (AlmacenLibros) um.unmarshal(new FileReader(FICHERO_XML)); ArrayList<Persona> lista = all.getListaPersona(); for (Persona per : lista) { System.out.println("nif: " + per.getNif() ); System.out.println("nombre: " + per.getNombre() ); System.out.println("direccion: " + per.getDireccion() ); }

} }

Ejemplo 04.
En este ejemplo, se maneja el siguiente fichero XML con un atributo:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <personas> <persona nif="nif1"> <nombre>nombre1</nombre> <direccion>calle1</direccion> <poblacion>pueblo1</poblacion> <telefono>1111</telefono> </persona> <persona nif="nif2"> <nombre>nombre2</nombre> <direccion>calle2</direccion> <poblacion>pueblo2</poblacion> <telefono>1112</telefono> </persona> <persona nif="nif3"> <nombre>nombre3</nombre> <direccion>calle3</direccion> <poblacion>pueblo3</poblacion> <telefono>1113</telefono> </persona> </personas>

El cdigo es exactamente el mismo que el correspondiente al del ejemplo 1. Slo se ha cambiado la declaracin de la clase persona para ajustarle el atributo, segn el siguiente cdigo:
import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; @XmlType(propOrder = { "nif", "nombre", "direccion", "poblacion", "telefono" }) public class Persona {
EnriqueMoraMoral.Pag: 59/74

Unidad10.XSLT.

private private private private private

String String String String String

nif; nombre; direccion; poblacion; telefono;

// Cambia el elemento a un atributo @XmlAttribute (name="nif") public String getNif() { return nif; } public void setNif(String nif) { this.nif = nif; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getDireccion() { return direccion; } public void setDireccion(String direccion) { this.direccion = direccion; } public String getPoblacion() { return poblacion; } public void setPoblacion(String poblacion) { this.poblacion = poblacion; } public String getTelefono() { return telefono; } public void setTelefono(String telefono) { this.telefono = telefono; } }

En este caso se ha ajustado la siguiente anotacin en:


@XmlAttribute (name="nif") public String getNif() { return nif; }

Que indica que el Nif no es un elemento sino un atributo denominado nif.

EnriqueMoraMoral.Pag: 60/74

Unidad10.XSLT.

Ejemplo 5.
El proceso anterior se puede simplificar durante la creacin JAXB no puede simplificar el proceso bastante al ahorrarnos de crear manualmente las clases de cada uno de los elementos y de la clase almacn. Comenzamos creando nuestro fichero desde un Esquema XSD, admite Relax NG de forma experimental. Por ejemplo el siguiente documento para personas: <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="personas"> <xs:complexType> <xs:sequence> <xs:element name="persona" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="nif" type="xs:string"/> <xs:element name="nombre" type="xs:string"/> <xs:element name="direccion" type="xs:string"/> <xs:element name="poblacion" type="xs:string"/> <xs:element name="telefono" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> Una vez creado el esquema podemos crear el fichero con los datos, si se desea leer o crearlo directamente desde Java. Lo nico que nos interesa es el fichero anterior. Desde el terminal de comandos nos vamos a la carpeta donde se encuentra el fichero o utilizamos el comando xjc para que cree las clases Java a partir de nuestro Esquema XSD. Basta con ejecutar: xjc personas.xsd Y se crea una carpeta con los fuentes de las clases Java. Arrancamos Eclipse, creamos un nuevo proyecto en este caso proyecto04 y se copian mediante arrastre los dos ficheros generados por xjc hasta obtener la siguiente estructura:

Los ficheros Java


EnriqueMoraMoral.Pag: 61/74

Unidad10.XSLT.

presentan cada uno un error derivado de la introduccin de el paquete generate. En nuestro caso y para simplificar el proceso borramos la linea package de cada uno de los ficheros, eliminndose los errores. El fichero ObjectFactory.java es un simple constructor de la clase Personas. El fichero Personas.java contiene en una misma la clase almacn y en su interior la declaracin de la clase persona. Los elementos y tecnologas utilizadas son semejantes a los de los ejercicios anteriores. En este caso la clase slo es de lectura y no se permite su modificacin. Basta con aadir el mtodo setPersona con el siguiente cdigo:
public void setPersona ( List<Personas.Persona> pa1) { persona = pa1; }

Una vez realizado este proceso podemos con algunos modificaciones utilizar el cdigo del ejercicio anterior. Cargando la siguiente clase Main.java:
import import import import import import import import java.io.File; java.io.FileReader; java.io.IOException; java.util.ArrayList; javax.xml.bind.JAXBContext; javax.xml.bind.JAXBException; javax.xml.bind.Marshaller; javax.xml.bind.Unmarshaller;

public class Main { private static final String FICHERO_XML = "./personas.xml"; public static void main(String[] args) throws JAXBException, IOException { // creacion del objeto factory ObjectFactory of = new ObjectFactory(); ArrayList<Personas.Persona> listaPersonas = new ArrayList<Personas.Persona>(); // carga de las personas.

Personas.Persona p = new Personas.Persona(); p.setNif("nif1"); p.setNombre("nombre1"); p.setDireccion("calle1"); p.setPoblacion("pueblo1"); p.setTelefono("1111"); listaPersonas.add(p); p = new Personas.Persona(); p.setNif("nif2");
EnriqueMoraMoral.Pag: 62/74

Unidad10.XSLT.

p.setNombre("nombre2"); p.setDireccion("calle2"); p.setPoblacion("pueblo2"); p.setTelefono("1112"); listaPersonas.add(p); p = new Personas.Persona(); p.setNif("nif3"); p.setNombre("nombre3"); p.setDireccion("calle3"); p.setPoblacion("pueblo3"); p.setTelefono("1113"); listaPersonas.add(p);

// creacin de la estructura de almacenamiento que se pasa JAXB Personas ap = of.createPersonas();

ap.setPersona(listaPersonas); // crea JAXB contexto de trabajo e inicializa marshaller // que es el objeto que proceso JAXBContext context = JAXBContext.newInstance(Personas.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Escribe a partir de la lista de personas en la salida m.marshal(ap, System.out); // Hace lo mismo sobre un fichero m.marshal(ap, new File(FICHERO_XML)); // una vez escrito el fichero xml pasamos al proceso de lectura // cambiamos el objeto Marshaller por Unmarshaller System.out.println(); System.out.println("Lectura del fichero: "); // creacin dle objeto de lectura Unmarshaller um = context.createUnmarshaller(); Personas apl = (Personas) um.unmarshal(new FileReader(FICHERO_XML)); ArrayList<Personas.Persona> lista = (ArrayList<Personas.Persona>) apl.getPersona(); for (Personas.Persona per : lista) { System.out.println("nif: " + per.getNif() ); System.out.println("nombre: " + per.getNombre() ); System.out.println("direccion: " + per.getDireccion() ); }
EnriqueMoraMoral.Pag: 63/74

Unidad10.XSLT.

} }

La clase Main.java es prcticamente la misma que la de apartados anteriores ajustando las listas a la clase Personas.java que se ha creado automticamente. Se pueden realizar ciertas modificaciones sobre uta extensin de la clase Personas.java aadiendo nuevos mtodos, como el que inserta una Persona de forma directa sin utilizar la puntuacin dentro de la clase parametrizada.

Ejemplo 6.
Acceso a un fichero XML usando la librera DOM. El acceso a la libera DOM se puede realizar con el siguiente cdigo de ejemplo:
import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import import import import import org.w3c.dom.Document; org.w3c.dom.Element; org.w3c.dom.Node; org.w3c.dom.NodeList; org.xml.sax.SAXException;

public class Main { /** * @param args * @throws ParserConfigurationException * @throws IOException * @throws SAXException */ public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException { // Enlace a la lireria DOM DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse("personas.xml"); // acceso a los nodos que se almacena en personas // devuelve una lista de nodos NodeList personas = ((org.w3c.dom.Document) doc).getElementsByTagName("persona"); for (int i = 0; i <personas.getLength(); i++) { // acceso a cada una de las personas en concreto Element persona = (Element)personas.item(i); // vuelve a generar la lista de nodos hijos cada uno de un tipo NodeList hijos = (NodeList)persona.getChildNodes();
EnriqueMoraMoral.Pag: 64/74

Unidad10.XSLT.

for (int j = 0; j < hijos.getLength(); j++){ Node hijo = hijos.item(j); // imprime informacin de cada hijo System.out.println( hijo.getNodeName() + " hijo.getTextContent() ); } } } } " +

La librera DOM esta muy desarrollada y consta de multitud de mtodos para acceder a sus distintos elementos. Se utiliza en JavaScript como elemento base de tratamiento de los documentos HTML. Los nodos se extraen con mtodos del estilo:
NodeList personas = ((org.w3c.dom.Document) doc).getElementsByTagName("persona");

Que en este caso particular devuelve una lista de nodos de todos los elementos persona del fichero que se ha abierto anteriormente. Esta estructura se mantiene entera en memoria por lo que se puede modificar y posteriormente almacenar. El problema que presenta es que necesita una gran cantidad de memoria para su procesado.

Ejemplo 7.
Se puede recorrer el fichero XML utilizando las librera SAX-SAXON. En este caso de forma recursiva voy extrayendo cada elemento. Con un manejador especifico para cada documento voy extrayendo y procesando nodo a nodo los distintos valores. De todas las libreras es tal vez la ms rpida pero el manejo en documentos complejos requiere de un manejador complejo. El siguiente cdigo realiza un parse o recorrido lineal del fichero personas.xml mostrando los datos por la salida estndar.
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class Main { /** * @param args */ public static void testParsingWithSAX() throws Exception { // elementos de creacin del parse SAX
EnriqueMoraMoral.Pag: 65/74

Unidad10.XSLT.

SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); // // // // SAX necesita un objeto manejador para poder recorrer el documento. el manejador necesita una clase que extienda de DefaultHandler o crear el objeto directamente cosa que se ha realizado.

/* * El manejador recorre elemento a elemento de forma recursiva * Por cada elemento hace una entrada con startElement * una salida o finalizacin con endElement * y un proceso por cada Entrada/salida de extraccin de datos * con characters */ DefaultHandler manejador = new DefaultHandler() { // se usa para saber en que elemento estoy String nombreElemento; // me dice si proceso inicio o fin para extraer los datos boolean bfin = false; public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException { nombreElemento = qName; bfin = false; } public void endElement(String uri, String localName, String qName) throws SAXException { bfin = true; } public void characters(char ch[], int start, int length) throws SAXException { if (!bfin) { if ( nombreElemento.equalsIgnoreCase("nif")) { String nif = new String(ch, start, length); System.out.println ("nif: " + nif); } else if (nombreElemento.equalsIgnoreCase("nombre")) { String nombre = new String(ch, start, length); System.out.println ("nombre: " + nombre); } } } }; // proceso de pare del fichero con el manejador anterior
EnriqueMoraMoral.Pag: 66/74

Unidad10.XSLT.

saxParser.parse("personas.xml", manejador); } public static void main(String[] args) throws Exception { // TODO Auto-generated method stub testParsingWithSAX(); } }

Ejemplo 8.
Uso de la Herramienta DataQuery bajo Eclipse. Comenzamos instalando el Plugin Editor DataQuery en Eclipse, como se puede observar en la siguiente figura:

Una vez instalado el producto pasamos a utilizar la Perspectiva DataQuery Editor que se ha instalado en Eclipse:
EnriqueMoraMoral.Pag: 67/74

Unidad10.XSLT.

Es una herramienta de pago. Una vez instalada convierte la expresiones Xquery en cdigo ejecutable Java. Es una solucin rpida para el manejo de la Techologa XML en Java.

7. Ejemplo Cooperativa Agraria.


Sobre el siguiente documento Relax NG:
datatypes xsd = "http://www.w3.org/2001/XMLSchema-datatypes" element cooperativa { element socios { element socio { attribute numeroSocio { xsd:integer}, element nif {xsd:string}, element nombre {xsd:string}, element direccion {xsd:string}, element poblacion {xsd:string}, element telefono {xsd:string}, element saldo {xsd:decimal}}* }, element vales {element vale { attribute numeroVale { xsd:integer}, attribute numeroSocio {xsd:integer}, element fecha {xsd:date}, element peso {xsd:decimal}, element rendimiento {xsd:decimal}}* }, element gastos { element gasto { attribute numeroGasto {xsd:integer}, attribute numeroSocio {xsd:integer},

EnriqueMoraMoral.Pag: 68/74

Unidad10.XSLT.

element fecha {xsd:date}, element descripcion {xsd:string}, element importe {xsd:decimal}}*}}

Ejercicios sobre XSLT:


1. Generar un pgina WEB con los datos de cada socio, por cada socio mostrar, en una tabla la informacin de sus vales con la fecha, peso, rendimiento y kilos de aceite obtenidos e importe de estos sabiendo que se ha pagado a 1.5 el kilo de aceite en bruto.
2. <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> May 17, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <xsl:for-each select="cooperativa/socios/socio"> Numero: <xsl:value-of select="@numeroSocio"/> Nif: <xsl:value-of select="nif"/> Nombre: <xsl:value-of select="nombre"/> <br/> Direccin: <xsl:value-of select="direccion"/> Poblacion: <xsl:value-of select="poblacion"/> Telefono: <xsl:value-of select="telefono"/> <br/> <xsl:variable name="numeroSocio" select="@numeroSocio"/> <table border="3px"> <tr> <th>Numero vale</th> <th> Fecha</th> <th> Peso</th> <th> Rendimiento</th> <th>K. Aceite</th> <th>Importe</th></tr> <xsl:for-each select="/cooperativa/vales/vale[@numeroSocio = $numeroSocio]"> <tr> <td> <xsl:value-of select="@numeroVale"/></td> <td> <xsl:value-of select="fecha"/></td> <td> <xsl:value-of select="peso"/></td> <td> <xsl:value-of select="rendimiento"/></td> <td> <xsl:value-of select="peso * rendimiento div 100"/></td> <td> <xsl:value-of select="peso * rendimiento div 100 * 1.5"/></td> </tr> </xsl:for-each> <xsl:if test="sum(/cooperativa/vales/vale[@numeroSocio = $numeroSocio]/peso) != 0"> <tr> <th colspan="2"> Totales: </th> <th> <xsl:value-of select="sum(/cooperativa/vales/vale[@numeroSocio = $numeroSocio]/peso)"/> </th> <th> <xsl:value-of select="sum(/cooperativa/vales/vale[@numeroSocio = $numeroSocio]/(peso * rendimiento)) div sum(/cooperativa/vales/vale[@numeroSocio = $numeroSocio]/peso)" /> </th> <th> <xsl:value-of select="sum(/cooperativa/vales/vale[@numeroSocio = $numeroSocio]/(peso * rendimiento div 100))" /></th>
EnriqueMoraMoral.Pag: 69/74

Unidad10.XSLT.

<th> <xsl:value-of select="sum(/cooperativa/vales/vale[@numeroSocio = $numeroSocio]/(peso * rendimiento div 100 * 1.5))" /></th> </tr> </xsl:if> </table> </xsl:for-each> </body></html> </xsl:template> </xsl:stylesheet>

3. En cooperativa.xml obtener un listado de aquellos socios que no tienen ni portes ni gastos. <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> May 17, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <body> <xsl:for-each select="cooperativa/socios/socio[not(@numeroSocio = /cooperativa/vales/vale/@numeroSocio) and not (@numeroSocio = /cooperativa/gastos/gasto/@numeroSocio)]"> Numero: <xsl:value-of select="@numeroSocio"/> Nif: <xsl:value-of select="nif"/> Nombre: <xsl:value-of select="nombre"/> <br/> Direccin: <xsl:value-of select="direccion"/> Poblacion: <xsl:value-of select="poblacion"/> Telefono: <xsl:value-of select="telefono"/> <br/> </xsl:for-each> </body></html> </xsl:template> </xsl:stylesheet> 4. Generar una salida como documento XML que contenga los vales agrupados por socios con la siguiente estrucutura: <valesSocios> <socio numeroSocio=> <nif> </nif> <nombre> </nombre> <direccion> </direccion> <poblacion> </poblacion>
EnriqueMoraMoral.Pag: 70/74

Unidad10.XSLT.

<telefono> </telefono> <vales> <vale numeroVale = > <fecha> </fecha> <peso> </peso> <rendimiento> <rendimiento> <kilosAceite> </kilosAceite> </vale> <vales> <socios </valesSocios> Cdigo XSLT: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> May 17, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <valesSocio> <xsl:for-each select="cooperativa/socios/socio"> <socio numeroSocio="{@numeroSocio}"> <xsl:copy-of select="nif"/> <xsl:copy-of select="nombre"/> <xsl:copy-of select="direccion"/> <xsl:copy-of select="poblacion"/> <xsl:copy-of select="telefono"/> <xsl:variable name="numeroSocio" select="@numeroSocio"/> <vales> <xsl:for-each select="/cooperativa/vales/vale[@numeroSocio = $numeroSocio]"> <xsl:copy-of select="."/> </xsl:for-each> </vales> </socio> </xsl:for-each> </valesSocio> </xsl:template>
Enr iqueMoraMoral.Pag: 71/74

Unidad10.XSLT.

</xsl:stylesheet>

Resultado en salida XML formateada:


<?xml version="1.0" encoding="UTF-8"?> <valesSocio> <socio numeroSocio="1"> <nif>nif1</nif> <nombre>nombre1</nombre> <direccion>calle1</direccion> <poblacion>pueblo1</poblacion> <telefono>11111</telefono> <vales><vale numeroSocio="1" numeroVale="1"> <fecha>2011-12-01</fecha> <peso>200</peso> <rendimiento>20</rendimiento> </vale> <vale numeroSocio="1" numeroVale="1"> <fecha>2011-12-01</fecha> <peso>200</peso> <rendimiento>20</rendimiento> </vale> <vale numeroSocio="1" numeroVale="2"> <fecha>2011-12-01</fecha> <peso>200</peso> <rendimiento>22</rendimiento> </vale> </vales> </socio> <socio numeroSocio="2"> <nif>nif2</nif> <nombre>nombre2</nombre> <direccion>calle2</direccion> <poblacion>pueblo2</poblacion> <telefono>21111</telefono> <vales> <vale numeroSocio="2" numeroVale="3"> <fecha>2011-12-01</fecha> <peso>200</peso> <rendimiento>20</rendimiento> </vale> <vale numeroSocio="2" numeroVale="4"> <fecha>2011-12-01</fecha> <peso>200</peso> <rendimiento>22</rendimiento> </vale> </vales> </socio>
EnriqueMoraMoral.Pag: 72/74

Unidad10.XSLT.

<socio numeroSocio="3"> <nif>nif3</nif> <nombre>nombre3</nombre> <direccion>calle3</direccion> <poblacion>pueblo3</poblacion> <telefono>311111</telefono> <vales> <vale numeroSocio="3" numeroVale="5"> <fecha>2011-12-01</fecha> <peso>200</peso> <rendimiento>20</rendimiento> </vale> <vale numeroSocio="3" numeroVale="6"> <fecha>2011-12-01</fecha> <peso>200</peso> <rendimiento>22</rendimiento> </vale> </vales> </socio> <socio numeroSocio="30"> <nif>nif30</nif> <nombre>nombre30</nombre> <direccion>calle30</direccion> <poblacion>pueblo30</poblacion> <telefono>3011111</telefono> <vales/> </socio> </valesSocio> 4. Sobre el documento como la salida que se ha generado en el ejemplo anterior, que se puede llamar sol3.xml, mostrar un documento HTML donde aparezca nif, nombre del socio e importe total de sus aceitunas: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xs xd" version="2.0"> <xd:doc scope="stylesheet"> <xd:desc> <xd:p><xd:b>Created on:</xd:b> May 17, 2012</xd:p> <xd:p><xd:b>Author:</xd:b> tridente</xd:p> <xd:p></xd:p> </xd:desc> </xd:doc> <xsl:template match="/"> <html> <head></head> <body>
Enr iqueMoraMoral.Pag: 73/74

Unidad10.XSLT.

<xsl:for-each select="valesSocio/socio"> Nif: <xsl:value-of select="nif"/> Nombre: <xsl:value-of select="nombre"/> Importe: <xsl:value-of select="sum(vales/vale/(peso * rendimiento div 100 * 1.5))"/> <br/> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

Enr iqueMoraMoral.Pag: 74/74