Ciclo Formativo de Grado Superior en Administración y de Sistemas Informáticos en Red IES Valle del Cidacos – Calahorra Lenguajes de Marcas y Sistemas Gestores de Información © Enrique Rivas Marco Usted es libre de: Compartir — copiar y redistribuir el material en cualquier medio o formato Adaptar — remezclar, transformar y crear a partir del material El licenciador no puede revocar estas libertades mientras cumpla con los términos de la licencia. Bajo las condiciones siguientes: Reconocimiento — Debe reconocer adecuadamente la autoría, proporcionar un enlace a la licencia e indicar si se han realizado cambios<. Puede hacerlo de cualquier manera razonable, pero no de una manera que sugiera que tiene el apoyo del licenciador o lo recibe por el uso que hace. NoComercial — No puede utilizar el material para una finalidad comercial. CompartirIgual — Si remezcla, transforma o crea a partir del material, deberá difundir sus contribuciones bajo la misma licencia que el original. No hay restricciones adicionales — No puede aplicar términos legales o medidas tecnológicas que legalmente restrinjan realizar aquello que la licencia permite. 1 eXtensible Stylesheet Language for Transformations, XSLT. 1. Introducción a XSLT ......................................................................................................... 3 2. Aplicar al documento XML una hoja de estilos XSLT ................................................. 8 3. <xsl:template>.................................................................................................................... 9 4. <xsl:value-of>................................................................................................................... 10 5. <xsl:apply-templates> .................................................................................................... 11 6. <xsl:apply-templates> y <xsl:value-of> ....................................................................... 11 7. <xsl:sort> .......................................................................................................................... 13 8. Sólo la plantilla raíz <xsl:for-each> .............................................................................. 15 9. Estructuras condicionales <xsl:if>...................................................................................... 15 10. <xsl:choose> / <xsl:when> / <xsl:otherwise>............................................................. 16 11. Generar contenido <xsl:text> ........................................................................................ 17 12. <xsl:element> / <xsl:attribute> ...................................................................................... 17 13. XSLT En el cliente con JavaScript ............................................................................... 18 14. XSLT en el servidor con PHP ........................................................................................ 19 15. Convertir XML en PDF utilizando XSL-FO y FOP....................................................... 20 Bloque 1 de ejercicios XSLT ......................................................................................................... 24 Bloque 2 de ejercicios XSLT ......................................................................................................... 25 Bloque 3 de ejercicios XSLT ......................................................................................................... 27 16. Bibliografía.................................................................................................................................. 29 2 1. Introducción a XSLT XSLT (eXtensible Stylesheet Language for Transformations) es un lenguaje que permite aplicar una transformación a un documento XML para obtener otro documento XML, un documento HTML o un documento de texto plano. La hoja de estilos XSLT con las reglas de transformación es también un documento de texto XML en sí, generalmente con extensión .xsl, por lo que se podrá comprobar si está bien formado o no. • XSLT es el lenguaje de hojas de estilo recomendado de XML. • XSLT es mucho más sofisticado que el CSS. • XSLT puede ser utilizado para transformar documentos XML en HTML, antes de ser mostrados en un navegador. • XSLT usa XPath para encontrar información en un documento XML. XPath se utiliza para navegar a través de elementos y atributos en documentos XML. El funcionamiento lo podemos observar en la siguiente imagen: A un documento XML se le pueden aplicar una o varias transformaciones XSLT e incluso una transformación CSS. No debemos confundir las transformaciones XSLT con la presentación de documentos XML con CSS. Con XSLT, generaremos un documento HTML a partir de un documento XML. Con CSS, el navegador recibe un documento XML que formatea utilizando las reglas CSS para presentarlo en pantalla de forma que sea más fácilmente legible, pero es el mismo documento. Las hojas de estilos XSLT son más útiles que las hojas de estilos CSS porque: • Permiten cambiar el orden los elementos. • Permiten realizar operaciones con sus valores. • Permiten agrupar elementos. De ahí que se suelan utilizar en combinación más que decantarse por una u otra hoja de estilos. 3 Ejemplo inicial: <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="ej1.xsl"?> <catalog> <cd> <title>Empire Burlesque</title> <artist>Bob Dylan</artist> <country>USA</country> <company>Columbia</company> <price>10.90</price> <year>1985</year> </cd> <cd> <title>Hide your heart</title> <artist>Bonnie Tyler</artist> <country>UK</country> <company>CBS Records</company> <price>9.90</price> <year>1988</year> </cd> <cd> <title>Greatest Hits</title> <artist>Dolly Parton</artist> <country>USA</country> <company>RCA</company> <price>9.90</price> <year>1982</year> </cd> <cd> <title>Still got the blues</title> <artist>Gary Moore</artist> <country>UK</country> <company>Virgin records</company> <price>10.20</price> <year>1990</year> </cd> <cd> <title>Eros</title> <artist>Eros Ramazzotti</artist> <country>EU</country> <company>BMG</company> <price>9.90</price> <year>1997</year> </cd> <cd> <title>One night only</title> <artist>Bee Gees</artist> <country>UK</country> <company>Polydor</company> <price>10.90</price> <year>1998</year> </cd> <cd> <title>Sylvias Mother</title> <artist>Dr.Hook</artist> <country>UK</country> <company>CBS</company> <price>8.10</price> <year>1973</year> </cd> <cd> <title>Maggie May</title> 4 <artist>Rod Stewart</artist> <country>UK</country> <company>Pickwick</company> <price>8.50</price> <year>1990</year> </cd> <cd> <title>Romanza</title> <artist>Andrea Bocelli</artist> <country>EU</country> <company>Polydor</company> <price>10.80</price> <year>1996</year> </cd> <cd> <title>When a man loves a woman</title> <artist>Percy Sledge</artist> <country>USA</country> <company>Atlantic</company> <price>8.70</price> <year>1987</year> </cd> <cd> <title>Black angel</title> <artist>Savage Rose</artist> <country>EU</country> <company>Mega</company> <price>10.90</price> <year>1995</year> </cd> <cd> <title>1999 Grammy Nominees</title> <artist>Many</artist> <country>USA</country> <company>Grammy</company> <price>10.20</price> <year>1999</year> </cd> <cd> <title>For the good times</title> <artist>Kenny Rogers</artist> <country>UK</country> <company>Mucik Master</company> <price>8.70</price> <year>1995</year> </cd> <cd> <title>Big Willie style</title> <artist>Will Smith</artist> <country>USA</country> <company>Columbia</company> <price>9.90</price> <year>1997</year> </cd> <cd> <title>Tupelo Honey</title> <artist>Van Morrison</artist> <country>UK</country> <company>Polydor</company> <price>8.20</price> <year>1971</year> </cd> <cd> <title>Soulsville</title> 5 <artist>Jorn Hoel</artist> <country>Norway</country> <company>WEA</company> <price>7.90</price> <year>1996</year> </cd> <cd> <title>The very best of</title> <artist>Cat Stevens</artist> <country>UK</country> <company>Island</company> <price>8.90</price> <year>1990</year> </cd> <cd> <title>Stop</title> <artist>Sam Brown</artist> <country>UK</country> <company>A and M</company> <price>8.90</price> <year>1988</year> </cd> <cd> <title>Bridge of Spies</title> <artist>T`Pau</artist> <country>UK</country> <company>Siren</company> <price>7.90</price> <year>1987</year> </cd> <cd> <title>Private Dancer</title> <artist>Tina Turner</artist> <country>UK</country> <company>Capitol</company> <price>8.90</price> <year>1983</year> </cd> <cd> <title>Midt om natten</title> <artist>Kim Larsen</artist> <country>EU</country> <company>Medley</company> <price>7.80</price> <year>1983</year> </cd> <cd> <title>Pavarotti Gala Concert</title> <artist>Luciano Pavarotti</artist> <country>UK</country> <company>DECCA</company> <price>9.90</price> <year>1991</year> </cd> <cd> <title>The dock of the bay</title> <artist>Otis Redding</artist> <country>USA</country> <company>Atlantic</company> <price>7.90</price> <year>1987</year> </cd> <cd> <title>Picture book</title> 6 <artist>Simply Red</artist> <country>EU</country> <company>Elektra</company> <price>7.20</price> <year>1985</year> </cd> <cd> <title>Red</title> <artist>The Communards</artist> <country>UK</country> <company>London</company> <price>7.80</price> <year>1987</year> </cd> <cd> <title>Unchain my heart</title> <artist>Joe Cocker</artist> <country>USA</country> <company>EMI</company> <price>8.20</price> <year>1987</year> </cd> </catalog> <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th style="text-align:left">Title</th> <th style="text-align:left">Artist</th> </tr> <xsl:for-each select="catalog/cd"> <tr> <td><xsl:value-of select="title"/></td> <td><xsl:value-of select="artist"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> 7 En otros ejemplos vamos a tomar como referencia el siguiente documento XML: <?xml version="1.0" encoding="UTF-8"?> <bib url="http://www.ticarte.com"> <book id="1"> <title>TCP/IP Illustrated</title> <author>Stevens</author> <publisher>Addison-Wesley</publisher> <year>2002</year> </book> <book id="2"> <title>Advanced Programming in the Unix Environment</title> <author>Stevens</author> <publisher>Addison-Wesley</publisher> <year>2004</year> </book> <book id="3"> <title>Data on the Web</title> <author>Abiteboul</author> <author>Buneman</author> <author>Suciu</author> <year>2006</year> </book> </bib> Para diseñar hojas de estilos XSLT podemos utilizar el software libre XML Copy Editor. Para probarlo sólo tenemos que abrir el documento XML en el navegador Mozilla Firefox o Internet Explorer para ver el resultado de la transformación. El navegador Google Chrome por defecto no aplica las transformaciones. En el navegador podemos utilizar la opción del botón derecho "Inspeccionar elemento" para comprobar los resultados de la transformación, ya que si elegimos "Ver código fuente" se nos abrirá el documento XML original sin ninguna transformación. 2. Aplicar al documento XML una hoja de estilos XSLT • Incluir la referencia a la hora de estilos en el documento xml: <?xml-stylesheet type="text/xsl" href="ej1.xsl"?> • Una hoja de estilo XSLT es un documento XML. Debe estar bien formado. • Deben comenzar con una declaración XML: <?xml version="1.0"?> • El elemento raíz de la hoja de estilo XSLT es <xsl:stylesheet... • Este elemento contendrá a todos los demás, y va precedido por el alias xsl correspondiente al espacio de nombres para hojas de estilo XSLT. La estructura básica de un documento XSLT es la que se muestra a continuación: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> </xsl:stylesheet> 8 En este caso, al no contener ninguna regla de transformación, todos los nodos se enviarán por defecto a la salida de la transformación. 3. <xsl:template> Se utiliza para construir plantillas, cada regla se define con un elemento <xsl:template>. El atributo match se utiliza para asociar la plantilla a un elemento XML. El atributo match también puede usarse para definir una plantilla para todo el documento XML (eje. Match = "/" define todo el documento). El valor del atributo match es una expresión XPath: Expresión Descripción nombrenodo Selecciona todos los nodos secundarios del nodo “nombrenodo” / Selecciona la raíz del documento // Selecciona los nodos en el documento desde el nodo actual que coincidan con la selección sin importar donde se encuentren . Selecciona el nodo actual .. Selecciona el padre del nodo actual @ Selecciona atributos La hoja de estilos debe tener al menos una plantilla que suele corresponder con el nodo raíz, aunque puede ser de otro nodo. Si esta plantilla no contiene nada, como en el siguiente ejemplo, no se enviará nada como salida de la transformación: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> </xsl:template> </xsl:stylesheet> Si no hay plantillas, el procesador simplemente extrae el texto contenido por los nodos. <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> </xsl:stylesheet> Si hay una plantilla vacía, el procesador sustituye el nodo y todos sus subelementos por nada y no extrae el texto contenido por ese nodo o sus subelementos. Lo normal es que tengamos más plantillas, una para cada nodo de nuestro documento XML. 9 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th>Title</th> <th>Artist</th> </tr> <tr> <td>.</td> <td>.</td> </tr> </table> </body> </html> </xsl:template> </xsl:stylesheet> Explicación: El elemento <xsl:template> define una plantilla. El atributo match="/" asocia la plantilla con la raíz del documento XML de origen. El contenido dentro de la etiqueta <xsl:template> define contenido HTML para escribir a la salida. Las dos últimas líneas definen el final de la plantilla y el final de la hoja de estilo. El resultado de este ejemplo fue un poco decepcionante, ya que no hay datos que se copien del documento XML a la salida. Ahora veremos cómo utilizar el <xsl:value-of> para seleccionar los valores de los elementos XML. 4. <xsl:value-of> Puede ser utilizado para extraer el valor de un elemento XML y añadirlo a la cadena de salida de la transformación: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0"> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th>Title</th> <th>Artist</th> </tr> <tr> <td><xsl:value-of select="catalog/cd/title"/></td> <td><xsl:value-of select="catalog/cd/artist"/></td> </tr> </table> </body> </xsl:template> </xsl:stylesheet> 10 5. <xsl:apply-templates> Utilizaremos la etiqueta <xsl:apply-templates> para mostrar en una plantilla la transformación de otra. Prestar atención a los atributos que se utilizan, en <xsl:template> se utiliza "match" y en <xsl:apply-templates> se utiliza "select". En el siguiente ejemplo la plantilla raíz transformará cada nodo "book" de su interior por su plantilla. Hay que ver como las plantillas <xsl:template> utilizan rutas XPath absolutas para identificar los nodos a los que hacen referencia, pero <xsl:apply-templates> utilizará, normalmente, rutas XPath relativas al nodo de contexto en el que se esté llamando. Este ejemplo aún no muestra nada en la salida. <!-- Plantilla raíz --> <xsl:template match="/"> <xsl:apply-templates select="bib/book" /> </xsl:template> <!-- Plantilla book --> <xsl:template match="/bib/book"> </xsl:template> 6. <xsl:apply-templates> y <xsl:value-of> En el interior de una plantilla podemos utilizar la etiqueta <xsl:value-of> para imprimir el valor que contiene el nodo, utilizando expresiones XPath para acceder a ellas. Tomaremos como nodo contexto el nodo en el que estamos trabajando o estamos posicionados actualmente. El ejemplo anterior lo podemos modificar mostrando en la plantilla "book" el contenido del nodo "title", para mostrar todos los títulos de los libros: <!-- Plantilla raíz --> <xsl:template match="/"> <xsl:apply-templates select="bib/book" /> </xsl:template> <!-- Plantilla book --> <xsl:template match="/bib/book"> <xsl:value-of select="title" /> </xsl:template> En el ejemplo anterior hemos mostrado el valor del nodo "title" desde "book", pero podemos crear también una nueva plantilla para el nodo "title" y que dicha plantilla muestre directamente su valor de la siguiente manera. Mirar de nuevo cómo se utilizan las rutas absolutas y relativas en Xpath. <!-- Plantilla raíz--> <xsl:template match="/"> <xsl:apply-templates select="bib/book" /> </xsl:template> <!-- Plantilla book --> 11 <xsl:template match="/bib/book"> <xsl:apply-templates select="title" /> </xsl:template> <!-- Plantilla title --> <xsl:template match="/bib/book/title"> <xsl:value-of select="." /> </xsl:template> Si una plantilla lo único que tiene es mostrar el valor de su nodo se podría eliminar, obteniéndose el mismo resultado. En el siguiente ejemplo eliminamos la plantilla del nodo "title" y aún así el resultado es el mismo que el ejemplo anterior: <!-- Plantilla raíz --> <xsl:template match="/"> <xsl:apply-templates select="bib/book" /> </xsl:template> <!-- Plantilla book --> <xsl:template match="/bib/book"> <xsl:apply-templates select="title" /> </xsl:template> También se puede utilizar <xsl:apply-templates> sin seleccionar ningún nodo concreto, de esa manera se aplicarán todas las plantillas que existan para los nodos que se recorran. Si en el ejemplo anterior no utilizamos "select" dentro de la plantilla "book" se mostrará por salida todos los datos de los nodos que contenga dentro "book", existan o no sus plantillas. <!-- Plantilla raíz --> <xsl:template match="/"> <xsl:apply-templates select="bib/book" /> </xsl:template> <!-- Plantilla book --> <xsl:template match="/bib/book"> <xsl:apply-templates /> </xsl:template> <!-- Plantilla title --> <xsl:template match="/bib/book/title"> <xsl:value-of select="." /> </xsl:template> Los atributos también pueden transformarse creándoles una plantilla como vemos en el siguiente ejemplo: <!-- Plantilla raíz --> <xsl:template match="/"> <xsl:apply-templates select="bib/book" /> </xsl:template> <!-- Plantilla book --> <xsl:template match="/bib/book"> <xsl:apply-templates select="@id" /> </xsl:template> <!-- Plantilla atributo id --> 12 <xsl:template match="/bib/book/@id"> <xsl:value-of select="." /> </xsl:template> Otro ejemplo: <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="cd"> <p> <xsl:apply-templates select="title"/> <xsl:apply-templates select="artist"/> </p> </xsl:template> <xsl:template match="title"> Title: <span style="color:#ff0000"> <xsl:value-of select="."/></span> <br /> </xsl:template> <xsl:template match="artist"> Artist: <span style="color:#00ff00"> <xsl:value-of select="."/></span> <br /> </xsl:template> </xsl:stylesheet> 7. <xsl:sort> Se puede ordenar la salida de los nodos de una plantilla mediante la etiqueta <xsl:sort> situándola dentro de las etiquetas <xsl:apply-templates>. Los siguientes atributos se pueden utilizar con ella: • lang: "language-code". • data-type: "text | number | qname". • order: "ascending | descending". • case-order: "upper-first | lower-first". <!-- Plantilla bib --> <xsl:template match="/bib"> <ul> <xsl:apply-templates select="book"> <xsl:sort select="title" order="ascending" /> </xsl:apply-templates> </ul> </xsl:template> 13 <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th>Title</th> <th>Artist</th> </tr> <xsl:for-each select="catalog/cd"> <xsl:sort select="artist"/> <tr> <td><xsl:value-of select="title"/></td> <td><xsl:value-of select="artist"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> Ejemplo completo En el siguiente ejemplo más completo utilizaremos las plantillas para transformar el documento XML a una lista con formato HTML donde cada elemento de la lista sea el nombre del libro y el año de publicación entre paréntesis, situando el código HTML en sus plantillas correspondientes: <!-- Plantilla raíz --> <xsl:template match="/"> <html> <head> </head> <body> <xsl:apply-templates select="bib" /> </body> </html> </xsl:template> <!-- Plantilla bib --> <xsl:template match="/bib"> <ul> <xsl:apply-templates select="book" /> </ul> </xsl:template> <!-- Plantilla book --> <xsl:template match="/bib/book"> <li> <xsl:apply-templates select="title" /> <xsl:apply-templates select="year" /> </li> </xsl:template> <!-- Plantilla title --> <xsl:template match="/bib/book/title"> <xsl:value-of select="." /> </xsl:template> <!-- Plantilla year --> <xsl:template match="/bib/book/year"> (<xsl:value-of select="." />) </xsl:template> 14 8. Sólo la plantilla raíz <xsl:for-each> El mismo ejemplo anterior se puede realizar utilizando solamente la plantilla raíz y haciendo uso de la etiqueta <xsl:for-each>, que permite pasar por todos los nodos seleccionados, como si se tratara de un bucle "for" en programación: <!-- Plantilla raíz --> <xsl:template match="/"> <html> <head> </head> <body> <xsl:for-each select="bib"> <ul> <xsl:for-each select="book"> <li> <xsl:value-of select="title" /> </li> </xsl:for-each> </ul> </xsl:for-each> </body> </html> </xsl:template> 9. Estructuras condicionales <xsl:if> <xsl:if test="expression"> ...some output if the expression is true... </xsl:if> La etiqueta <xsl:if> permite introducir una condición en la transformación mediante una condición evaluada mediante XPath en el atributo "test". Pero tan simple que no admite ni siquiera la opción "else". Hay que tener en cuenta que para utilizar los operadores "mayor que" y "menor que" hay reemplazarlos por su carácter codificado en HTML. • Mayor que: &gt; • Menor que: &lt; <!-- Plantilla year --> <xsl:template match="/bib/book/year"> <xsl:if test=". &gt; 2000"> <strong><xsl:value-of select="." /></strong> </xsl:if> <xsl:if test=". &lt; 2000"> <xsl:value-of select="." /> </xsl:if> </xsl:template> 15 Otro ejemplo: <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th>Title</th> <th>Artist</th> <th>Price</th> </tr> <xsl:for-each select="catalog/cd"> <xsl:if test="price &gt; 10"> <tr> <td><xsl:value-of select="title"/></td> <td><xsl:value-of select="artist"/></td> <td><xsl:value-of select="price"/></td> </tr> </xsl:if> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> 10. <xsl:choose> / <xsl:when> / <xsl:otherwise> La estructura "choose" es similar al "switch" de los lenguajes de programación, permitiendo condiciones consecutivas: <xsl:choose> <xsl:when test="expression"> ... some output ... </xsl:when> <xsl:otherwise> ... some output .... </xsl:otherwise> </xsl:choose> <!-- Plantilla year --> <xsl:template match="/bib/book/year"> <xsl:choose> <xsl:when test=". &gt; 2000"> <strong><xsl:value-of select="." /></strong> </xsl:when> <xsl:when test=". &gt; 2000"> <em><xsl:value-of select="." /></em> </xsl:when> <xsl:otherwise> <xsl:value-of select="." /> </xsl:otherwise> </xsl:choose> </xsl:template> 16 Otro ejemplo: <xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th>Title</th> <th>Artist</th> </tr> <xsl:for-each select="catalog/cd"> <tr> <td><xsl:value-of select="title"/></td> <xsl:choose> <xsl:when test="price > 10"> <td bgcolor="#ff00ff"> <xsl:value-of select="artist"/> </td> </xsl:when> <xsl:otherwise> <td><xsl:value-of select="artist"/></td> </xsl:otherwise> </xsl:choose> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> 11. Generar contenido <xsl:text> En algunas ocasiones necesitaremos texto literal en la salida, por ejemplo espacios en blanco para separar valores. En este caso utilizaremos la etiqueta <xsl:text> con su código correspondiente: <!-- Plantilla year --> <xsl:template match="/bib/book/year"> (<xsl:text>&#10;</xsl:text> <xsl:value-of select="." /> <xsl:text>&#10;</xsl:text>) </xsl:template> 12. <xsl:element> / <xsl:attribute> Cuando tengamos que crear nodos nuevos en el documento de salida, con su etiquetas y atributos necesitaremos utilizar las etiquetas <xsl:element> y <xsl:attribute> para poder utilizar los valores del XML origen en dichos nodos. En el siguiente ejemplo crearemos enlace mediante HTML, es decir, una etiqueta "a" con el atributo "href" utilizando el atributo "url" del nodo "bib": <!-- Pantilla bib --> <xsl:template match="/bib"> 17 <xsl:element name="a"> <xsl:attribute name="href"> <xsl:value-of select="@url" /> </xsl:attribute> Visita la bibioteca </xsl:element> <ul> <xsl:apply-templates select="book" /> </ul> </xsl:template> 13. XSLT En el cliente con JavaScript Hasta ahora hemos transformado xml enlazando una hoja de transformación xsl, con la etiqueta <?xml-stylesheet type="text/xsl" href="ej1.xsl"?>, una solución más versátil sería usar un JavaScript para hacer la transformación: <html> <head> <script> function loadXMLDoc(filename) { if (window.ActiveXObject) { xhttp = new ActiveXObject("Msxml2.XMLHTTP"); } else { xhttp = new XMLHttpRequest(); } xhttp.open("GET", filename, false); try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11 xhttp.send(""); return xhttp.responseXML; } function displayResult() { xml = loadXMLDoc("cdcatalog.xml"); xsl = loadXMLDoc("cdcatalog.xsl"); // code for IE if (window.ActiveXObject || xhttp.responseType == "msxml-document") { ex = xml.transformNode(xsl); document.getElementById("example").innerHTML = ex; } // code for Chrome, Firefox, Opera, etc. else if (document.implementation && document.implementation.createDocument) { xsltProcessor = new XSLTProcessor(); xsltProcessor.importStylesheet(xsl); resultDocument = xsltProcessor.transformToFragment(xml, document); document.getElementById("example").appendChild(resultDocument); } } </script> </head> 18 <body onload="displayResult()"> <div id="example" /> </body> </html> Ahora el documento xml no tiene que tener la referencia a la hoja de transformación xsl, la función de JavaScript se encarga de enlazarlos y mostrar la transformación. 14. XSLT en el servidor con PHP Para que los datos XML sean compatibles con todos los navegadores, podemos transformar el documento XML en el servidor y enviar de vuelta al navegador como XHTML. <?php // Load XML file $xml = new DOMDocument; $xml->load('cdcatalog.xml'); // Load XSL file $xsl = new DOMDocument; $xsl->load('cdcatalog.xsl'); // Configure the transformer $proc = new XSLTProcessor; // Attach the xsl rules $proc->importStyleSheet($xsl); echo $proc->transformToXML($xml); ?> 19 15. Convertir XML en PDF utilizando XSL-FO y FOP XSL-FO, un lenguaje de formateo, que no es más que un vocabulario XML para especificar objetos de formateo (FO). Mediante los objetos de formateo (Formatting Objects -FO-) y sus propiedades podemos describir cómo se van a visualizar los componentes de un documento. Con estos objetos definimos: • Las características de la página. • Los párrafos. • Las listas. • Las tablas. • Los enlaces. • Etc. Ejemplo: <?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master master-name="simple" page-height="29.7cm" page-width="21cm" margin-top="1cm" margin-bottom="2cm" margin-left="2.5cm" margin-right="2.5cm"> <fo:region-body margin-top="3cm"/> <fo:region-before extent="3cm"/> <fo:region-after extent="1.5cm"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="simple"> <fo:flow flow-name="xsl-region-body"> <fo:block font-size="20pt" font-family="arial" line-height="20pt" space-after.optimum="15pt" text-align="center" padding-top="3pt"> Ejemplo de XSL-FO </fo:block> <fo:block font-size="14pt" font-family="sans-serif" line-height="14pt" space-after.optimum="3pt" text-align="justify"> 20 Seguimos con el ejemplo de XSL-FO, una vez visto xsl, estaremos familiarizados con los lenguajes de trasnsformación. </fo:block> </fo:flow> </fo:page-sequence> </fo:root> El FOP (Formatting Object to PDF) es el primer procesador de objetos de formateo XSL que aparecio. Empezó a ser desarrollada en solitario por James Tauber pero posteriormente se incorporó al "Apache XML Project" lo que está acelerando su desarrollo. Es una aplicación en Java por lo que para poder utilizarla el único requisito necesario es tener instalado la máquina virtual Java. Instalacion fop en linux sudo apt-get install fop En Windows ir a https://xmlgraphics.apache.org/fop/ descargar la distribución binaria y descomprimir. Podemos probar con el archivo fo anterior "fop -fo prueba.fo -pdf prueba.pdf" creará un pdf con el contenido especificado: Propiedades y regiones de la página • Mediante el atributo page-width establecemos el ancho de la página. • Mediante el atributo page-height establecemos el alto de la página. • Podemos establecer los márgenes de la página con los atributos margin-top, margin-bottom, margin-left y margin-right. • Las regiones que forman la página son: • fo:region-body Cuerpo de la página • fo:region-before Encabezado • fo:region-after Pie de página • fo:region-start Margen izquierdo • fo:region-end. Margen derecho 21 • El atributo extent da la altura de las regiones before y after, y la anchura para start y end. • Para la región body no podemos usar extend, usamos margin. Ejemplo: <fo:layout-master-set> <fo:simple-page-master master-name='plantilla' page-width='8.5in' page-height='11in' margin-top='0.5in' margin-bottom='0.5in' margin-left='0.5in' margin-right='0.5in'> <fo:region-start extent='1.0in'/> <fo:region-before extent='1.0in'/> <fo:region-body margin='1.0in'/> <fo:region-end extent='1.0in'/> <fo:region-after extent='1.0in'/> </fo:simple-page-master> </fo:layout-master-set> Las imágenes y sus atributos Los formatos soportados son: .gif, .jpg, .svg y .png Se insertan imágenes con el elemento fo:external-graphic, de la siguiente manera: <fo:external-graphic src='cup.gif'/> El enlace a la imagen puede ser tanto relativo como absoluto. Generalmente lo que interesa es generar un documento PDF a partir de un documento XML, lo vemos en el siguiente ejemplo: Sea nombres.xml un archivo en siguiente contenido: <?xml version="1.0" encoding="UTF-8"?> <names> <name>enrique</name> <name>pedro</name> <name>paz</name> </names> Para crear un archivo PDF a partir de este archivo XML, se necesita una XSLT que convierta el XML a XSL-FO. Este es el primer paso in la cadena de procesos. El segundo paso será dado por FOP cuando lea el documento XSL-FO generado y lo convierta en un documento PDF: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="A4-portrait" page-height="29.7cm" page-width="21.0cm" margin="2cm"> <fo:region-body/> </fo:simple-page-master> 22 </fo:layout-master-set> <fo:page-sequence master-reference="A4-portrait"> <fo:flow flow-name="xsl-region-body"> <xsl:for-each select="names/name"> <fo:block> Hello, <xsl:value-of select="."/>! </fo:block> </xsl:for-each> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> </xsl:stylesheet> La siguiente orden ejecuta los dos pasos anteriores en línea de comandos: fop -xml name.xml -xsl namefo.xsl -pdf name.pdf Es posible dar formato de salida, veamos otra versión del ejemplo anterior: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/names"> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="A4-portrait" page-height="29.7cm" page-width="21.0cm" margin="2cm"> <fo:region-body/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="A4-portrait"> <fo:flow flow-name="xsl-region-body"> <xsl:apply-templates/> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> <xsl:template match="name"> <fo:block font-size="2em" color="red" font-weight="bold" backgroundcolor="blue" margin="10px" padding="20px"> Hello, <xsl:value-of select="."/>! </fo:block> </xsl:template> </xsl:stylesheet> 23 Bloque 1 de ejercicios XSLT <?xml version="1.0" encoding="UTF-8"?> <ies nombre="IES Francisco de los Rios" web="http://www.iesfranciscodelosrios.es" > <ciclos> <ciclo id="ASIR"> <nombre>Administración de Sistemas Informáticos en Red</nombre> <grado>Superior</grado> <decretoTitulo año="2009" /> </ciclo> <ciclo id="DAW"> <nombre>Desarrollo de Aplicaciones Web</nombre> <grado>Superior</grado> <decretoTitulo año="2010" /> </ciclo> <ciclo> <nombre>Desarrollo de Aplicaciones Multiplataforma</nombre> <grado>Superior</grado> <decretoTitulo año="2010" /> </ciclo> <ciclo id="SMR"> <nombre>Sistemas Microinformáticos y Redes</nombre> <grado>Medio</grado> <decretoTitulo año="2008" /> </ciclo> </ciclos> </ies> Dado el anterior documento XML y utilizando una plantilla (template) para cada nodo del mismo que se necesite transformar, realiza las siguientes transformaciones XSLT: • Mostrar los nombres de los ciclos sin etiquetas. • Mostrar en párrafos cada uno de los nombres de los ciclos. • Mostrar en una lista sin numerar los nombres de los ciclos ordenados, y entre paréntesis su grado. • Mostrar en una etiqueta H1 el nombre del instituto y luego en una tabla con su fila encabezado las siguientes columnas, nombre del ciclo y año. Si el año es mayor al 2009 la letra será de color verde, si es igual al 2009 de color azul y si es menor al 2009 de color rojo. Generar un documento PDF con los datos del documento XML. 24 Bloque 2 de ejercicios XSLT <?xml version="1.0" encoding="UTF-8"?> <bib url="http://www.uco.es/servicios/biblioteca/"> <libro año="1994"> <titulo>TCP/IP Illustrated</titulo> <autor> <apellido>Stevens</apellido> <nombre>W.</nombre> </autor> <editorial>Addison-Wesley</editorial> <precio>65.95</precio> </libro> <libro año="1992"> <titulo>Advan Programming for Unix environment</titulo> <autor> <apellido>Stevens</apellido> <nombre>W.</nombre> </autor> <editorial>Addison-Wesley</editorial> <precio>65.95</precio> </libro> <libro año="2000"> <titulo>Data on the Web</titulo> <autor> <apellido>Abiteboul</apellido> <nombre>Serge</nombre> </autor> <autor> <apellido>Buneman</apellido> <nombre>Peter</nombre> </autor> <autor> <apellido>Suciu</apellido> <nombre>Dan</nombre> </autor> <editorial>Morgan Kaufmann editorials</editorial> <precio>39.95</precio> </libro> <libro año="1999"> <titulo>Economics of Technology for Digital TV</titulo> <editor> <apellido>Gerbarg</apellido> <nombre>Darcy</nombre> <afiliacion>CITI</afiliacion> </editor> <editorial>Kluwer Academic editorials</editorial> <precio>129.95</precio> </libro> </bib> Dado el anterior documento XML y utilizando una plantilla (template) para cada nodo del mismo que se necesite transformar, realiza las siguientes transformaciones XSLT: • Mostrar una tabla con las siguientes columnas ordenadas por el título del libro: 1. Título del libro, en color rojo si el precio es mayor de 100, añadiéndole el texto "(Caro)" a continuación. 25 2. Autores del libro mostrando primero el nombre y luego el apellido. Si hay más de un autor se muestran todos en la misma celda. Si no hay autor se deja en blanco. 3. Editores del libro mostrando el nombre, el apellido y la afiliación. Si hay más de un editor se muestran todos en la misma celda. Si no hay editor se deja en blanco. • Mostrar una tabla con las siguientes columnas: 1. Precio del libro, ordenando los resultados por este campo (Nota: se ordenan como si fueran cadenas y no números). 2. Título del libro. Se mostrará el fondo de la celda en color rojo si el precio es mayor de 100. 3. Año de publicación. Se mostrará el texto en cursiva. • Mostrar una lista enumerada con todos los autores ordenados por apellidos. • Mostrar una lista enumerada con todos los títulos de libros cuyo precio sea menor de 100. 26 Bloque 3 de ejercicios XSLT <catalogo> <artistas> <artista id="uno"> <nombre>Carlos Jean</nombre> <nacionalidad>España</nacionalidad> </artista> <artista id="dos"> <nombre>Miguel Rios</nombre> <nacionalidad>España</nacionalidad> </artista> <artista id="tres"> <nombre>La Mala</nombre> <nacionalidad>España</nacionalidad> </artista> <artista id="cuatro"> <nombre>Etta James</nombre> <nacionalidad>USA</nacionalidad> </artista> </artistas> <discograficas> <discografica id="uno"> <nombre>Motown</nombre> <nacionalidad>USA</nacionalidad> </discografica> <discografica id="dos"> <nombre>Subterfuge</nombre> <nacionalidad>España</nacionalidad> </discografica> <discografica id="tres"> <nombre>Sony</nombre> <nacionalidad>USA</nacionalidad> </discografica> </discograficas> <cds> <cd autor="uno" disc="dos"> <titulo>Bad Jean</titulo> <precio>15</precio> <año>2000</año> </cd> <cd autor="dos" disc="tres"> <titulo>Rock and Rios</titulo> <precio>12</precio> <año>1982</año> </cd> <cd autor="tres" disc="tres"> <titulo>Malamarismo</titulo> <precio>10.90</precio> <año>2008</año> </cd> <cd autor="cuatro" disc="uno"> <titulo>At last</titulo> <precio>13</precio> <año>1979</año> </cd> <cd autor="cuatro" disc="uno"> <titulo>Chess soul sisters</titulo> <precio>16</precio> <año>1980</año> </cd> <cd autor="dos" disc="dos"> <titulo>Michael Rios</titulo> 27 <precio>10</precio> <año>1973</año> </cd> <cd autor="uno" disc="dos"> <titulo>Party Stereo</titulo> <precio>13</precio> <año>2009</año> </cd> <cd autor="tres" disc="tres"> <titulo>Dirty Bailarina</titulo> <precio>13</precio> <año>1979</año> </cd> </cds> </catalogo> Dado el anterior documento XML y utilizando una plantilla (template) para cada nodo del mismo que se necesite transformar, realiza las siguientes transformaciones XSLT: • Mostrar una lista con los autores españoles. • Mostrar una tabla con el nombre del disco en verde si el año es posterior al 2000, y en rojo si el año es anterior al 2000. Generar un documento PDF con los datos del archivo XML 28 16. Bibliografía • Sintes Marco, Bartolomé. "Qué es el XML" y "XPath" del curso "XML: Lenguaje de Marcas Extensible Licencia". Licencia CC BY-CN-SA. http://www.mclibre.org/ • Rafa Morales, educación, ciclos formativos, Lenguaje de marcas y sistemas de gestión de la información. ". Licencia CC BY-CN-SA. http://www.ticarte.com/ • Taboada León Juan José. “Convertir XML en PDF utilizando XSL-FO y FOP”. Licencia CC BY-CN-SA. http://docencia.taboadaleon.es/2015-02-13-07-38- 06/convertir-xml-en-pdf.html • w3schools.com, “XSLT Tutorial”. http://www.w3schools.com/xsl/default.asp 29