MokaByte 47 - Dicembre 2000
Foto dell'autore non disponibile
di
Andrea Giovannini
XML e Java 
Trasformazione di documenti 
XML in applicazioni Java tramite XSL
XML [1] è una tecnologia molto potente per applicazioni enterprise, in particolare in campi come l'integrazione di applicazioni e il web publishing. Per poter elaborare documenti XML è spesso necessario eseguire su di essi delle trasformazioni e per questo si usa XSL (eXtensible Stylesheet Language). In questo articolo si approfondiranno XSL e il suo utilizzo con Java.

Introduzione
XSL [2] è composto da due parti
 
  • XSL Transformation (XSLT): un linguaggio per trasformare documenti XML in altri documenti. Si noti che il formato di destinazione potrebbe essere ancora XML oppure qualcosa di diverso, come ad esempio un formato grafico. In questo caso il foglio di trasformazione viene chiamato stylesheet. Questo è comunque solo un esempio dei possibili utilizzi di XSLT.
  • Formatting Objects (FO): un linguaggio per descrivere il layout del testo. Un documento XSL:FO contiene quindi delle direttive per indicare al motore di rendering come visualizzare il documento. Per maggiori informazioni si rimanda a [3].


Si osservi che trasformazione di documenti è un termine generico che comprende il mapping di un documento XML in una pagina HTML ma anche la trasformazione di un documento in uno dato schema in uno schema diverso. XSL è quindi alla base delle principali applicazioni XML, ovvero Web publishing e integrazione di applicazioni.
Un documento XSL viene elaborato da un processore, o engine, che dati in ingresso un documento XML e un documento XSL restituisce un nuovo documento XML.
 
 
 

Trasformazione di documenti XML
Si vedranno ora alcuni fondamenti di XSLT. Innanzi tutto una trasformazione XSL viene definita in un file XML come il seguente

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
...
</xsl:stylesheet>

L'intestazione del documento indica la versione di XSL utilizzata e il namespace utilizzato, ovvero si dichiara che si useranno dei tag con prefisso xsl e che la definizione di questi tag corrisponde all'URL indicato. E' necessario porre molta attenzione al namespace poiché engine XSL diversi potrebbero implementare namespace diversi e incompatibili.

XSLT è un linguaggio dichiarativo; una trasformazione viene quindi specificata con una regola che attraverso un meccanismo di pattern matching viene applicata all'elemento XML di partenza. Una regola viene espressa mediante un template:

<xsl:template match="node">
...
</xsl:template>

Quando l'engine XSL incontrerà questa regola allora ricercherà nel documento XML un elemento di nome node e ad esso applicherà la trasformazione. Per attivare la regola precedente è necessario utilizzare il comando

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

Si consideri ora il seguente documento XML

<?xml version="1.0"?>
<article>
<title>XSL and Java</title>
<author email="doe@doe.com">John Doe</author>
</article>

Per accedere al contenuto di un singolo nodo si usa il comando xsl:value-of; il contenuto del nodo title sarà quindi

<xsl:value-of select="title"/>

Il valore dell'attributo select permette molta libertà nell'accesso agli elementi. E' ad esempio possibile accedere agli attributi di un elemento usando il carattere @; il valore dell'attributo email di author è quindi

<xsl:value-of select="author/@email"/>

Si possono inoltre specificare elementi annidati ("article/author"), wildcards ("*/title") e altri pattern mediante espressioni XPath [4]. XPath è un linguaggio definito dal W3C per individuare le singole parti di un documento XML ed è al momento giunto alla versione 1.0.
Vi sono molti altri comandi in XSLT. Si possono ad esempio esprimere condizioni con i comandi xsl:choose e xsl:if. Il primo permette una scelta multipla fra diversi condizioni, analogamente allo switch in Java

<xsl:choose>
 <xsl:when test="condition1">
  ...
 </xsl:when>
 <xsl:when test="condition2">
  ...
 </xsl:when>
 <xsl:otherwise>
  ...
 </xsl:otherwise>
</xsl:choose>

mentre xsl:if permette di indicare una sola condizione e nessuna alternativa

<xsl:if test="condition">
 ...
</xsl:if>

In XSLT è inoltre possibile esprimere cicli con l'istruzione xsl:for-each:

<xsl:for-each select="pattern">
 ...
</xsl:for-each>

Web publishing con Java, XML e XSL
Si vedrà ora un esempio completo di utilizzo di XSL. Sia dato il seguente documento, un elenco di articoli

<?xml version="1.0" ?>
<articles>
 <article>
  <title>XSL and Java</title>
  <author id="1">
   <first-name>John</first-name>
   <last-name>Doe</last-name>
   <email>doe@doe.com</email>
  </author>
 </article>
 <article>
  <title>Distributed Java programming</title>
  <author id="2">
   <first-name>Tod</first-name>
   <last-name>Mann</last-name>
   <email>tod@foo.com</email>
  </author>
 </article>
 <article>
  <title>Java, XML and enterprise application integration</title>
  <author id="3">
   <first-name>Frank</first-name>
   <last-name>Kipple</last-name>
   <email>kipple@bar.com</email>
  </author>
 </article>
</articles>

