Translating
With XSLT processing, there are two high-level tasks: establishing an XSL template from which to build a transformer, and invoking the transformer on the XML document. The following list summarizes the detailed steps needed to accomplish these tasks.
Tell the system which parser you want to use for transformations. This can be done in a number of ways:
Through the javax.xml.transform.TransformFactory system property
Through the jre_dir/lib/jaxp.properties,
Through the J2EE Services API and the class specified in the META-INF/services/javax.xml.transform.TransformFactory
With a system-dependent default processor
As XSLT depends on DOM and SAX, you can tell the system which DOM and SAX parser to use for processing the document. By default, Apache Xalan-J uses the Apache Xerces-J DOM and SAX parsers.
Establish a factory in which to create transformers. Before processing an XML document, you first need to establish a TransformerFactory. The factory allows you to create different transformers for different style sheet templates.
TransformerFactory factory = TransformerFactory.newInstance();
Generate a transformer for a particular style sheet template. For each style sheet, you can generate a separate transformer to apply to multiple XML documents.
Source xsl = new StreamSource(xslStream); Templates template = factory.newTemplates(xsl); Transformer transformer = template.newTransformer();
Typically, the XSL source is a StreamSource object. You can easily convert an XSL document to a StreamSource through a File, Reader, InputStream, or URI (represented as a String) reference to the document.
Invoke the transformer to process the source document. You invoke the transformation by calling the transform method, supplying the XML source and a Result object to receive the transformed document.
Source xml = new StreamSource(xmlStream); Result result = new StreamResult(outputStream); transformer.transform(xml, result);
Similar to the XSL source, the XML source is typically a StreamSource constructed from a File, Reader, InputStream, or URI. The transformed StreamResult can be a File, Writer, OutputStream, or URI.
Listing 1 presents a class for preforming XSLT transformations of documents. As the TransformFactory system property is not set programmatically, the default Apache Xalan transformer is used. The XML and XSL source documents can be either Readers or Files, and the resulting transformed document can be a Writer or a File. The advantage of handling the documents as Readers and Writers is that they can remain in memory and can easily be processed as strings by a StringReader or CharArrayReader for the source documents and a StringWriter or CharArrayWriter for the result document. For example, a servlet could receive a database query as an XML character stream, process the input using XSLT, and deliver the result as an HTML document to a browser client. At no time do the XML document and transformed result need to reside on disk.
Listing 1XslTransformer.java. Class to perform XLST transformation of input documents using the default Apache Xalan transformer.
import javax.xml.transform.*; import javax.xml.transform.stream.*; import java.io.*; import java.util.*; /** Creates an XSLT transformer for processing an XML document. * A new transformer, along with an style template are created * for each document transformation. The XSLT, DOM, and * SAX processors are based on system default parameters. */ public class XslTransformer { private TransformerFactory factory; public XslTransformer() { factory = TransformerFactory.newInstance(); } /** Transform an XML and XSL document as <code>Reader</code>s, * placing the resulting transformed document in a * <code>Writer</code>. Convenient for handling an XML * document as a String (<code>StringReader</code>) residing * in memory, not on disk. The output document could easily be * handled as a String (<code>StringWriter</code>) or as a * <code>JSPWriter</code> in a JavaServer page. */ public void process(Reader xmlFile, Reader xslFile, Writer output) throws TransformerException { process(new StreamSource(xmlFile), new StreamSource(xslFile), new StreamResult(output)); } /** Transform an XML and XSL document as <code>File</code>s, * placing the resulting transformed document in a * <code>Writer</code>. The output document could easily * be handled as a String (<code>StringWriter</code>) or as * a <code>JSPWriter</code> in a JavaServer page. */ public void process(File xmlFile, File xslFile, Writer output) throws TransformerException { process(new StreamSource(xmlFile), new StreamSource(xslFile), new StreamResult(output)); } /** Transform an XML <code>File</code> based on an XSL * <code>File</code>, placing the resulting transformed * document in an <code>OutputStream</code>. Convenient for * handling the result as a <code>FileOutputStream</code> or * <code>ByteArrayOutputStream</code>. */ public void process(File xmlFile, File xslFile, OutputStream out) throws TransformerException { process(new StreamSource(xmlFile), new StreamSource(xslFile), new StreamResult(out)); } /** Transform an XML source using XSLT based on a new template * for the source XSL document. The resulting transformed * document is placed in the passed in <code>Result</code> * object. */ public void process(Source xml, Source xsl, Result result) throws TransformerException { try { Templates template = factory.newTemplates(xsl); Transformer transformer = template.newTransformer(); transformer.transform(xml, result); } catch(TransformerConfigurationException tce) { throw new TransformerException( tce.getMessageAndLocation()); } catch (TransformerException te) { throw new TransformerException( te.getMessageAndLocation()); } } }