Post on 22-Jan-2016
description
Curso: XML, de los datos a la presentaciónJulio de 2005
CAPTIVA · www.captiva.es
XSLT
¿Qué es XSLT?
Parte de XSL (eXtensible Stylesheet Language) XSLT XSL Transformations (Transformaciones) XSL-FO XSL Formatting Objects (Formato)
Aplicación XML Lenguaje de programación en base a templates
para transformar fichero XML en otro fichero XML Se utiliza XPath para seleccionar partes del fichero
de entrada
¿Con qué se procesan? Procesadores XSLT
Procesador XSLT MSXML (IE6) (.Net) http://msdn.microsoft.com/library/en-us/xmlsdk/html/6b8e4b12-f090-49e5-a2e4-b8fb913ac320.asp
Xalan del proyecto Apache (basado en LotusXSL de IBM) (Java) Api y programa línea de comandos http://xml.apache.org/xalan-j/
Cocoon del proyecto Apache (Java) Aplicación web para crear portales web multiformato Hace uso de Xalan http://cocoon.apache.org/
Saxon (Java) Versión comercial (soporta schema) y opensource Versión estable (XSLT 1.0) y Saxon-B (XSLT 2.0 WD 4-04-2005) http://saxon.sourceforge.net/
XT (Java) Uno de los primeros pero descontinuado (2002) http://www.blnz.com/xt/index.html
4Suite (python) Suite con procesamiento XML de todo tipo (DOM, RDF, XSLT, RELAX NG, …) http://www.4suite.org
¿Con qué se procesan? (II)
Los navegadores más conocidos tienen soporte XSLT (Explorer, Mozilla/Firefox).
Si creamos plantilla XSL que convierta a XHTML ¡Podemos ver directamente nuestro XML en un
navegador! La instancia de documento XML debe apuntar a
la plantilla necesaria con la PI<?xml-stylesheet type=“text/xml" href=“url-a-plantilla.xsl"?> <?xml-stylesheet type=“text/xsl" href=“url-a-plantilla.xsl"?>
Estructura mínima
Este es un ejemplo de fichero mínimo XSLT válido:<xsl:stylesheet version = '1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<!-- Aqui van los templates --></xsl:stylesheet>
El elemento raíz es xsl:stylesheet o xsl:transform (son sinónimos)
Es obligatorio indicar el namespace y el atributo de versión
Ejemplo Aplicar basica.xsl a carta.xml (directorio ejemplos)
La pieza clave: Template Elemento básico de programación template Formato
<xsl:template match=“xpath"> <!-- Contenido a substituir --></xsl:template>
Ejemplo. Consideremos el fichero XML de entrada libro.xml. Aplicamos la siguiente plantilla libro-template.xsd. Ejecutar transformación en JEdit.
<?xml version="1.0"?><libro> <titulo>Sin noticias de Grub</titulo> <autor>Eduardo Mendoza</autor></libro>
<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="titulo"> Un titulo </xsl:template> <xsl:template match="autor"> Un autor </xsl:template></xsl:stylesheet>
La pieza clave: Template (II)
¿Cómo funciona procesador XSLT? Documento coge nodo raíz (/) Recorre nodo a nodo de arriba abajo pasando por todos hasta el final Los
templates para los padres se evalúan antes que los de sus hijos Determina si hay reglas que seleccionen dicho nodo (match)
¿Hay templates aplicables? Deja en manos del template el procesado del nodo y descendientes
¿No hay? Regla por defecto. Regla por defecto Convertir a string el nodeset (o sea contenido textual del
primer nodo elemento hijo) y seguir procesando la descendencia
<?xml version="1.0" encoding="UTF-8"?>
Un titulo Un autor
Extracción de texto <xsl:value-of>
Convierte a texto una expresión XPath Sintaxis:
<xsl:value-of select=“xpath”/> Se evalúa dentro de un template. Vamos a extraer el contenido de los nodos de libro.xml a través de la
siguiente plantilla (libro-valueof.xsl):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/" xml:space="preserve"> <html xmlns="http://www.w3.org/1999/xhtml"> <head></head> <body> <h1> <xsl:value-of select="//titulo"/> </h1> <h2> <xsl:value-of select="//autor"/> </h2> </body> </html> </xsl:template></xsl:stylesheet>
Aplicación de templates Hemos visto el funcionamiento por defecto
Seleccionar nodo (empezamos por raíz) ¿Se le aplica alguna regla de template? Sí lo procesa la
regla No Procesado por defecto (para nodos elemento mostrar
primer nodo hijo textual y procesar nodos elemento hijos) Los templates pueden alterar cómo se recorre el árbol
<xsl:apply-templates select=“subgrupo”> Si no se especifica expresión Xpath para el subgrupo se sigue
procesando todos los hijos Ejemplos. Coger fichero ejemplo-apply-
templates.xml y aplicar ejemplo-apply-templates.xsd
Descomentar uno a uno <xsl:apply-templates> y explicar lo ocurrido
Reglas por defecto
Había siete tipos de nodos en XML: nodo raíz, elementos, texto, atributos, namespaces, PI, comentarios
XSLT proporciona templates por defecto para cada tipo
Hemos visto la regla para el raíz y elementos:
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
Reglas por defecto (II) Regla por defecto para atributos y texto
<xsl:template match=“text()|@*"> <xsl:value-of “.” />
</xsl:template> Aplicar una plantilla vacía (basica.xsl) a ejemplo-apply-
templates.xml ¿Por qué no salen los valores de los atributos?
XSLT considera a los elementos padres de los atributos pero no al revés ¿? Solución Seleccionar manualmente atributos
<xsl:apply-templates select=“@*”/> Ejemplo Plantilla ejemplo-default-templates.xsl
Regla por defecto para PI y comentarios No hace nada<xsl:template match="processing-instruction()|
comment( )"/> Regla por defecto para namespaces
No hay El procesador XSLT los agrega adecuadamente en caso de que sean necesarios.
Modos
Modo Aplicación de templates diferentes a mismos elementos
diferentes salidas con misma entrada ¿Cómo se usan?
<xsl:template match=“/”><xsl:apply-templates select=“AAA” ><xsl:apply-templates select=“AAA” mode=“cursiva”><xsl:apply-templates select=“AAA” mode=“negrita”>
</xsl:template><xsl:template match=“AAA” mode=“cursiva”>…<xsl:template match=“AAA” mode=“negrita”>…
Ejemplo ejemplo-base.xml y ejemplo-modos.xsl
Atributos Esta forma no funciona
<xsl:template match=“AAA”><“AAA2” bbb2=‘<xsl:value-of select=“BBB”’/>
</xsl:template> Forma correcta {}
<xsl:template match=“AAA”><“AAA2” bbb2=“{BBB}”>
</xsl:template> Alternativa <xsl:attribute>
<TD> <xsl:attribute name="style"> <xsl:text>color:</xsl:text> <xsl:value-of select="."/> </xsl:attribute> <xsl:value-of select="."/></TD>
Ejemplos: ejemplo-atributos.xml ejemplo-atributos.xsl
Prioridad Es posible que existan diversos templates que sirvan
para procesar el mismo nodo ¿Cómo decide el procesador cuál coger?
El procesador computa un valor de prioridad (entre -0.5 y 0.5) Las reglas más específicas tienen más prioridad
P.e. match=“AAA” antes que match=“*” Si dos reglas dan la misma prioridad puede dar error el
procesador Se puede especificar valor de prioridad (mayor a más grande) <xsl:template match="CCC" priority="3">
Ejemplo Aplicar hoja de transformación ejemplo-prioridad.xsd
sobre ejemplo-base.xml Comparar resultado si se eliminan prioridades
Bucles <xsl:for-each select=“”>
Aplica patrón nodo a nodo consecutivamente del conjunto especificado con select
Ejemplo:<xsl:template match="/"> <xsl:for-each select="//BBB"> <DIV style="color:red"> <xsl:value-of select="name()"/> <xsl:text> id=</xsl:text> <xsl:value-of select="@id"/> </DIV> </xsl:for-each></xsl:template>
Ejemplo: Aplicamos ejemplo-bucle.xsl a ejemplo-base.xml
Ordenación
<xsl:sort order=“ascending|descending” select=“”>
Se pueden ordenar los nodos cuando se procesan en <xsl:for-each> y <xsl:apply-templates>
select determina por el nodo por el se ordena (típicamente “.”)
Ejemplo. Aplicamos ejemplo-orden.xsl a ejemplo-orden.xml
Vemos que los nombres salen ordenados Podemos abrirlo directamente con navegador
Condiciones <xsl:if test=“valor-booleano">
Se utiliza típicamente con <xsl:for-each> Si se verifica la condición se aplica el patrón contenido dentro
Ejemplo. Separamos una lista de valores con comas y si es el último no ponemos<xsl:template match="list"> <xsl:for-each select="entry"> <xsl:value-of select="@name"/> <xsl:if test="not (position()=last())"> <xsl:text>, </xsl:text> </xsl:if> </xsl:for-each></xsl:template>
Numeración
Dentro de un for-each podemos hacer uso de: <xsl:number/>
Nos va dando una numeración consecutiva Podemos numerar de forma múltiple de acuerdo al nivel:
Atributo level=“multiple” Podemos usar cualquier formato (p.e. letras, números
romanos, etc.) Atributo format=“i.1.A”
Ejemplo ejemplo-numeracion.xml y ejemplo-numeracion.xsl
Probar con level=“multiple” Probar distintos formatos: P.e.: “1” “a” “1.I-A”
Variables
Declaración de una variable (2 formas)<xsl:variable name=“numCapitulos"> <xsl:value-of select="count(//cap)"/></xsl:variable> <xsl:variable name=“numCapitulos“ select=“count(//cap)”>
Ámbito de variable Global Si se declara fuera de cualquier template Local Si se declara dentro de un template.
Referencia de una variable<xsl:value-of select=“$numCapitulos”/>
Ejemplo. Ficheros ejemplo-variables.xml y ejemplo-
variables.xsl
Variables (II) Copiado de fragmentos de árbol
Es posible asignar a una variable un fragmento de documento (no una cadena)<xsl:variable name=“primerCapitulo"> <xsl:copy-of select=“//cap[1]"/></xsl:variable>
<xsl:template match=“/”>...
<xsl:copy-of select=“$primerCapitulo”/>...</xsl:template>
Ejemplo. Ficheros ejemplo-copiado.xml y ejemplo-copiado.xsl
Cambiar alguno de los copy-of por value-of
Funciones Declaración de la función
<xsl:template name=“nombreFunc”> <xsl:param name=“param1”/>
<!-- Procesamiento aquí --></xsl:template>
Esta es una función template de nombre “nombreFunc” Los parámetros se referencian como si fueran variables
Llamada a la función de la función<xsl:call-template name=“nombreFunc”> <xsl:with-param name=“param1” select=“loquequeramos”/></xsl:call-template>
Los nombres de los parámetros with-param y param deben coincidir
Ejemplo. Ficheros ejemplo-funcion.xml y ejemplo-funcion.xsl
Para saber más
Todo http://www.w3.org/TR/xslt
Tutoriales http://www.w3schools.com/xsl/ http://geneura.ugr.es/~jmerelo/XSLT/
Ejercicio (1/3) Crear hoja de estilo XSLT que gane complejidad hasta que a
partir de casino.xml obtengamos el XHTML salida-casino.html Primera parte
Crear template para nodo “/” que sólo procese hijos (apply-templates)
Crear template para nodo “casino” que cree esqueleto HTML, imprima bienvenida y procese cada hijo “mesa”
Crear template para nodo “mesa” que imprima una tabla como la mostrada, con título “Mesa de juego ‘XXXX’” cada fila se procesará en base a un for-each para cada “jugador”. En cada jugador se aplicará template por cada “carta”
Crear template para “carta” se imprimirá sólo su valor entre corchetes [As].
Ejercicio (2/3)
Segunda parte Amplicar template “carta” con variable interna
“color” que en base a <xsl:choose> del palo asigne un color que se usará como parámetro para
<div style=“color:{$color}”> [As de copas] </div>
Evidentemente “As” y “copas” se extraen del elemento <carta> procesado en cuestión.
Añadir en template “mesa” la parte que suma todas las apuestas de la mesa, sacando los valores de € y $, tras la tabla. Sumar apuestas en € y $ por separado.
Ejercicio (3/3) Tercera parte
Extraer del template “mesa” la parte que imprime la tabla a un template-funcion “funcionMesa” que es llamado desde “mesa” dos veces con un parámetro “orden” que toma cada vez los valores: “ascending” “descending”
El template-funcion en función de su parámetro de entrada “orden” imprimirá una tabla con cabecera “Mesa de juego ‘XXXX' en orden ‘Ascendente|Descendente' por Jugador” Se aconseja crear variable local “textoOrden” que asocie un
valor “Ascendente” ó “Desdendente” en función del parámetro de entrada “orden”
Comprobar que la hoja XSLT sigue funcionando con casino2.xml salida-casino2.html