The JAXP Transformation API


The previous sections provided a summary of the classes and methods defined in JAXP to control XML parsing. This section covers the classes and methods used to control XSLT transformation.

These classes are designed so they could be used with transformation mechanisms other than XSLT, for example they could in principle be used to invoke XQuery (however, a different API is under development for XQuery, which is likely to have more in common with JDBC). But XSLT is the initial target and is the one we will concentrate on.

There is one other kind of transformation that's worth mentioning, however, and this is an identity transformation in which the result represents a copy of the source. JAXP provides explicit support for identity transformations. These are more useful than they might appear, because JAXP defines three ways of supplying the source document (SAX, DOM, or serial XML) and three ways of capturing the result document (SAX, DOM, or serial XML), so an identity transformation can be used to convert any of these inputs to any of the outputs. For example, it can take SAX input and produce a serial XML file as output, or it can take DOM input and produce a stream of SAX events as output. An implementation of JAXP can also support additional kinds of Source and Result object if it chooses.

JAXP is also designed to control a composite transformation consisting of a sequence of transformation steps, each defined by an XSLT stylesheet in its own right. To do this, it builds on the SAX2 concept of an XMLFilter , which takes an input document as a stream of SAX events and produces its output as another stream of SAX events. Any number of such filters can be arranged end to end in a pipeline to define a composite transformation.

As with the JAXP SAXParser and DocumentBuilder interfaces, JAXP allows the specific XSLT implementation to be selected using a TransformerFactory object. Typically the XSLT vendors will each provide their own subclass of TransformerFactory .

For performance reasons, the API separates the process of compiling a stylesheet from the process of executing it. A stylesheet can be compiled once and executed many times against different source documents, perhaps concurrently in different threads. The compiled stylesheet, following Microsoft's MSXML3 nomenclature , is known as a Templates object. To keep simple things simple, however, there are also methods that combine the two processes of compilation and execution into a single call.

The classes defined in the javax.xml.transform package fall into several categories:

Category

Class or interface

Description

Principal classes

TransformerFactory

Selects and configures a vendor's implementation

Templates

Represents a compiled stylesheet in memory

Transformer

Represents a single execution of a stylesheet to transform a source document into a result

SAXTransformerFactory

Allows a transformation to be packaged as a SAX XMLFilter

Source

Represents the input to a transformation

Result

Represents the output of a transformation

Source classes

SAXSource

Transformation input in the form of a SAX event stream

DOMSource

Transformation input in the form of a DOM Document

StreamSource

Transformation input in the form of a serial XML document

Result classes

SAXResult

Transformation output in the form of a SAX event stream

DOMResult

Transformation output in the form of a DOM Document

 

StreamResult

Transformation output in the form of a serial XML document (or HTML, or a plain text file)

Helper classes

URIResolver

User -supplied object that takes a URI contained in the stylesheet (for example, in the document() function) and fetches the relevant document as a Source object

ErrorListener

User-supplied object that is notified of warnings and errors. The ErrorListener notifies these conditions to the user and decides whether to continue processing

SourceLocator

Used primarily to identify where in the stylesheet an error occurred

DOMLocator

Subclass of SourceLocator , used when the source was a DOM

OutputKeys

A collection of constants defining the names of properties for serial output files

Error classes

Transformer ConfigurationException

Generally denotes an error in the stylesheet that is detected at compile time

Transformer Exception

A failure occurring in the course of executing a transformation

TransformerFactory ConfigurationError

A failure to configure the Transformer

In the following sections I will describe each of these classes, in alphabetical order of the class name (ignoring the name of the package).

javax.xml.transform.dom.DOMLocator

A DOMLocator is used to identify the location of an error when the document is supplied in the form of a DOM. This object will normally be created by the processor when an error occurs, and can be accessed using the getLocator() method of the relevant Exception object. It specializes SourceLocator , providing one additional method:

Method

Description

org.w3c.dom.Node getOriginatingNode()

Returns the node at which the error or other event is located

javax.xml.transform.dom.DOMResult

