Re: [saxon] Chaining xsl transformations programmatically

> A further question, though: is this the best way to write
> the results to a stream?
Yes, probably, especially if you want the application to control the
serialization properties.
Michael Kay
http://www.saxonica.com/

Thread view

Hi!
I would like to chain two xsl transformations so that the result of the
first one will be the input for the second one. I want to do the chaining
in the calling Java program, not in the xsl stylesheets themselves.
I don't want to use an intermediate result file or byte buffer as that
requires serializing and reparsing the xml. Instead, I would like to use
SAX so that the SAX events resulting from the first transformation (using
SAXResult) are used as the input for the second one.
Or would it be better to construct a DOM tree as the result of the first
transformation, and use that as the input for the second?
I tried looking at JAXP API, but could not figure out how to do this. I
would prefer to do this using the JAXP API, but if necessary, I can call
the Saxon API directly.
I'm using Saxon 655 (due to using docboox xsl stylesheets that have
extensions that don't work w/ the newer versions) and Java 1.5.
.::Antti::.

>>>>> "Antti" == Antti Karanta <antti.karanta@...> writes:
Antti> I'm using Saxon 655 (due to using docboox xsl
Antti> stylesheets that have extensions that don't work w/ the
Antti> newer versions) and Java 1.5.
There are XSLT 2.0 stylesheets that you could use with Saxon 9.
--
Colin Adams
Preston Lancashire

There are examples of how to do this using JAXP in the TraxExamples.java
sample application which is included with the Saxon 6.5.5 distribution.
There are actually two ways to do it. One sets up the transformation as a
SAX XMLFilter:
/**
* This example shows how to chain events from one Transformer
* to another transformer, using the Transformer as a
* SAX2 XMLFilter/XMLReader.
* @param sourceID file name of the source file
* @param xslID_1 file name of the first stylesheet file
* @param xslID_2 file name of the second stylesheet file
* @param xslID_3 file name of the third stylesheet file
*/
public static void exampleXMLFilterChain(
String sourceID, String xslID_1, String xslID_2, String xslID_3)
throws TransformerException, SAXException,
IOException, ParserConfigurationException {
TransformerFactory tfactory = TransformerFactory.newInstance();
// If one success, assume all will succeed.
if (tfactory.getFeature(SAXSource.FEATURE)) {
SAXTransformerFactory stf = (SAXTransformerFactory) tfactory;
XMLReader reader = makeXMLReader();
XMLFilter filter1 = stf.newXMLFilter(new StreamSource(new
File(xslID_1)));
XMLFilter filter2 = stf.newXMLFilter(new StreamSource(new
File(xslID_2)));
XMLFilter filter3 = stf.newXMLFilter(new StreamSource(new
File(xslID_3)));
if (null != filter1) // If one success, assume all were
success.
{
// transformer1 will use a SAX parser as it's reader.
filter1.setParent(reader);
// transformer2 will use transformer1 as it's reader.
filter2.setParent(filter1);
// transformer3 will use transformer2 as it's reader.
filter3.setParent(filter2);
filter3.setContentHandler(new ExampleContentHandler());
// filter3.setContentHandler(new
org.xml.sax.helpers.DefaultHandler());
// Now, when you call transformer3 to parse, it will set
// itself as the ContentHandler for transform2, and
// call transform2.parse, which will set itself as the
// content handler for transform1, and call
transform1.parse,
// which will set itself as the content listener for the
// SAX parser, and call parser.parse(new
InputSource(foo_xml)).
filter3.parse(new InputSource(new
File(sourceID).toURL().toString()));
} else {
System.out
.println("Can't do exampleXMLFilter because "
+ "tfactory doesn't support newXMLFilter()");
}
} else {
System.out.println("Can't do exampleXMLFilter because "
+ "tfactory is not a SAXTransformerFactory");
}
}
The other approach sets up a transformer as a SAX ContentHandler. This code
doesn't actually demonstrate chaining, but since a TransformerHandler is a
ContentHandler it can be wrapped in a SAXResult and used as the destination
of another transformation.
/**
* Show the Transformer using SAX events in and SAX events out.
* @param sourceID file name of the source file
* @param xslID file name of the stylesheet file
*/
public static void exampleContentHandlerToContentHandler(
String sourceID, String xslID)
throws TransformerException, SAXException,
ParserConfigurationException,
IOException {
TransformerFactory tfactory = TransformerFactory.newInstance();
// Does this factory support SAX features?
if (tfactory.getFeature(SAXSource.FEATURE)) {
// If so, we can safely cast.
SAXTransformerFactory stfactory =
((SAXTransformerFactory) tfactory);
// A TransformerHandler is a ContentHandler that will listen for
// SAX events, and transform them to the result.
TransformerHandler handler =
stfactory.newTransformerHandler(new StreamSource(xslID));
// Set the result handling to be a serialization to System.out.
Result result = new SAXResult(new ExampleContentHandler());
handler.setResult(result);
// Create a reader, and set it's content handler to be the
TransformerHandler.
XMLReader reader = makeXMLReader();
reader.setContentHandler(handler);
// It's a good idea for the parser to send lexical events.
// The TransformerHandler is also a LexicalHandler.
reader.setProperty(
"http://xml.org/sax/properties/lexical-handler";, handler);
// Parse the source XML, and send the parse events to the
TransformerHandler.
reader.parse(sourceID);
} else {
System.out.println(
"Can't do exampleContentHandlerToContentHandler because
tfactory is not a SAXTransformerFactory");
}
}
Michael Kay
http://www.saxonica.com/
> -----Original Message-----
> From: saxon-help-bounces@...
> [mailto:saxon-help-bounces@...] On Behalf
> Of Antti Karanta
> Sent: 08 February 2008 12:49
> To: saxon-help@...
> Subject: [saxon] Chaining xsl transformations programmatically
>
>
>
> Hi!
>
> I would like to chain two xsl transformations so that the
> result of the first one will be the input for the second one.
> I want to do the chaining in the calling Java program, not in
> the xsl stylesheets themselves.
>
> I don't want to use an intermediate result file or byte
> buffer as that requires serializing and reparsing the xml.
> Instead, I would like to use SAX so that the SAX events
> resulting from the first transformation (using
> SAXResult) are used as the input for the second one.
> Or would it be better to construct a DOM tree as the
> result of the first transformation, and use that as the input
> for the second?
>
> I tried looking at JAXP API, but could not figure out how
> to do this. I would prefer to do this using the JAXP API, but
> if necessary, I can call the Saxon API directly.
>
>
> I'm using Saxon 655 (due to using docboox xsl stylesheets
> that have extensions that don't work w/ the newer versions)
> and Java 1.5.
>
>
>
> .::Antti::.
>
>
>
> --------------------------------------------------------------
> -----------
> This SF.net email is sponsored by: Microsoft Defy all
> challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> saxon-help mailing list archived at
> http://saxon.markmail.org/ saxon-help@...
> https://lists.sourceforge.net/lists/listinfo/saxon-help

On Fri, 08 Feb 2008 15:01:38 +0200, Michael Kay
<mike-JkSD5nQpfvpWk0Htik3J/w@...> wrote:
> There are actually two ways to do it. One sets up the transformation as a
> SAX XMLFilter:
Thanks! Using XML Filters looks precisely like what I want.
A further question, though: is this the best way to write the results to
a stream?
OutputStream out = ...
XMLFilter lastFilter = ...
TransformerHandler thandler =
saxTransformerFactory.newTransformerHandler() ;
thandler.setResult( new StreamResult( out ) ) ;
lastFilter.setContentHandler( thandler ) ;
.::Antti::.

> A further question, though: is this the best way to write
> the results to a stream?
Yes, probably, especially if you want the application to control the
serialization properties.
Michael Kay
http://www.saxonica.com/

On Fri, 08 Feb 2008 15:01:31 +0200, Colin Paul Adams wrote:
>>>>>> "Antti" == Antti Karanta writes:
>
> Antti> I'm using Saxon 655 (due to using docboox xsl
> Antti> stylesheets that have extensions that don't work w/ the
> Antti> newer versions) and Java 1.5.
>
> There are XSLT 2.0 stylesheets that you could use with Saxon 9.
I was under the impression that they are pretty much work-in-progress
and not recommended for production use? Are they production ready?
http://wiki.docbook.org/topic/DocBookXsl2Stylesheets
"The XSLT 2.0 stylesheets are incomplete and immature as compared to the
existing DocBookXslStylesheets. They should be considered experimental for
the time being."
Of course, that wiki entry could be outdated...
.::Antti::.

