250 likes | 527 Views
XML. 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
E N D
XML 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 enLotusXSL 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" 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> <?xml version="1.0"?> <libro> <titulo>Sin noticias de Grub</titulo> <autor>Eduardo Mendoza</autor> </libro>
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:variablename=“numCapitulos"> <xsl:value-of select="count(//cap)"/> </xsl:variable> <xsl:variablename=“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