Writing input filters
Saxon can take its input from a JAXP SAXSource
object, which essentially
represents a sequence of SAX events representing the output of an XML parser. A very useful
technique is to interpose a filter between the parser and Saxon. The filter will
typically be an instance of the SAX2 XMLFilter class.
There are a number of ways of using a Saxon XSLT transformation as part of a pipeline of filters. Some of these techniques also work with XQuery. The techniques include:
-
Generate the transformation as an
XMLFilter
using thenewXMLFilter()
method of theTransformerFactory
. This works with XSLT only. A drawback of this approach is that it is not possible to supply parameters to the transformation using standard JAXP facilities. It is possible, however, by casting theXMLFilter
to a net.sf.saxon.jaxp.FilterImpl, and calling itsgetTransformer()
method, which returns aTransformer
object offering the usualaddParameter()
method. -
Generate the transformation as a SAX
ContentHandler
using thenewTransformerHandler()
method. The pipeline stages after the transformation can be added by giving the transformation aSAXResult
as its destination. This again is XSLT only. -
Implement the pipeline step before the transformation or query as an
XMLFilter
, and use this as theXMLReader
part of aSAXSource
, pretending to be an XML parser. This technique works with both XSLT and XQuery, and it can even be used from the command line, by nominating theXMLFilter
as the source parser using the-x
option on the command line.
The -x
option on the Saxon command line specifies the parser that Saxon will use
to process the source files. This class must implement the SAX2 XMLReader
interface, but it is not required to be a real XML parser; it can take the input from any kind
of source file, so long as it presents it in the form of a stream of SAX events. When using
the JAXP API, the equivalent to the -x
option is to call
transformerFactory.setAttribute( net.sf.saxon.lib.Feature.SOURCE_PARSER_CLASS.name,
'com.example.package.Parser')