Programmatic Invocation of the XSLT Processor
The XSLT processor exposes two Java classes that you need to use to perform an XSL transformation: XSLProcessor and XSLStylesheet. An XSLStylesheet object holds all information about an XSLT stylesheet, such as its templates, keys, variables, and attribute sets. This object, once constructed, can be used multiple times to apply the same transformation to a variety of XML documents. It can also be “tweaked” periodically by setting suitable stylesheet parameter values from the outside.
The following code demonstrates how the XSLT APIs could be used:
import java.util.*;
import java.io.*;
import java.net.*;
import org.w3c.dom.*;
import oracle.xml.parser.v2.*;
/**
* This is a simple example of how to use the XSL processing
* capabilities of the Oracle XML Parser V2.0. An input XML document
* is transformed using a given input stylesheet
*/
public class XSLExample {
public static void main (String args[]) throws Exception {
DOMParser parser;
XMLDocument xmldoc, xsldoc, out;
FileInputStream xmlstream, xslstream;
try {
// Create an instance of the DOMParser
parser = new DOMParser();
parser.setPreserveWhitespace(true);
// parse input XML file
xmlstream = new FileInputStream(args[0]);
parser.parse(xmlstream);
xmldoc = parser.getDocument();
// parse input XSL file
xslstream = new FileInputStream(args[1]);
parser.parse(xslstream);
xsldoc = parser.getDocument();
// instantiate a stylesheet
XSLStylesheet xsl = processor.newXSLStylesheet(xsldoc);
// Apply stylesheet
XSLProcessor processor = new XSLProcessor();
XMLDocumentFragment result =
processor.processXSL(xsl, xmldoc);
// print the transformed document
result.print(System.out);
} catch (Exception e) {
e.printStackTrace();
}
}
}
The preceding example is fairly straightforward. It accepts as input, the XML input file, and the XSL stylesheet to apply. The first thing you need to do is to parse these using the DOMParser and to retrieve the roots of their respective DOM trees:
// Create an instance of the DOMParser
parser = new DOMParser();
parser.setPreserveWhitespace(true);
// parse input XML file
xmlstream = new FileInputStream(args[0]);
parser.parse(xmlstream);
xmldoc = parser.getDocument();
// parse input XSL file
xslstream = new FileInputStream(args[1]);
parser.parse(xslstream);
xsldoc = parser.getDocument();
The important thing to note is that the new parser is explicitly configured to preserve whitespace (by default, it is not unless a DTD is present). This is crucial, as it allows XSLT whitespace rules to determine how white space should be dealt with.
The next step is to construct a stylesheet object:
// instantiate a stylesheet
XSLStylesheet xsl = processor.newXSLStylesheet(xsldoc);
This example, being extremely simple, assumes that the input stylesheet does not reference anything external, such as included stylesheets, external entities, and so forth. Only in such a case can you get away with passing a null as the second argument to the XSLStylesheet constructor. Otherwise, you need to create a URL to serve as a reference point for resolving external references within the stylesheets.
The next step is to create a new XSLProcessor and use it to apply the stylesheet on the input XML document:
// Apply stylesheet
XSLProcessor processor = new XSLProcessor();
DocumentFragment result = processor.processXSL(xsl, xml);
The transformed output is now available to you as a document fragment, which can be further manipulated using the regular DOM APIs. For the sake of simplicity, this example prints the results:
// print the transformed document
result.print(System.out);
A simple yet powerful stylesheet is the identity stylesheet:
<?xml version="1.0"?>
<!–– Identity transformation ––>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*|@*|comment()|processing-instruction()|text()">
<xsl:copy>
<xsl:apply-templates select="*|@*|comment()|processing-
instruction()|text()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
If you apply this stylesheet to any XML document, you get the same document back. You can test the preceding example by passing it a reference to a file containing the identity stylesheet and (say) the booklist example from Chapter 2. The output generated would be as expected:
<booklist>
<book isbn="0-07-213495-X">
<title>Oracle9i XML Handbook</title>
<author>Chang, Scardina and Kiritzov</author>
<publisher>Osborne</publisher>
<price>49.99</price>
</book>
<book isbn="1230-23498-2349879">
<title>Emperor's New Mind</title>
<author>Roger Penrose</author>
<publisher>Oxford Publishing Company</publisher>
<price>15.99</price>
</book>
</booklist>