Home > Articles

  • Print
  • + Share This
From the author of

Java with JAXP and Xalan

The Java example is coded in two source files: DOMAndXSLT.java is the class for the application, and a SAX error-handling class is coded in SAXErrorHandler.java. For this article, I'll assume that you already know the basics of using the DOM with JAXP and I'll just focus on the parts of the program that deal with the XSLT transformation. That code is located in lines 59–78 of Listing 5 (DOMAndXSLT.java).

Listing 5 DOMAndXSLT.java





 1 /* DOMAndXSLT.java
 2 
 3 This program illustrates basic techniques for transforming
 4 a DOM source document into a DOM result document using
 5 JAXP and Xalan.
 6 
 7 Michael C. Rawlins, 2003, for InformIT
 8
 9 */
 10
 11 // Standard libraries
 12 import java.io.*;
 13
 14 // XML packages
 15 import javax.xml.parsers.*;
 16 import javax.xml.transform.*;
 17 import javax.xml.transform.dom.*;
 18 import org.xml.sax.*;
 19 import org.xml.sax.helpers.*;
 20 import org.w3c.dom.*;
 21 import org.apache.xml.serialize.*;
 22
 23 public class DOMAndXSLT
 24 {
 25
 26 public static void main (String argv [])
 27  {
 28   // Local variables
 29   Document docSource;
 30   Document docResult;
 31   Document docXSLT;
 32   DOMSource dsSource;
 33   DOMSource dsXSLT;
 34   DOMResult drResult;
 35   OutputFormat MyOutputFormat;
 36   XMLSerializer MySerializer;
 37   FileOutputStream OutputXML;
 38
 39   System.out.println("DOM and XSLT Demonstration");
 40
 41   try
 42   {
 43    // Create a document builder factory, the builder, and load
 44    // the source document. The factory must be namespace-aware for
 45    // XSLT.
 46    DocumentBuilderFactory dFactory =
 47     DocumentBuilderFactory.newInstance();
 48    dFactory.setNamespaceAware(true);
 49    DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
 50    dBuilder.setErrorHandler(new SAXErrorHandler());
 51
 52    // Load and parse the source and stylesheet documents
 53    docSource = dBuilder.parse(new File("HelloWorld.xml"));
 54    docXSLT = dBuilder.parse(new File("HelloWorld.xsl"));
 55
 56    // Create the result document
 57    docResult = dBuilder.newDocument();
 58
 59    // Create DOMSource objects for the source document and stylesheet.
 60    // Set the base URI for the system ID so that any relative URIs can
 61    // be resolved - not needed for this constrained example, but is
 62    // good practice.
 63    dsSource = new DOMSource(docSource);
 64    dsSource.setSystemId("HelloWorld.xml");
 65    dsXSLT = new DOMSource(docXSLT);
 66    dsXSLT.setSystemId("HelloWorld.xsl");
 67
 68    // Create a DOMResult object for the result of the
 69    // transformation, and set its node to be the result Document
 70    drResult = new DOMResult(docResult);
 71
 72    // Create a transformer factory, then a transformer from the
 73    // stylesheet DOMSource
 74    TransformerFactory tFactory = TransformerFactory.newInstance();
 75    Transformer transformer = tFactory.newTransformer(dsXSLT);
 76
 77    // Perform the transformation and get the DOM result tree
 78    transformer.transform(dsSource, drResult);
 79
 80    // Save Output XML Document by creating an output stream, an
 81    // XMLSerializer, assigning the output stream to the serializer, and
 82    // setting the serializer to be a DOM serializer
 83    OutputXML = new FileOutputStream("Result.xml");
 84    MySerializer = new XMLSerializer();
 85    MySerializer.setOutputByteStream(OutputXML);
 86    MySerializer.asDOMSerializer();
 87
 88    // Create the Output Format for the Serializer for
 89    //  XML, UTF-8, and indentation true
 90    MyOutputFormat = new OutputFormat("XML","UTF-8",true);
 91    MySerializer.setOutputFormat(MyOutputFormat);
 92
 93    // Write out the document, and close the output stream
 94    MySerializer.serialize(docResult);
 95    OutputXML.flush();
 96    OutputXML.close();
 97   }
 98
 99   // General purpose catch block
100   catch (Throwable t)
101   {
102    t.printStackTrace ();
103    System.exit(1);
104   }
105
106   // Finish up
107   System.out.println("Successful Completion");
108   System.exit(0);
109  }
110 }

While MSXML supports XSLT transformations by extending the DOM Document interface with a new method, JAXP adds an entirely new interface, the "transformer" interface. A transformer object is built from a TransformerFactory in a fashion very similar to the way in which a JAXP DocumentBuilder object is produced from a DocumentBuilderFactory. The actual transformation is again a single method call, the Transformer's transform, but the arguments are the source and result documents, passed as DOMSource and DOMResult objects, respectively. The Transformer object is initialized by passing the XSLT stylesheet, also as a DOMSource object, in the newTransformer call.

As with MSXML, most of the complexity in using XSLT is in setting up for the transformation, and not in the actual method call that performs the transformation. The transform and newTransformer methods don't take DOM Documents as arguments, but instead take DOMSource or DOMResult objects. The source document and stylesheet, after being loaded as DOM Documents, are used to create DOMSource objects. This is performed in lines 59–66. Notice that after creating these objects the sample program also calls their setSystemID methods. This method is not needed in our example, but is good programming practice. It's required if either the source or stylesheet document uses relative URLs to reference other XML documents, stylesheets, entities, etc. The setSystemID enables JAXP to locate these other documents. At line 70, the DOMResult document is created from the empty result DOM Document.

Finally, in lines 72–75 we create a TransformerFactory and the Transformer object, and then perform the transformation at line 78.

If you're familiar with JAXP, you may notice that this program uses the same DocumentBuilder object to load both the source document and the stylesheet. This approach works fine if you don't need to validate the source document against a DTD or schema. However, if you need to validate, you have to create a validating DocumentBuilder for the source document and a different, non-validating but namespace-aware DocumentBuilder for the stylesheet, as stylesheets aren't normally validated against a schema.

  • + Share This
  • 🔖 Save To Your Account