Last week, the Apache XML group released version 2 of Xalan-Java (http://xml.apache.org/xalan-j/index.html). Xalan takes a fundamental approach to the general problem of transformation. Traditionally, transformation has been thought of application of an XSLT stylesheet to an XML document and retrieving a resulting XML document. In actual practice however, transformation is a more complex issue. For one thing, XSLT is not the only transformation tool. For various reasons, including performance, some programmers choose strict code based transformations using languages like Java or Perl. Sometimes the transformation needs to occur between different representations of an XML document like a SAX event stream or a DOM model.
So while the fundamental transformation problem is the same (i.e., going from A to B), the manner in which it is implemented is different. Xalan 2 provides a transformation framework that is independent of the parser and transformer implementations. This framework is called TrAX (Transformation API for XML) and is also part of JAXP effort from Sun. Several abstract notions make up the framework. A tree is some representation of an XML document. Transformation instructions describe the actual transformation. This is not limited to XSLT. A transformer is then responsible for applying the transformation instructions to a source tree and producing a result tree.
Let’s look at some of the specifics. In order to decouple the abstract notion of transformation from an implementation, we use a TranfrormFactory.
javax.xml.transform.TranformerFactory tranFactory = javax.xml.tranform.TransformerFactory.newInstance();
We can now use the factory to retrieve an instance of Transformer which can transform a source tree into a result tree given some instructions. This will give us the engine that will be responsible for applying the transformation rules.
javax.xml.transform.Transformer transformer = tranFactory.newTransformer(new javax.xml.transform.stream.StreamSource("somefile.xsl"));
The final step would be to do the actual transformation. We are using an StreamSource as the source tree. We could have used DOMSource or SAXSource. The transformation output (result tree) is put abstractly in a StreamResult and physically in a file. Other choices would have been a DOMResult or a SAXResult.
transformer.transform(new StreamSource("source.xml"), new StreamResult(new FileOutputStream("result.xml")));
A nice feature of Xalan is that using system properties, you can plug in different DOM and SAX parsers and different transformer processors (e.g., XSLT processors, etc.) This plugability feature is part of the Java API for XML Parsing (JAXP) under review by JavaSoft and most likely will be supported by other parsers as well.
By supporting a SAXSource and SAXResult, Xalan can do incremental transformations. Recall that the SAX API uses an event model to parse an XML document. These events can be acted upon and transformed as they arise. It would be interesting to examine the performance benefits of this approach.