>>>>> "Antti" == Antti Karanta <antti.karanta@...> writes:
>> There are XSLT 2.0 stylesheets that you could use with Saxon 9.
Antti> I was under the impression that they are pretty much
Antti> work-in-progress and not recommended for production use?
Antti> Are they production ready?
Antti> http://wiki.docbook.org/topic/DocBookXsl2Stylesheets
Antti> "The XSLT 2.0 stylesheets are incomplete and immature as
Antti> compared to the existing DocBookXslStylesheets. They should
Antti> be considered experimental for the time being."
I don't know the latest status.
--
Colin Adams
Preston Lancashire

On 08/02/2008, Antti Karanta <antti.karanta@...> wrote:
> > There are XSLT 2.0 stylesheets that you could use with Saxon 9.
>
> I was under the impression that they are pretty much work-in-progress
> and not recommended for production use? Are they production ready?
>
> http://wiki.docbook.org/topic/DocBookXsl2Stylesheets
>
> "The XSLT 2.0 stylesheets are incomplete and immature as compared to the
> existing DocBookXslStylesheets. They should be considered experimental for
> the time being."
>
> Of course, that wiki entry could be outdated...
That refers to the docbook xslt 2.0 stylesheets. They are still in development
(ask on the docbook-apps mailing list)
XSLT 2.0 is a W3C recommendation however.
HTH
--
Dave Pawson
XSLT XSL-FO Docbook FAQ.
http://www.dpawson.co.uk