Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
The theory is that when you install a particular XSLT processor, it will contain a file in its
.jar
archive that makes that particular processor the default, so if you don't do anything to select a specific processor, the one chosen will depend on the order of files and directories on your class path. Unfortunately the practice can be rather different, because you don't always have control over the classpath, especially in a complex application server environment.
Relying on a search of the classpath has two other disadvantages. Firstly, it is expensive; if the transformation is a short one then it can take longer to find a transformer than to run it. Secondly, it is error-prone; it's difficult to be sure that your application will keep working when small and apparently unrelated configuration changes are made. Although it's a good thing to write your application in such a way that it will potentially work with any XSLT processor, it's a bad thing to allow it to run with an XSLT processor that it hasn't been tested with.
If you're writing an application that's designed to work only with Saxon, and you don't mind having compile-time references to Saxon classes in your code, then I would recommend bypassing the call to
TransformerFactory.newInstance()
, and simply calling
new net.sf.saxon.TransformerFactoryImpl()
instead. Alternatively, call
System.setProperty(“javax.xml.transform.TransformerFactory”, “net.sf.saxon.TransformerFactoryImpl”)
. But remember that this setting will affect everything running in the same Java VM.
For Saxon-SA, the name of the class is
com.saxonica.SchemaAwareTransformerFactory
.
The latest JAXP release, included in Java 6, provides a new version of the
TransformerFactory.newInstance()
method that allows you to specify the name of the implementation class as a parameter to the call. This avoids the side effects of setting the system property.
Java includes a copy of Xalan in its core libraries. This doesn't stop you using any of the techniques above to load a different XSLT processor, such as Saxon. What can be slightly tricky, however, is to use a later version of Xalan than the one included with the JDK. The easiest way to achieve this is to copy
xalan.jar
into a specially recognized directory for endorsed code, such as
j2sdk1.5.0/jre/lib/endorsed/xalan.jar
.
Once you have got a
TransformerFactory
, you can use a number of methods to configure it. Finally, you can call the
newTemplates()
method to compile a stylesheet, or call the
new Transformer()
method to obtain a
Transformer
directly (if you only want to use the compiled stylesheet once).
The methods available are shown below.
Method | Description |
Source getAssociatedStyleSheet(Source doc, String media, String title, String charset) | Within the XML source document identified by the Source argument, finds the processing instruction corresponding to the media , title , and charset parameters (any of which may be null), and returns a Source representing this stylesheet. |
Object getAttribute(String) | Gets a vendor-specific configuration property. |
ErrorListener getErrorListener() | Gets the default error listener that will be used for transformations. If none has been set, this will be a vendor-supplied ErrorListener . |
boolean getFeature(String) | Gets information about the features supported by this implementation. Features are defined by constants within other classes; for example, getFeature(SAXResult.FEATURE) returns true if the processor supports output to a SAX ContentHandler . |
URIResolver getURIResolver() | Gets the default URIResolver that will be used for transformations. |
static TransformerFactory newInstance() | Returns an instance of the vendor-specific TransformerFactory , selected according to the rules given above. |
Templates newTemplates(Source) | Compiles the stylesheet provided in the given Source , returning a Templates object as a representation of the compiled stylesheet. |
Transformer newTransformer() | Creates a Transformer that will perform an identity transformation. |
Transformer newTransformer(Source) | A shortcut method equivalent to calling newTemplates(Source).newTransformer() . |
void setAttribute(String, Object) | Sets a vendor-specific configuration property. |
void setErrorListener(ErrorListener) | Defines the ErrorListener to be used for error handling. |
void setURIResolver(URIResolver) | Defines the URIResolver to be used for resolving URIs contained in the stylesheet or source document. |
javax.xml.transform.TransformerFactoryConfigurationError
A
TransformerFactoryConfigurationError
(the specification writers must be good typists) represents an error in configuring the XSLT processor, as distinct from an error in the stylesheet itself.
Note that this is an
Error
rather than an
Exception
, which means that an application is not expected to take any recovery action.
The only methods available are:
Method | Description |
String getMessage() | Gets the error message |
Exception getException() | Gets any nested exception |
javax.xml.transform.sax.TransformerHandler
The
TransformerHandler
interface is a specialization of the SAX
ContentHandler
. It is an object that receives SAX events representing a source document and performs a transformation on this source document, writing the results of the transformation to a given
Result
object.
The
TransformerHandler
interface extends three SAX event-handling interfaces: the
ContentHandler
, the
LexicalHandler
, and the
DTDHandler.
It needs to act as a
LexicalHandler
so that it can handle comments in the source document, and it needs to act as a
DTDHandler
so that it can ignore comments in the DTD and find out about unparsed entity declarations in the DTD.
Using a
TransformerHandler
is an alternative to creating a
Transformer
and using a
SAXSource
to define the input document. This alternative approach is particularly useful when the source of SAX events is something other than a SAX
XMLReader
. For example, the source of SAX events might be another JAXP transformation, or it might be any other piece of software that allows a
ContentHandler
to be nominated to receive results.
A
TransformerHandler
is always created using the
newTransformerHandler()
method of a
SAXTransformerFactory
.
In addition to the methods defined in the SAX
ContentHandler
,
LexicalHandler
, and
DTDHandler
interfaces, a
TransformerHandle
r
offers the following methods:
Method | Description |
String getSystemId() | Gets the system identifier defined for the source document. |
Transformer getTransformer() | Gets the underlying Transformer. This can be used to set parameters and output properties for the transformation. |
void setResult(Result) | Sets the output destination for the transformation. |
void setSystemId(String) | Sets the system identifier for the source document. This will be used as a base URI to resolve any relative URIs contained in the document. |
javax.xml.transform.URIResolver
URIResolver
is an interface; you can write a class that implements this interface and supply it to the
setURIResolver()
method of the
TransformerFactory
or
Transformer
class. The
URIResolver
supplied to the
TransformerFactory
is used to handle a URI encountered at compile time in an
URIResolver
supplied to the
Transformer
is used at runtime to handle the
document()
function. The
URIResolver
can treat the URI any way it likes, and it returns the required document as a
Source
object: typically a
SAXSource
, a
DOMSource
, or a
StreamSource
.
For example, if the stylesheet called
document(‘db:employee=517541’)
, your
URIResolver
could interpret this URI as a database query and return an XML document containing the results of the query.