Supplying a DOMResult as the result of a transformation indicates that the output is to be written to a DOM in memory. This object will normally be created by the application, and supplied to the processor as the second argument of the Transformer.transform() method.

The DOMResult identifies a Node (which will generally be a Document or an Element , or possibly a DocumentFragment ) to hold the results of the transformation. The children of the root in the result tree will become children of this Node in the DOM. If no Node is supplied by the application, the system will create a Document node, which can be retrieved using getNode() .

Many XSLT processors will support DOM output, but it is not mandatory. If the processor does support it, then getFeature(DOMResult.FEATURE) will return true.

If the XSLT stylesheet outputs text using « disable-output-escaping ="yes" » , then this text will be preceded in the tree by a processing instruction named by the constant Result.PI_DISABLE_OUTPUT_ESCAPING , and followed by another processing instruction named by the constant Result.PI_ENABLE_OUTPUT_ESCAPING .

The DOMResult object holds a reference to the destination Node , and also a String containing a system identifier.

The class has two constructors:

 DOMResult() DOMResult(org.w3c.xml.Node) 

and the following methods:

Method

Description

org. w3 c .dom .Node getNode()

Gets the node that will contain the result tree

String getSystemId()

Gets the system identifier (that is, the base URI)

void setNode(org.w3c.dom.Node)

Sets the node that will contain the result tree. It must be a Document , an Element , or a DocumentFragment

void setSystemId(String)

Sets the system identifier (that is, the base URI)

javax.xml.transform.dom.DOMSource

A DOMSource packages a DOM Document as a Source , so it can be supplied as input to a transformation.

The DOMSource object will normally be created by the application, and supplied to the processor as the first argument of the Transformer.transform() method. It can also be used to identify the stylesheet document, in which case it will be supplied as a parameter to TransformerFactory.newTemplates() .

It is a good idea to call setSystemId() to supply a base URI for the document, so that relative URIs (for example, those used in the document() function) can be resolved. The DOM itself does not hold this information, so it must be supplied extraneously.

The DOMSource can identify any node in the DOM; it does not have to be the Document node. For example, when you use a DOMSource to identify a stylesheet, this might be a stylesheet embedded within another document, in which case the DOMSource would identify the <xsl:stylesheet> element node. When you supply a node other than the Document node as input to the transform() method, the effect is not specified very clearly, but it is probably intended that it should behave like the transformNode() method in MSXML3. This means that the entire document containing the identified node forms the input to the transformation, but the transformation starts by looking for a template rule that matches the specified node, rather than the one that matches the root node.

Note that there are two different ways XSLT processors might handle the supplied document. They might create the XPath tree model as a view or wrapper around the DOM tree, or they might make a copy. The difference between these approaches will become apparent if the stylesheet makes calls to external Java functions that attempt to manipulate the tree as a DOM. It will also, of course, affect performance. Generally, it is best to supply input as a stream or SAX source if you can. Don't construct a DOM specially in order to supply it as input to a transformation, as you might do if you are used to the Microsoft MSXML API. Most implementations will have an internal tree model that is designed to optimize transformation speed, and this will often run several times faster than the same transformation using the DOM.

Not every XSLT processor will support DOM input. If the processor does so, then getFeature(DOMSource.FEATURE) will return true.

The class has three constructors:

 DOMSource() DOMSource(Node) DOMSource(Node, String) 

Its methods are listed below:

Method

Description

Node getNode()

Gets the starting node of this DOMSource

String getSystemId()

Gets the system identifier (that is, base URI) for resolving relative URIs

void setNode(Node)

Sets the starting node of this DOMSource

setSystemId(String)

Gets the system identifier (that is, base URI) for resolving relative URIs

javax.xml.transform.ErrorListener

ErrorListener is an interface; if you want to do your own error handling you can write a class that implements this interface and supply it to the setErrorListener() methods of the Transformer Factory or Transformer class. The ErrorListener will be notified of both compile-time and runtime errors.

The class is modeled on the SAX ErrorHandler interface, and recognizes three categories of errors: warnings, errors, and fatal errors. After a warning, the transformation can proceed to a successful conclusion; after an error, the processor can continue for the purpose of finding further errors, but in the end it will fail; and after a fatal error, it will stop immediately.

