|
| |
Note: This document describes the design of XSLTC's TrAX implementation.
The XSLTC TrAX API user documentation
is kept in a separate document.
The structure of this document is, and should be kept, as follows:
- A brief introduction to TrAX/JAXP
- Overall design of the XSLTC TrAX implementation
- Detailed design of various TrAX components
|
| |
The Java API for XML Processing (JAXP) includes an XSLT framework based
on the Transformation API for XML (TrAX). A JAXP transformation application
can use the TrAX framework in two ways. The simplest way is:
- create an instance of the TransformerFactory class
- from the factory instance and a given XSLT stylesheet, create a new
Transformer object
- call the Transformer object's transform() method, specifying the XML
input and a Result object.
| | | |
import javax.xml.transform.*;
public class Compile {
public void run(Source xsl) {
....
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xsl);
....
}
} | | | | |
This suits most conventional XSLT processors that transform XML documents
in one go. XSLTC needs one extra step to compile the XSL stylesheet into a
Java class (a "translet"). Fortunately TrAX has another approach
that suits XSLTC two-step transformation model:
- create an instance of the TransformerFactory class
- from the factory instance and a given XSLTC, stylesheet, create a new
Templates object (this step will compile the stylesheet and put the
bytecodes for translet class(es) into the Templates object)
- from the Template object create a Transformer object (this will
instanciate a new translet object).
- call the Transformer object's transform() method, specifying the XML
input and a Result object.
| | | |
import javax.xml.transform.*;
public class Compile {
public void run(Source xsl) {
....
TransformerFactory factory = TransformerFactory.newInstance();
Templates templates = factory.newTemplates(xsl);
Transformer transformer = templates.newTransformer();
....
}
} | | | | |
Note that the first two steps need be performed only once for each
stylesheet. Once the stylesheet is compiled into a translet and wrapped in a
Templates object, the Templates object can be used
over and over again to create Transformer object (instances of the translet).
The Templates instances can even be serialized and stored on
stable storage (ie. in a memory or disk cache) for later use.
The code below illustrates a simple JAXP transformation application that
creates the Transformer directly. Remember that this is not the
ideal approach with XSLTC, as the stylesheet is compiled for each
transformation. | | | |
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
public class Proto {
public void run(String xmlfile, String xslfile) {
Transformer transformer;
TransformerFactory factory = TransformerFactory.newInstance();
try {
StreamSource stylesheet = new StreamSource(xslfile);
transformer = factory.newTransformer(stylesheet);
transformer.transform(new StreamSource(xmlfile),
new StreamResult(System.out));
}
catch (Exception e) {
// handle errors...
}
:
:
} | | | | |
This approach seems simple is probably used in many applications. But, the
use of Templates objects is useful when multiple instances of
the same Transformer are needed. Transformer
objects are not thread safe, and if a server wants to handle several clients
requests it would be best off to create one global Templates
object, and then from this create a Transformer object for each
thread handling the requests. This approach is also by far the best for
XSLTC, as the Templates object will hold the class definitions
that make up the translet and its auxiliary classes. (Note that the bytecodes
and not the actuall class definitions are stored when serializing a
Templates object to disk. This is because of class loader
security restrictions.) To accomodate this second approach to TrAX
transformations, the above class would be modified as follows: | | | |
try {
StreamSource stylesheet = new StreamSource(xslfile);
Templates templates = factory.newTemplates(stylesheet);
transformer = templates.newTransformer();
transformer.transform(new StreamSource(inputFilename),
new StreamResult(System.out));
}
catch (Exception e) {
// handle errors...
} | | | | |
|
|
|