Il documento precedente potrebbe essere il risultato di una query su database; per trasformarlo in una tabella HTML in modo da visualizzarla in un browser si userà il seguente documento XSL

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

 <xsl:template match="/">
  <HTML>
  <BODY>
   <TITLE>Articles' list</TITLE>
   <TABLE BORDER="1">
    <TH>Title</TH><TH>Author</TH><TH>email</TH>
    <xsl:apply-templates select="//article"/>
   </TABLE>
  </BODY>
  </HTML>
 </xsl:template>

 <xsl:template match="article">
  <TR>
   <TD><x<xsl:template match="article"></TD>
   <TD><xsl:value-of select="title"/></TD>
   <TD><xsl:value-of select="author/first-name"/>
                  <xsl:text> </xsl:text>
                  <xsl:value-of select="author/last-name"/>
             </TD>
   <TD><xsl:value-of select="author/email"/></TD>
  </TR>
 </xsl:template>

</xsl:stylesheet>

Per visualizzare la pagina HTML generata dal precedente file XSL ci sono due possibilità:
 

  • trasferire i file XML e XSL direttamente al browser, ma si tratta di una funzionalità supportata al momento solo da Internet Explorer;
  • eseguire la trasformazione sul server e mandare al browser una comune pagina HTML. In questo modo si garantisce il supporto a più browser e, parametrizzando opportunamente la trasformazione XSL, è possibile ad esempio generare codice WML per i browser WAP.


Si vuole ora realizzare come esempio un semplice Servlet che genera il codice HTML corrispondente ai file XML e XSL specificati come parametri. Il metodo doGet() del Servlet, chiamato XMLServlet, inoltrerà la richiesta al seguente metodo doXSLProcessing()

private void doXSLProcessing(HttpServletRequest request, 
             HttpServletResponse response)
             throws IOException, ServletException {

   response.setContentType("text/html");
   PrintWriter out = response.getWriter();
   try {
     // Si ottengono gli URL corrispondenti ai 
     // documenti XML e XSL specificati come parametri
     String xmlUrl = getDocURL("XML", request);
     String xslUrl = getDocURL("XSL", request);

     XSLTProcessor proc = XSLTProcessorFactory.getProcessor();

     // Si esegue la trasformazione del documento dirigendone
     // l'output sul browser
     proc.process(new XSLTInputSource(xmlUrl),
                  new XSLTInputSource(xslUrl),
                  new XSLTResultTarget(out));

   }
   catch(org.xml.sax.SAXException e) {
       out.write(e.getMessage());
   }
   finally {
     proc.reset();
   }
}

Il metodo, ottenuti gli URL del documento XML da visualizzare e del file XSL da usare per la formattazione, manda il risultato della trasformazione al browser usando Xalan, l'engine XSL dell'XML Apache Group (http://xml.apache.org). Xalan incapsula il comportamento dell'engine XSL nell'interfaccia XSLTProcessor; si osservi che in questo modo non si fa riferimento ad un'implementazione specifica. I dettagli relativi alla creazione dell'engine vengono incapsulati nella classe factory XSLTProcessorFactory. Il metodo process() di XSLTProcessor esegue la trasformazione vera e propria del documento ed ha la seguente firma

process(XSLTInputSource xmlSource, 
   XSLTInputSource xslStylesheet, 
   XSLTResultTarget resulTree) throws org.xml.sax.SAXException;

Il parametro xmlSource rappresenta il documento XML da trasformare mentre xslStylesheet è lo stylesheet XSL da usare per la trasformazione. Il documento risultato della trasformazione è rappresentato dal parametro resulTree. Le classi XSLTInputSource e XSLTResultTarget sono dei contenitori per i documenti coinvolti nella trasformazione e possono essere istanziate a partire da un URL, uno stream, un nodo DOM o un handler SAX.

Per attivare il Servlet si digita il seguente URL

http://localhost/xsl/servlet/XMLServlet?
               XML=articles.xml&XSL=list.xsl

e verrà visualizzata la seguente pagina
 
 
 

Figura 1 Risultato della trasformazione XSL applicata dal Servlet.

 

Conclusioni
La trasformazione di documenti XML è alla base delle applicazioni che vogliano sfruttare questa tecnologia. 
Il vantaggio principale di usare XSL consiste nel non dover cablare la logica di trasformazione nel codice. In questo modo è possibile apportare modifiche senza dover ricorrere a ricompilazioni dell'applicazione. Per approfondire l'utilizzo di XSL e XPath con Java si veda [5]. I sorgenti dell'esempio mostrato sono disponibili per il download.
 
 
 

Riferimenti
[1] - Specifiche W3C di XML: http://www.w3c.org/XML;
[2] - XSL: http://www.w3.org/TR/xsl;
[3] - Apache XML FOP (Formatting Objects Project): http://xml.apache.org/fop;
[4] - XPath: http://www.w3.org/TR/xpath;
[5] - André Tost; XML document processing in Java using XPath and XSLT, JavaWorld Settembre 2000, http://www.javaworld.com/jw-09-2000/jw-0908-xpath.html;

I sorgenti degli esempi si possono trovare qui

Vai alla Home Page di MokaByte
Vai alla prima pagina di questo mese


MokaByte®  è un marchio registrato da MokaByte s.r.l.
Java® è un marchio registrato da Sun Microsystems; tutti i diritti riservati
E' vietata la riproduzione anche parziale
Per comunicazioni inviare una mail a
mokainfo@mokabyte.it