Each method can throw an exception to cause processing to stop immediately, even where the processor is prepared to continue.

Some processors (Xalan in particular) report the output of <xsl:message> to the ErrorListener . If «terminate="no" » is specified, the message is treated as a warning; if «terminate="yes" » is specified, it is treated as a fatal error. JAXP doesn't dictate how <xsl:message> is handled, and other processors do it differently.

If no ErrorListener is supplied, errors will be reported on the standard System.err output stream.

The methods are listed below. The «[TE] » after each method shows that each of them can throw a TransformerException , to terminate processing.

Method

Description

void error(TransformerException) [TE]

Handles an error

void fatalError(TransformerException) [TE]

Handles a fatal error

void warning(TransformerException) [TE]

Handles a warning

javax.xml.transform.OutputKeys

This class defines a set of constant strings used to represent the standard output properties defined in the <xsl:output> element. This list hasn't yet been updated to support the new properties found in XSLT 2.0.

The names of these constants are:

 CDATA_SECTION_ELEMENTS DOCTYPE_PUBLIC DOCTYPE_SYSTEM ENCODING INDENT MEDIA  _  TYPE METHOD OMIT_XML_DECLARATION STANDALONE VERSION 

They correspond in the obvious way to the attributes of the <xsl:output> element.

These constants are useful when you call methods such as getOutputProperty() and setOutputProperty() on the Transformer object.

javax.xml.transform.Result

Result is an interface; it exists as an abstraction of the three classes SAXResult , DOMResult , and StreamResult , which are different ways of representing an XML output destination. This allows any of these different kinds of destination to be supplied as the second argument to the Transformer . transform() method. Implementations can also define other kinds of Result object if they wish.

This class defines the two static constants PI_DISABLE_OUTPUT_ESCAPING and PI_ENABLE_OUTPUT_ESCAPING which are the names of the processing instructions generated as a result of setting «disable-output-escaping="yes" » on the <xsl:text> or <xsl:value-of> instruction in the stylesheet.

The interface defines two methods, allowing any of the different types of Result to have a system identifier (or base URI):

Method

Description

String getSystemId()

Gets the system identifier

void setSystemId()

Sets the system identifier

javax.xml.transform.sax.SAXResult

