TrAX (Transformation API for XML)

What is TrAX (Transformation API for XML) ?

TrAX is an API for transforming XML documents using XSLT style sheets. TrAX is a Java API and has been defined to provide common access to different XSLT Processors. TrAX is part of the JAXP API, which combines a number of Java APIs.

The TrAX API extends the original JAXP mission to include XML transformations: provide a vendor and implementation agnostic standard Java API for specifying and executing XML transformations. This is important to note, because TrAX is more than just a standard interface for XSLT engines – it is designed to be used as a general-purpose transformation interface for XML documents.

TrAX is not a competitor to the existing DOM and SAX APIs used to represent and process XML, but a common Java API to bridge the various XML transformation methods (JDBC, JNDI, etc.) including SAX Events and XSLT Templates. In fact, TrAX relies upon a SAX2- and DOM-level-2-compliant XML parser/XSLT engine. JAXP 1.0 allows the developer to change XML parsers by setting a property, and TrAX provides the same functionality for XSLT engines.

How to apply XSLT stylesheet to an XML document and write the results to an HTML file using TrAX ?
1. create the XML content input source:
//can be a DOM node, SAX stream, or any Java input stream/reader

String xmlInputFile = "news.xml";
Source xmlSource = new StreamSource(new FileInputStream(xmlInputFile));

2. create the XSLT Stylesheet input source
//can be a DOM node, SAX stream, or a java input stream/reader

String xsltInputFile = "news.xsl";
Source xsltSource = new StreamSource(new FileInputStream(xsltInputFile));

3. create the result target of the transformation
//can be a DOM node, SAX stream, or a java out stream/reader

String xmlOutputFile = "news.html";
Result transResult = new StreamResult(new FileOutputStream(xmlOutputFile));

4. create the transformerfactory and transformer instance

TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer(xsltSource);

5. execute transformation and fill result target object

t.transform(xmlSource, transResult);

The first three steps simply establish our inputs and output targets. Notice that the XSLT stylesheet is not handled via a different class in TrAX but, it is treated just like any other XML source document. We use the stream implementations of the Source and Result interfaces from the javax.xml.transform.stream package to handle reading the data from our file streams.

In the fourth step, we use the TransformerFactory to get an instance of a Transformer, and then use the Source instance for the XSLT stylesheet we created in the second step to define the transformation that this transformer will perform. A Transformer actually executes the transformation and assembles the result. A single Transformer instance can be reused, but it is not thread-safe.

In this example, the XSLT stylesheet is reprocessed for each successive transformation. A very common case is that the same transformation is applied multiple times to different Sources, perhaps in different threads. A more efficient approach in this case is to process the transformation stylesheet once, and save this object for successive transformations. This is achieved through the use of the TrAX Templates interface:

// we’ve already set up our content Source instance,
// XSLT Source instance, TransformerFactory, and
// Result target from the previous example
// process the XSLT stylesheet into a Templates instance
// with our TransformerFactory instance

Templates t = tf.newTemplates(xsltSource);

// whenever you need to execute this transformation, create
// a new Transformer instance from the Templates instace

Transformer trans = t.newTransformer();

// execute transformation and fill result target object

trans.transform(xmlSource, transResult);

While the Transformer performs the transformation, a Templates instance is the actual run-time representation of the processed transformation instructions. Templates instances may be reused to increase performance, and they are thread-safe. It might seem odd that an interface has a plural name, but it stems from the fact that an XSLT stylesheet consists of a collection of one or more xsl:template elements. Each template element defines a transformation in that stylesheet, so it follows that the simplest name for a representation of a collection of template elements is Templates.

One of the main reasons the TrAX API is so clean and simple is the Interface-driven approach to design. The highest-level interfaces define the essential entities that are being modeled, and the interactions are left to the implementations. The interfaces themselves aren’t very interesting. They are essentially marker interfaces.

What is Source interface in TrAX ?

The Source interface is a generic container for existing XML documents that will be used in a transformation as either the input document or the stylesheet. Serve as a single vendor-neutral object for multiple types of input. Implementations of the Source interface provide access to the XML document to be processed. TrAX defines Source implementations for DOM trees (DOMSource); SAX 2.0 InputSources (SAXSource); and Java InputStreams, Readers and any of their derived classes (StreamSource).

package javax.xml.transform;
public interface Source {
    public void setSystemId(String systemId);
    public String getSystemId();
}

What is Result interface in TrAX ?

