DOM and XSL

Java based XML applications may use XSL style sheets for processing. A DOM tree may for example be transformed into another tree. The package javax.xml.transform provides interfaces and classes for this purpose. We consider the following product catalog example:

Figure 769. A simplified XML product catalog Slide presentation Create comment in forum
<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="catalog.xsd">
  <title>Outdoor products</title>
  <introduction>
    <para>We offer a great variety of basic stuff for mountaineering
          such as ropes, harnesses and tents.</para>
    <para>Our shop is proud for its large number of available
      sleeping bags.</para>
  </introduction>
  <product id="x-223">
    <title>Multi freezing bag  Nightmare camper</title>
    <description>
      <para>You will feel comfortable till  minus 20 degrees - At
            least if you are a penguin or a polar bear.</para>
    </description>
  </product>
  <product id="r-334">
    <title>Rope 40m</title>
    <description>
      <para>Excellent for indoor climbing.</para>
    </description>
  </product>
</catalog>

A corresponding schema file catalog.xsd is straightforward:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified"
   vc:minVersion="1.0" vc:maxVersion="1.1">

   <xs:simpleType name="money">
      <xs:restriction base="xs:decimal">
         <xs:fractionDigits value="2"/>
      </xs:restriction>
   </xs:simpleType>

   <xs:element name="title" type="xs:string"/>
   <xs:element name="para" type="xs:string"/>

   <xs:element name="description" type="paraSequence"/>
   <xs:element name="introduction" type="paraSequence"/>

   <xs:complexType name="paraSequence">
      <xs:sequence>
         <xs:element ref="para" minOccurs="1" maxOccurs="unbounded"/>
      </xs:sequence>
   </xs:complexType>

   <xs:element name="product">
      <xs:complexType>
         <xs:sequence>
            <xs:element ref="title"/>
            <xs:element ref="description"/>
         </xs:sequence>
         <xs:attribute name="id" type="xs:ID" use="required"/>
         <xs:attribute name="price" type="money" use="optional"/>
      </xs:complexType>
   </xs:element>

   <xs:element name="catalog">
      <xs:complexType>
         <xs:sequence>
            <xs:element ref="title"/>
            <xs:element ref="introduction"/>
            <xs:element ref="product" minOccurs="1" maxOccurs="unbounded"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>

</xs:schema>

A XSL style sheet may be used to transform this document into the HTML Format:

Figure 770. A XSL style sheet for catalog transformation to HTML. Slide presentation Create comment in forum
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0" xmlns="http://www.w3.org/1999/xhtml">

  <xsl:template match="/catalog">
    <html>
      <head><title><xsl:value-of select="title"/></title></head>
      <body style="background-color:#FFFFFF">
        <h1><xsl:value-of select="title"/></h1>
        <xsl:apply-templates select="product"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="product">
    <h3><xsl:value-of select="title"/></h3>
    <xsl:for-each select="description/para">
      <p><xsl:value-of select="."/></p>
    </xsl:for-each>
    <xsl:if test="price">
      <p>
        <xsl:text>Price:</xsl:text>
        <xsl:value-of select="price/@value"/>
      </p>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

As a preparation for the section called “Generating HTML from both XML and relational input data” we now demonstrate the usage of XSL within a Java application. This is done by a Transformer instance:

Figure 771. Transforming an XML document instance to HTML by a XSL style sheet. Slide presentation Create comment in forum
package dom.xsl;
...
public class Xml2Html {
   private final SAXBuilder builder = new SAXBuilder();

   final XSLTransformer transformer;

  public Xml2Html(final String xslFilename) throws XSLTransformException {
     builder.setErrorHandler(new MySaxErrorHandler(System.err));
     transformer =  new XSLTransformer(xslFilename);
  }
  public void transform(final String xmlInFilename,
      final String resultFilename) throws JDOMException, IOException {

    final Document inDoc = builder.build(xmlInFilename);
    Document result = transformer.transform(inDoc);

    // Set formatting for the XML output
    final Format outFormat = Format.getPrettyFormat();

    // Serialize to console
    final XMLOutputter printer = new XMLOutputter(outFormat);
    printer.output(result.getDocument(), System.out);

  }
}

A corresponding driver file is needed to invoke a transformation:

Figure 772. A driver class for the xml2xml transformer. Slide presentation Create comment in forum
package dom.xsl;
...
public class Xml2HtmlDriver {
...
  public static void main(String[] args) {
    final String
     inFilename = "Input/Dom/climbing.xml",
     xslFilename = "Input/Dom/catalog2html.xsl",
     htmlOutputFilename = "Input/Dom/climbing.html";
    try {
      final Xml2Html converter = new Xml2Html(xslFilename);
      converter.transform(inFilename, htmlOutputFilename);
    } catch (Exception e) {
      System.err.println("The conversion of '" + inFilename
          + "' by stylesheet '" + xslFilename
          + "' to output HTML file '" + htmlOutputFilename
          + "' failed with the following error:" + e);
      e.printStackTrace();
    }
  }
}