Lunanbay XML HowTo

These examples will concentrate primarily on Java uses of XML. A good source of information on these scripts is Mapping XML to Java from JavaSoft and the SAX Project.

There is a standard means to invoke the SAX Parser:

CLASSPATH=.:xerces.jar export CLASSPATH javac XMLMapping.java java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser XMLMapping

Note the assignment of the org.xml.sax.driver to be a particular instance of the driver, in this case org.apache.xerces.parsers.SAXParser found in xerces.jar.
The SAX Project suggest a number of alternatives here.

SAX Walker

In this example you can walk an arbitrary XML document reacting to each element therein. The following source with this test XML results in this output:

<?xml version="1.0"?> <simple date="7/7/2000"> <name> Bob </name> <location> New York </location> </simple>

A silly example as it regenerates what it was given.

XSLT

However, we can do something (probably) more useful with XSLT (from the Apache XML Project). Supposing we wanted to transform the simple piece of XML in the previous example into a really handy table in an HTML page.

Using the following straightforward XSLT templates:

<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="people"> <table border="1"> <xsl:apply-templates select="simple"/> </table> </xsl:template> <xsl:template match="simple"> <tr> <xsl:apply-templates select="name"/> <xsl:apply-templates select="location"/> </tr> </xsl:template> <xsl:template match="name"> <td> <xsl:value-of select="."/> </td> </xsl:template> <xsl:template match="location"> <td> <xsl:value-of select="."/> </td> </xsl:template> </xsl:stylesheet>

Then the following JSP snippet:

<table border=1> <% javax.xml.transform.TransformerFactory tFactory = javax.xml.transform.TransformerFactory.newInstance (); java.net.URL f_xsl = new java.net.URL ("http://www.lunanbay.com/howto/test-1.xsl"); java.net.URL f_xml = new java.net.URL ("http://www.lunanbay.com/howto/test-1.xml"); java.io.InputStream in_xsl = f_xsl.openStream (); java.io.InputStream in_xml = f_xml.openStream (); javax.xml.transform.Transformer transformer = tFactory.newTransformer ( new javax.xml.transform.stream.StreamSource (in_xsl)); transformer.transform (new javax.xml.transform.stream.StreamSource (in_xml), new javax.xml.transform.stream.StreamResult (out)); %> </table>

Note that you have to jump through a couple of hoops to keep the StreamSources happy. I found that the two calls had inconsistent behaviour: transformer.transform () would always prepend the current working directory.

You should end up with the following table:

White spaces are required between publicId and systemId.

To show what happens when you increase the number of elements where the JSP code snippet doesn't need the <table> elements as they are reproduced by the XSLT transform of the people object.

White spaces are required between publicId and systemId.