The Result interface is a generic container for an XML document that will be produced by a transformation. Serve as a single object for multiple types of output, so there can be simple process method signatures. Implementations of the Result interface provide access to the transformed XML document. TrAX defines Result implementations for DOM trees (DOMResult); SAX 2.0 ContentHandlers (SAXResult); and Java OutputStreams, Writers and any of their derived classes (StreamResult).

package javax.xml.transform;
public interface Result  {
  public static final String PI_DISABLE_OUTPUT_ESCAPING;
  public static final String PI_ENABLE_OUTPUT_ESCAPING;
  public void setSystemId(String url);
  public String getSystemId();
}

What is Templates interface in TrAX ?

Templates is a thread-safe interface that represents a compiled stylesheet. It can quickly create new Transformer objects without having to reread and reparse the original stylesheet. It’s particularly useful when you want to use the same stylesheet in multiple threads. The runtime representation of the transformation instructions. A template implementation is the optimized, in-memory representation of an XML transformation that is processed and ready to be executed. Templates objects are safe to use in concurrent threads. To reuse a single Template instance in multiple concurrent threads, multiple Transformer instances would have to be created via the Templates.newTransformer() factory method. Each Transformer instance may be used completely independently in concurrent threads, and both the Templates and the Transformer instances can be reused for subsequent transformations.

package javax.xml.transform;
public interface Templates  {
  public Transformer newTransformer() throws TransformerConfigurationException;
  public Properties  getOutputProperties();
}

What is Transformer in TrAX ?

Transformer is the abstract class that represents a compiled stylesheet. It transforms Source objects into Result objects. A single Transformer can transform multiple input documents in sequence but not in parallel. Act as a per-thread execution context for transformations, act as an interface for performing the transformation. A Transformer is the object that actually applies the transformation to the source document and creates the result document. However, it is not responsible for outputting, or serializing, the result of the transformation. This is the responsibility of the transformation engine’s serializer and this behavior can be modified via the setOutputProperty(java.lang.String name, java.lang.String value) method. The configurable OutputProperties are defined in the OutputKeys class, and are described in the XSLT 1.0 Specification. Transformers are immutable, they cannot change which Templates instance gets applied to the Source.

package javax.xml.transform;
public abstract class Transformer  {
  protected Transformer();
  public void transform(Source input, Result output) throws TransformerException;
  public void setParameter(String name, Object value);
  public Object getParameter(String name);
  public void clearParameters();
  public void setURIResolver(URIResolver resolver);
  public URIResolver getURIResolver();
  public void setOutputProperties(Properties serialization) throws IllegalArgumentException;
  public Properties getOutputProperties();
  public void setOutputProperty(String name, String value) throws IllegalArgumentException;
  public String getOutputProperty(String name) throws IllegalArgumentException;
  public void setErrorListener(ErrorListener listener) throws IllegalArgumentException;
  public ErrorListener getErrorListener();
}

What is TransformerFactory in TrAX ?

A TransformerFactory instance can be used to create Transformer and Templates objects. The system property that determines which Factory implementation to create is named “javax.xml.transform.TransformerFactory”. The concrete subclass that newInstance() instantiates is specified by the javax.xml.transform.TransformerFactory Java system property. If this class is not set, a platform dependent default class is chosen. Serve as a vendor-neutral Processor interface for XSLT and similar processors. The TransformerFactory is primarily responsible for creating new Transformers and Templates objects. New instances of Transformer are created via the static newTransformer() method. Processing Source instances into Templates objects is handled by the newTemplates(Source source) method.

package javax.xml.transform;
public abstract class TransformerFactory  {
  protected TransformerFactory();
  public static TransformerFactory newInstance() throws TransformerFactoryConfigurationError;
  public Transformer newTransformer(Source source) throws TransformerConfigurationException;
  public Transformer newTransformer() throws TransformerConfigurationException;
  public Templates   newTemplates(Source source) throws TransformerConfigurationException;
  public Source getAssociatedStylesheet(Source source, String media, String title, String charset)
     throws TransformerConfigurationException;
  public void setURIResolver(URIResolver resolver);
  public URIResolver getURIResolver();
  public boolean getFeature(String name);
  public void setAttribute(String name, Object value) throws IllegalArgumentException;
  public Object getAttribute(String name) throws IllegalArgumentException;
  public void setErrorListener(ErrorListener listener) throws IllegalArgumentException;
  public ErrorListener getErrorListener();
}