Tema 5: JSP y XML

Si Java es el lenguaje portable por excelencia e independiente de la máquina, XML representa el equivalente a Java en cuanto a almacenamiento de datos. Ser capaz de almacenar datos estructurados, pero en formato de "texto plano" nos da la posibilidad de almacenar información compleja de manera portable. Esta capacidad se usa en muchos lugares: por ejemplo como formato de exportación/importación de bases de datos, como formato para ficheros de configuración en toda la plataforma J2EE, o como lenguaje de definición de páginas web. Es en este último contexto donde mejor podemos combinar la capacidad de procesamiento de JSP con la portabilidad de XML. No obstante, JSP y XML se pueden combinar de diversos modos en aplicaciones web.

5.1. Usos de JSP y XML

Caben diversas posibilidades a la hora de combinar JSP con XML. Algunas de ellas son:

J2EE nos proporciona dos herramientas fundamentales para conseguir estos fines:

5.2. Procesamiento de JSP y XML con JAXP

Se trata de utilizar código Java que llame al API JAXP para procesar el XML. Como se ve en el módulo de XML y Java de este curso, JAXP permite procesar documentos XML (reorganizarlos, filtrarlos, cambiar su estructura) mediante los APIs estándar SAX y DOM y además aplicar hojas de estilo XSLT para transformarlos a cualquier formato.

En el contexto de una aplicación web, que es donde vamos a usar JSP, el código Java puede ejecutarse en el servidor, on line en cada petición HTTP (mediante un filtro) o bien off-line.

5.2.1. Usar el XML para conseguir independencia del cliente

Como ejemplo, podéis bajaros la aplicación MiniamazonXML en formato WAR (la "diminuta" tienda web de discos y libros pero ahora desarrollada en JSP con XML en lugar de HTML). Un ejemplo de página de MiniamazonXML es la página de datos de un producto, masinfo.jsp:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<jsp:useBean id="prod" class="beans.prodBean"/>
<producto>
   <titulo>
      <jsp:getProperty name="prod" property="titulo"/>
   </titulo>
   <% for (int i=0; i<prod.getNumAutores(); i++) { %>
      <autor>
         <jsp:setProperty name="prod" property="numAutor" value="<%=i%>"/>
         <jsp:getProperty name="prod" property="autor"/>
      </autor>
   <% } %>
   <descripcion>
      <jsp:getProperty name="prod" property="descripcion"/>
   </descripcion>
</producto>

Obsérvese que la página no es un documento XML bien formado, por "culpa" del código Java que contiene. Como ya hemos visto en el tema 3, el código de la página se podría eliminar utilizando etiquetas JSTL, aunque en algunos casos extremos no habrá forma de evitarlo. No obstante, esto no importa, porque antes de procesar el XML con JAXP lo procesará el contenedor JSP (en nuestro caso Tomcat) que "eliminará" el código Java, dejando únicamente XML.

Si se visualiza la página de algún producto desde el navegador, introduciendo en la URL

http://localhost:8080/miniamazonxml/main?accion=masinfo&cod=0001

se obtendrá el documento XML perteneciente al producto solicitado. El Explorer muestra el documento en forma de árbol, mientras que otros navegadores, como Netscape, muestran simplemente el texto sin las etiquetas.

Para obtener el documento en otros formatos (por ejemplo HTML) necesitamos una hoja de estilo XSLT y un proceso que la aplique. En MiniamazonXML hay implementado un filtro (la clase FiltroXML, ver el fichero de configuración de la aplicación) que postprocesa el resultado devuelto por el contenedor JSP aplicándole una hoja de estilo XSLT. El filtro se activa si en el resultado devuelto por Tomcat aparece una instrucción de procesamiento denominada xslt. A esta instrucción se le debe poner como parámetro el nombre de la hoja de estilo a aplicar y el nombre del navegador ante el que hay que aplicar la hoja (recordemos que los navegadores se identifican mediante la cabecera HTTP User-Agent). Por ejemplo:

<? xslt cliente="Mozilla" xsl="masinfo-html.xsl" ?>

Volved a probar la solicitud HTTP anterior introduciendo esta línea en el fichero XML y comprobar el resultado. El navegador recibirá el código HTML producto de la transformación del documento original XML. Desarrollando distintas plantillas XSLT podemos ofrecer distintos formatos a distintos clientes web (navegadores, PDAs, móviles WAP,...).

5.3. Procesamiento de XML con la librería JSTL

Como ya se ha visto en el tema 3, JSTL dispone de etiquetas para procesamiento de documentos XML. De este modo no es necesario programar código Java para trabajar con XML, sino que se puede hacer más fácilmente con etiquetas.

Las etiquetas dedicadas a XML están divididas en tres grupos, atendiendo a la función que cumplen:

Función Etiquetas
Core

out

parse

set

Control de flujo

forEach

choose

   when
   otherwise

if

Transformación

transform

param

 

Como se ve, la mayoría de etiquetas core y de control de flujo tienen el mismo nombre que en las otras áreas de JSTL. La razón es que tienen la misma función, aunque orientada a XML. La diferencia principal es el soporte de expresiones XPath.

5.3.1. Etiquetas Core

Estas etiquetas proporcionan las funcionalidades básicas para analizar XML y acceder a nodos dentro del documento.

La etiqueta parse analiza el documento XML especificado con el atributo xml y guarda el resultado en la variable especificada por el atributo var. Por ejemplo:

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
<%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Ejemplo de parse</title>
</head>
<body>
<c:set var="discos">
<disco>
<titulo> O sea </titulo>
<interprete> Enrique Iglesias </interprete>
</disco>
</c:set>
<x:parse var="analizado" xml="${discos}" /> <!-- sacar el título --> título disco: <x:out select="$analizado//titulo"/>
<!-- meter el título en una variable para sacarlo con c:out --> <x:set var="tit" select="string($analizado//titulo)"/>
título disco: <c:out value="${tit}"/> <br>
</body>
</html>

Primero metemos un "documento XML" empotrado en la página web en la variable discos (podríamos haberlo tomado de una URL cualquiera con un c:import). Luego analizamos el documento con parse, y a partir de este momento podemos acceder a cualquiera de sus nodos con una expresión XPath.

La etiqueta x:out toma una expresión XPath (un conjunto de nodos), la convierte a String automáticamente y la inserta en la salida. La etiqueta x:set es el equivalente a c:set, pero admite expresiones XPath.

5.3.2. Etiquetas de control de flujo

Como en el caso anterior, su característica principal es que admiten expresiones XPath. Como ejemplo, veremos el uso de la etiqueta forEach, las otras son similares.

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Ejemplo de x:forEach</title>
</head>
<body>
<c:set var="discos">
<discos>
<disco>
<titulo> O sea </titulo>
<interprete> Enrique Iglesias </interprete>
</disco>
<disco>
<titulo> Money for Nothing </titulo>
<interprete> Dire Straits </interprete>
</disco>
</discos>
</c:set>

<h2> Titulos del mes </h2>
<x:parse xml="${discos}" var="analizado"/>
<x:forEach var="tit" select="$analizado//titulo">
<x:out select="$tit"/> <br>
</x:forEach>
</body>
</html>

Como se ve, es equivalente a un c:forEach, solo que admite expresiones XPath en el atributo select.

5.3.3. Etiquetas de transformación

la etiqueta transform aplica una plantilla XSLT. Por ejemplo, suponiendo que hubiéramos definido el documento XML "empotrado" discos del ejemplo anterior, podríamos añadir el siguiente código:

...

...
<c:set var="hojaxsl">
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="titulo">
<br/> <b> <xsl:value-of select="."/> </b> <br/>
</xsl:template>
</xsl:stylesheet>
</c:set> <x:transform xml="${discos}" xslt="${hojaxsl}"/>