Specifying a SAXResult as the output of the transformation causes the result tree produced by the transformation to be fed to a user-supplied SAX2 ContentHandler as a sequence of SAX events, just as if the events came from an XML parser. The SAXResult object holds a reference to this ContentHandler , and also to a String containing a system identifier. (This system identifier might be made available to the ContentHandler code as part of the Locator object, though the specification doesn't make it clear that this is what should happen.)

Many XSLT processors will support SAX output, but it is not mandatory. If the processor does support it, then getFeature(SAXResult.FEATURE) will return true .

There are several potential difficulties with supplying XSLT output to a ContentHandler :

  • What happens about disable-output-escaping ? The JAXP specification solves this by saying that any text output using disable-output-escaping="yes" will be preceded by a processing instruction named by the constant Result.PI_DISABLE_OUTPUT_ESCAPING , and followed by another processing instruction named by the constant Result.PI_ENABLE_OUTPUT_ESCAPING.

  • What happens to comments in the result tree? JAXP solves this by allowing the SAXResult to hold a LexicalHandler as well as a ContentHandler . Comments can then be notified to the LexicalHandler .

  • What happens if the result tree is not a well- formed document? The SAX ContentHandler interface is designed to receive a stream of events representing a well-formed document, and many ContentHandlers will fail (gracefully or otherwise ) if they are sent anything else. However, as you saw in Chapter 2, the output of an XSLT transformation needs only to be well-balanced. Unfortunately, the JAXP specification doesn't answer this question. (Saxon allows any sequence of events to be sent to the ContentHandler , whether it represents a well-formed sequence or not, unless the additional attribute saxon:require-well-formed="yes" is present on the <xsl:output> declaration.)

The class has two constructors:

 SAXResult() SAXResult(org.xml.sax.ContentHandler) 

and the following methods:

Method

Description

org.xml.sax.ContentHandler getHandler()

Gets the ContentHandler

org.xml.sax.ext.LexicalHandler getLexicalHandler()

Gets the LexicalHandler

String getSystemId()

Gets the system identifier (base URI)

void setHandler (org.xml.sax.ContentHandler)

Sets the ContentHandler that is to receive events representing the result tree

void setHandler (org.xml.sax.ext.LexicalHandler)

Sets the LexicalHandler that is to receive lexical events (notably, comments) representing the result tree

void setSystemId()

Sets the system identifier (base URI)

javax.xml.transform.sax.SAXSource

A SAXSource is a Source , so it is one of the possible inputs you can supply to the Transformer.transform() method (when it represents a source XML document) or to the TransformerFactory.newTemplates() method (when it represents a stylesheet).

Essentially, a SAXSource is the combination of a SAX parser ( XMLReader ) and a SAX InputSource , which can be a URI, a binary input stream, or a character input stream. A SAXSource delivers the source document in the form of a stream of SAX events. Usually it will achieve this by parsing XML held in a file or somewhere in memory; but by defining your own implementations of XMLReader and/or InputSource you can supply the SAX events from anywhere , for example you can generate them as the result of an SQL query or an LDAP directory search.

If no XMLReader is supplied, the system will use a default one. It may do this using the rules for the javax.xml.parsers.SAXParserFactory class described earlier in this appendix, but this is not guaranteed .

Not every XSLT processor will support SAX input. If the processor does so, then getFeature (SAXSource.FEATURE) will return true.

There are three constructors:

 SAXSource() SAXSource(InputSource) SAXSource(XMLReader, InputSource) 

plus the following methods:

Method

Description

InputSource getInputSource()

Gets the SAX InputSource .

String getSystemId()

Gets the System Identifier used for resolving relative URIs

XMLReader getXMLReader()

Gets the XMLReader (the parser) if one has been set

void setInputSource(org.xml.sax.InputSource)

Sets the SAX InputSource

void setSystemId(String)

Sets a System Identifier that can be used to resolve relative URIs

void setXMLReader(XMLReader)

Sets the XMLReader (the parser) to be used

static org.xml.sax.InputSource sourceToInputSource(Source source)

This static method attempts to construct a SAX InputSource from any kind of Source object. It will return null if this isn't possible

javax.xml.transform.sax.SAXTransformerFactory

This class is a subclass of TransformerFactory that provides three additional facilities:

  • The ability to construct a SAX ContentHandler (called a TemplatesHandler ), which will accept a stream of SAX events representing a stylesheet, and on completion return a Templates object for this stylesheet.

  • The ability to construct a SAX ContentHandler (called a TransformerHandler ) that will accept a stream of SAX events representing a source document, and on completion automatically apply a given stylesheet to that source document.

  • The ability to construct a SAX XMLFilter based on a particular stylesheet: The XMLFilter performs the same SAX-to-SAX transformation as the equivalent Transformer would perform, but using the interfaces defined for an XMLFilter . This makes it possible to insert this transformation filter into a pipeline of filters.

These are advanced facilities, and they are optional, so not every JAXP processor will support them.

  • If getFeature(SAXTransformerFactory.FEATURE) returns true , then the implementation's TransformerFactory will be a SAXTransformerFactory .

  • If getFeature(SAXTransformerFactory.FEATURE_XMLFILTER) returns true , then the two newXMLFilter() methods can be used.

If a SAXTransformerFactory is available at all, then it will always be produced as a result of calling TransformerFactory.newInstance() .

The class has the following methods, in addition to those of TransformerFactory :

Method

Description

TemplatesHandler newTemplatesHandler() [TCE]

Creates and returns a TemplatesHandler . The TemplatesHandler can be supplied with a stream of SAX events representing the contents of a stylesheet

TransformerHandler newTransformerHandler() [TCE]

Creates and returns a TransformerHandler . The TransformerHandler will perform an identity transformation on the XML source document that is supplied to it in the form of a stream of SAX events

TransformerHandler newTransformerHandler(Source) [TCE]

Creates and returns a TransformerHandler . The Source identifies a document containing a stylesheet. The TransformerHandler will perform the transformation defined by this stylesheet, on the XML source document that is supplied to it in the form of a stream of SAX events

TransformerHandler newTransformerHandler(Templates) [TCE]

Creates and returns a TransformerHandler . The Templates argument identifies a compiled stylesheet. The TransformerHandler will perform the transformation defined by this stylesheet, on the XML source document that is supplied to it in the form of a stream of SAX events

org.sax.xml.XMLFilter newXMLFilter(Source) [TCE]

Creates and returns an XMLFilter . The Source identifies a document containing a stylesheet. The resulting XMLFilter will perform the transformation defined by this stylesheet

org.sax.xml.XMLFilter newXMLFilter(Templates) [TCE]

Creates and returns an XMLFilter . The Templates argument identifies a compiled stylesheet. The resulting XMLFilter will perform the transformation defined by this stylesheet

javax.xml.transform.Source

Source is an interface; it exists as an abstraction of the three classes SAXSource , DOMSource , and StreamSource , which are different ways of representing an XML document. This allows any of these different kinds of object to be supplied as the source document to the Transformer.transform() method, or as the stylesheet to the TransformerFactory.newTemplates() method.

The interface defines two methods, allowing any of the different types of Source to have a system identifier. Specifying a system identifier on a Source object is important, because it will be used as the base URI when relative URIs within the Source are resolved.

Method

Description

String getSystemId()

Gets the system identifier

void setSystemId()

Sets the system identifier

javax.xml.transform.SourceLocator

SourceLocator is an interface modeled on the SAX Locator interface. A SourceLocator is used to indicate where in the stylesheet an error occurred. Normally a SourceLocator will be produced by the XSLT processor, and the application will access it using the TransformerException.getLocator() method.

The methods available are:

Method

Description

int getColumnNumber()

Returns the column number of the location if known, or -1 if not

int getLineNumber()

Returns the line number of the location if known, or -1 if not

String getPublicId()

Returns the public identifier of the document, if available, or null if not

String getSystemId ()

Returns the system identifier of the document, if available, or null if not

javax.xml.transform.stream.StreamSource

A StreamSource represents XML input in the form of a character or byte stream. It is modeled on the SAX InputSource class; the only reason StreamSource is necessary is that InputSource does not implement the Source interface, so it cannot be supplied directly as the input to methods such as Transformer.transform(Source, Result) .

Most XSLT processors will support stream input, but it is not mandatory. If the processor does support it, then getFeature(StreamSource.FEATURE) will return true.

If input is from a byte stream (Inputstream) or character stream (Reader) it is a good idea to call setSystemId() to supply a URI for the document, so that relative URIs (for example, those used in the document() function) can be resolved. The stream itself does not hold this information, so it must be supplied extraneously.

The constructors are as follows :

 StreamSource() StreamSource(java.io.File) StreamSource(java.io.InputStream) Streamsource(java.io.InputStream, String) StreamSource(java.io.Reader) StreamSource(java.io.Reader, String) StreamSource(String) 

In each case the effect is the same as using the default constructor followed by the relevant setxxx() method. The String argument is always a system identifier for the document.

In my experience the File-to-URI conversion used when you supply a java.io.File object is buggy : It's better to use the File.toURI() method to do the conversion, as this does a better job of handling special characters such as spaces.

The methods are straightforward:

Method

Description

java.io.InputStream getInputStream()

Gets the supplied InputStream

String getPublicId()

Gets the supplied Public Identifier

java.io.Reader getReader()

Gets the supplied Reader

String getSystemId()

Gets the system identifier

Void setInputStream(java.io.InputStream)

Supplies an InputStream

void setPublicId(String)

Supplies a Public Identifier

void setReader (java.io.Reader)

Supplies a Reader

void setSystemId(java.io.File)

Supplies a File from which a system identifier can be obtained

void setSystemId(String)

Supplies a system identifier (a URL)

javax.xml.transform.stream.StreamResult

You can supply a StreamResult as the result of a transformation if you want the result tree to be serialized. The format of the resulting file will be XML, HTML, or plain text, depending on the output method defined using <xsl:output> or the Transformer methods setOutputProperty() and setOutputProperties() . With an XSLT 2.0 engine, XHTML output will also be supported.

Note that if you supply a Writer (which represents a stream of characters rather than bytes), then the XSLT processor will ignore the encoding attribute specified on <xsl:output> The way in which characters are translated to bytes in this situation depends on how the Writer is configured, and not on the XSLT serializer. One consequence of this is that because the Writer knows nothing about XML, it will not be able to replace characters that aren't available in the chosen encoding by XML character references of the form «&#x20AC; » .

StreamResult is defined analogously to StreamSource , which in turn is based on the SAX InputSource class. A StreamResult may be a file (represented by a URL or a Java File object), or a character stream ( Writer ), or a byte stream ( OutputStream ).

Most XSLT processors will support stream output, but it is not mandatory. If the processor does support it, then getFeature(StreamResult.FEATURE) will return true .

Although the output destination can be expressed as a URI, this must be a writable destination. In practice this usually means it should be a URI that uses the «file: » prefix, but it could potentially be an ftp or WebDAV destination. If you're running the processor in an applet, writing the output to a file is probably not feasible . The specification doesn't say what happens if you supply a relative URI, but since relative URIs are not allowed in a SAX InputSource , on which this class is modeled, it's best to avoid them. Some processors might interpret a relative URI as being relative to the current directory.

The class has constructors for each of the possible output destinations. The constructor for a String expects the string to contain a system identifier (URL).

 StreamResult() StreamResult(File) StreamResult(java.io.OutputStream) StreamResult(String) StreamResult(java.io.Writer) 

The methods are straightforward:

Method

Description

java.io.OutputStream getOutputStream()

Gets the binary output stream

String getSystemId()

Gets the system identifier

java.io.Writer getWriter()

Gets the Writer (character output stream)

void setOutputStream(java.io.OutputStream)

Sets the binary output stream

void setSystemId(java.io.File)

Sets output to go to the specified file, by setting the system identifier to the URL of this file

void setSystemId(String)

Specifies the system identifier of the output, as a URL

void setWriter(java.io.Writer)

Specifies the Writer (character output stream) to receive the output

javax.xml.transform.Templates

A Templates object represents a compiled stylesheet. Compiled stylesheets cannot be saved on a disk, but they are held in memory and can be used as often as required. To use a Templates object to perform a transformation, first create a Transformer by calling its newTransformer() method, then configure the Transformer as required (for example, setting its parameters and output properties), and then run the transformation using the Transformer.transform() method.

The methods available on the Templates object are:

Method

Description

java.util.Properties getOutputProperties()

Returns a Properties object representing the names and values of the output properties defined using <xsl:output> elements in the stylesheet. The keys of these properties will be strings defined in the OutputKeys class; the values will be the values defined in the stylesheet. Note that output properties that are determined dynamically will not be returned: For example, if the method attribute of <xsl:output> is defaulted, the system doesn't know at compile time whether the output will be XML or HTML

Transformer newTransformer()(TCE ]

Creates a Transformer object, which can be used to effect the transformation defined in this stylesheet

javax.xml.transform.sax.TemplatesHandler

A TemplatesHandler is a SAX ContentHandler that treats the stream of SAX events supplied to it as the contents of a stylesheet. When the full document has been supplied, the stylesheet is compiled, and the compiled stylesheet can be retrieved using the getTemplates() method.

This provides an alternative to calling TransformerFactory.newTemplates() and supplying a SAXSource as the source of the stylesheet. The case for using a TemplatesHandler arises when the source of the SAX events is something other than a SAX XMLReader; for example, when the stylesheet is the output of another transformation, in which case the source of the SAX events is a JAXP Transformer. In this situation the TemplatesHandler can be wrapped into a SAXResult and used as the Result of the earlier transformation.

A TemplatesHandler is always created using the newTemplatesHandler() method of a SAXTransformerFactory. It provides the following methods in addition to those defined in the SAX ContentHandler interface:

Method

Description

String getSystemId()

Gets the system identifier of the stylesheet

Templates getTemplates()

Returns the Templates object created by compiling the supplied document as a stylesheet

void setSystemId()

Sets the system identifier of the stylesheet. A system identifier is needed if relative URIs (for example in <xsl:include> or <xsl:import> elements) need to be resolved

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.Transformer

A Transformer represents the collection of resources needed to perform a transformation of a Source to a Result . This includes the compiled stylesheet, the parameter values, and the output properties, as well as details such as an ErrorListener and a URIResolver .

This interface is analogous to the IXSLProcessor class in Microsoft's MSXML3 API.

A Transformer is always created by calling the newTransformer() method of either the Templates object, or the TransformerFactory object.

A transformer can be used to perform more than one transformation, but it is not thread-safe: You should not start one transformation until another has finished. If you want to perform several transformations in parallel, obtain several Transformers from the same Templates object.

The principal method is transform() , which takes two arguments, representing the Source and the Result . There are several different kinds of Source defined, and several kinds of Result . These are described elsewhere in this appendix.

The full set of methods is as follows. The exception codes [IAE] and [TE] refer to IllegalArgumentException and TransformerException respectively.

Method

Description

void clearParameters()

Clears all parameter set using setParameter()

ErrorListener getErrorListener()

Gets the ErrorListener for this transformation

java.util.Properties getOutputProperties() [IAE]

Gets the output properties defined for this transformation. This will be a combination of those defined in the stylesheet and those defined using setOutputProperty() and setOutput Properties()

String getOutputProperty (String) [IAE]

Gets a specific output property defined for this transformation. The argument should be one of the constants defined in OutputKeys , or a vendor-specific property name

Object getParameter (String)

Gets the value of a parameter defined for this transformation

URIResolver getURIResolver()

Gets the URIResolver used for this transformation, or null if none has been supplied

void setErrorListener (ErrorListener) [IAE]

Sets the ErrorListener to be used to handle errors reported during this transformation

void setOutputProperties (java.util.Properties) [IAE]

Sets output properties for the result of this transformation. These properties override any values set using <xsl:output> in the stylesheet. The property names will normally be constants defined in OutputKeys , or vendor-defined properties, but they can also be user-defined properties provided they are namespace-qualified. Names are namespace-qualified using the «{uri} localname » notation, in the same way as parameters

void setOutputProperty(String, String) [IAE]

Sets the value of a specific output property for the result of this transformation

void setParameter(String, Object)

Supplies a parameter for the transformation. The first argument corresponds to the parameter name, as defined in a global <xsl:param> element in the stylesheet; if this is namespace-qualified, it should be written in the form «{uri}1ocal-name » . The second argument is the parameter value. It's not defined in the JAXP 1.2 specification what the mapping from Java objects to XPath data types is: JAXP 1.3 is likely to have more to say on this subject. Using a String , a Double , a Boolean , or a DOM Node is likely to work in most processors, but beyond this, it depends on the implementation

void setURIResolver(URIResolver)

Sets the URIResolver to be used to resolve all URIs encountered during this transformation, especially when evaluating the document() function

void transform(Source, Result) [TE]

Performs the transformation. Source and Result are interfaces, allowing a wide range of different types of Source and Result to be supplied

javax.xml.transform.TransformerConfigurationException

This class defines a compile-time error, generally an error in the stylesheet. It is a subclass of TransformerException and has the same methods as its parent class, TransformerException.

There are several constructors defined, but since this object will usually be created by the XSLT processor itself, I won't list them here.

javax.xml.transform.TransformerException

A TransformerException represents an error that might be detected either at compile-time or at runtime. The exception may contain any or all of the following:

  • A message explaining the error.

  • A nested exception, generally containing additional information about this error. (Actually, despite the name getException() , this need not be an Exception object: It can be any Throwable , allowing an Error as well as an Exception.)

  • A SourceLocator , indicating where in the stylesheet the error occurred.

  • A cause. This is likely to be the same as the nested exception. Nested exceptions were introduced in JAXP before they became a standard Java feature in JDK 1.4, which is why there are two methods that appear to do the same thing.

There are several constructors defined, but since this object will usually be created by the XSLT processor itself, I won't list them here.

The methods available are:

Method

Description

Throwable getCause()

Gets the cause of the exception, if any

Throwable getException()

Gets the nested exception, if any

String getLocationAsString()

Constructs a String representing the location of the error

SourceLocator getLocator ()

Gets the SourceLocator , if any, that identifies where the error occurred

String getMessageAndLocation()

Constructs a String that combines information about the error and information about where it occurred

void initCause(Throwable)

Sets the cause of this exception

void setLocator(SourceLocator)

Sets a SourceLocator identifying where the error occurred

javax.xml.transform.TransformerFactory

Like the SAXParserFactory and DocumentBuilderFactory in the javax.xml.parsers package, described in the first part of this appendix, this factory class enables you to select a specific vendor's XSLT implementation.

The first thing an application must do is obtain a TransformerFactory , which it can do by calling the static method TransformerFactory.newInstance() . Different vendors of XSLT processors will each implement their own subclass of TransformerFactory , and this method call determines which vendor's processor your application will end up using. If there are several available, the one that is used is based on the following decision process:

  1. Use the value of the system property javax.xml.transform.TransformerFactory if it is available. You can set system properties using the -D option on the Java command line, or by calling System.setProperty() from your application.

  2. Look for a properties file $JAVA_HOME/lib/jaxp.properties , and within this file, for the property named javax.xml.parsers.TransformerFactory .

  3. Use the services API, which is part of the JAR specification. This generally means that the first processor found on the classpath will be used.

It is likely 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 .

JDK 1.4 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.4.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 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. As with other methods, the exceptions thrown are indicated by a list of codes, which are explained in the table on page 816 at the start of this appendix.

Method

Description

Source getAssociatedStyleSheet (Source doc, String media, String title, String charset) [TCE]

Within the XML source document identified by the Source argument, finds the <?xml-stylesheet ?> 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) [IAE]

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() [TFCE]

