JAXP supports XSLT with packages javax.xml.transform and subpackages. A transformation operates on a source and obtains a result. Both source and result can be of three types:
Actually, the transform package can be exploited in two ways: to transform the representation of the same XML document from one form (such as SAX) to another (such as DOM), or, to transform the content of an XML document using an XSLT stylesheet. In both cases, the following steps must be followed:
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(stylesheet);where stylesheet is an XSLT document (version 1.0) in some source form (stream, SAX, DOM). You may also get a transformer with no associated stylesheet in case you want to transform the same XML document from one data representation to another (identity transformation):
Transformer transformer = factory.newTransformer();
transformer.setErrorListener(handler);
transformer.transform(input, output);
For example, the following program XMLTrans perform an XSLT transformation of an XML document into the standard output:
import java.io.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; public class XMLTrans { static final String usage = "Syntax: java XMLTrans document.xml stylesheet.xsl"; public static void main(String[] args) { if (args.length != 2) { System.out.println(usage); System.exit(1); } // get source and result objects for input, stylesheet, and output StreamSource input = new StreamSource(new File(args[0])); StreamSource stylesheet = new StreamSource(new File(args[1])); StreamResult output = new StreamResult(System.out); /* or use: StreamResult output = new StreamResult(new File(filename)); to save the result in a file */ // create a transformer factory TransformerFactory factory = null; try { factory = TransformerFactory.newInstance(); } catch (TransformerFactoryConfigurationError tfce) { // the implementation is not available or cannot be instantiated System.err.println(tfce.getMessage()); System.exit(1); } // get a transformer for the stylesheet Transformer transformer = null; try { transformer = factory.newTransformer(stylesheet); } catch (TransformerConfigurationException tce) { // the transformer cannot be created System.err.println(tce.getMessage()); System.exit(1); } // set an error listener transformer.setErrorListener(new TransHandler()); // perform the transformation try { transformer.transform(input, output); } catch (TransformerException te) { // do nothing since an error handler has been installed } } }
The error listener TransHandler is implemented as follows:
import javax.xml.transform.*; /* Implements ErrorListener with methods to catch transformation warnings, errors and fatal errors */ public class TransHandler implements ErrorListener { public String relativeSystemID(String id) { if (id != null) { int index = id.lastIndexOf('/'); if (index != -1) { id = id.substring(index + 1); } } return id; } public void printError(String type, TransformerException te) { SourceLocator locator = te.getLocator(); if (locator != null) { System.err.print("[" + type + "] "); System.err.print(relativeSystemID(locator.getSystemId())); System.err.print(":" + locator.getLineNumber() + ":" + locator.getColumnNumber() + ": " + te.getMessage()); } else { System.err.print("[" + type + "] "); System.err.print(te.getMessageAndLocation()); } System.err.println(); System.err.flush(); } // A warning message. The program continues. public void warning(TransformerException te) throws TransformerException { printError("warning", te); } // A transformation error. The program decides to exit. public void error(TransformerException te) throws TransformerException { printError("error", te); System.exit(1); } // A transformation fatal error. The program must exit. public void fatalError(TransformerException te) throws TransformerException { printError("fatal error", te); System.exit(1); } }
The following code uses an identity transformer to switch form different representations of the same XML document. First, an XML file is read into a SAX source. The SAX source is then converted into a DOM result, which is finally transformed into a stream of XML text. The final result is not surprising: the input document is simply printed on the standard output. However, the code is interesting because it teaches how to use transformations to move between different forms of the same document:
import java.io.*; import javax.xml.transform.*; import javax.xml.transform.stream.*; import javax.xml.transform.dom.*; import javax.xml.transform.sax.*; import org.xml.sax.*; import org.w3c.dom.*; public class XMLTrans2 { public static void main(String[] args) throws TransformerException { // create an identity transformer TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); // create a SAX source from an XML document SAXSource saxInput = new SAXSource(new InputSource(args[0])); // create a DOM result DOMResult domOutput = new DOMResult(); // transform SAX representation into DOM representation transformer.transform(saxInput, domOutput); // obtain the document node of the DOM result Document document = (Document) domOutput.getNode(); // create a DOM source from a node DOMSource domInput = new DOMSource(document); // create a stream result (the standard output) StreamResult streamOutput = new StreamResult(System.out); // transform DOM representation into stream representation transformer.transform(domInput, streamOutput); } }