Returns an instance of the vendor-specific TransformerFactory , selected according to the rules given above

Templates newTemplates(Source) [TCE]

Compiles the stylesheet provided in the given Source , returning a Templates object as a representation of the compiled stylesheet

Transformer newTransformer() [TCE]

Creates a Transformer that will perform an identity transformation

Transformer newTransformer(Source) [TCE]

A shortcut method equivalent to calling newTemplates(Source) .newTransformer()

void setAttribute(String, Object) [IAE]

Sets a vendor-specific configuration property

void setErrorListener(ErrorListener) [IAE]

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.sax.TransformerHandler

A TransformerHandler receives SAX events representing a source document. It performs a transformation on this source document, and writes 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 so that it can 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 TransformerHandler 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) [IAE]

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. When the XSLT processor has to find an XML document using a URI specified in <xsl:include> , <xsl:import> , or in the document () function, it will call any user-supplied URIResolver to do the work. 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 result as a rowset.

The interface defines only one method:

Method

Description

Source resolve (String, String) [TE]

The first argument is a relative URI, the second is the base URI against which it is resolved. The method returns a Source containing the requested document, or throws a TransformerException if it cannot retrieve it. It may also return null, indicating that the default URIResolver should be used

Note  

There is a practical problem that the JAXP interface does not address, namely the XSLT rule that if you call the document() function twice to fetch the same absolute URI, the same document should be returned each time. Since the URIResolver accepts the relative URI and base URI as separate arguments, but does not actually return an absolute URI, it's not entirely clear whether it is the responsibility of the processor or the URIResolver to enforce this rule, especially when the URI is in a format that the XSLT processor itself does not recognize, as in the example above.

Note also that the arguments are supplied in the opposite order to those of the Java java.net.URI class.




XSLT 2.0 Programmer's Reference
NetBeansв„ў IDE Field Guide: Developing Desktop, Web, Enterprise, and Mobile Applications (2nd Edition)
ISBN: 764569090
EAN: 2147483647
Year: 2003
Pages: 324

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net