XSLT Chain improvement [INT-675]
Sebastien Chatel opened INT-675 and commented
Allows chained XSL Transformations, and minimize memory footprint by using a SAX filter chain.
It can be achieve with a javax.xml.transform.sax.TransformerHandler.
We can extend this to all other XML Transformations (XPath, XQuery, custom XMLFilter, FOP ...).
Affects: 1.0.2
Reference URL: http://forum.springsource.org/showthread.php?s=4f72efe116e8721864c3080448ab4c4c&p=246666
Attachments:
- xslt-chained-poc.zip (5.62 kB)
Sebastien Chatel commented
To understand how to build a SAX filter chain.
The chain looks like this :
SAXResult1 => TransformerHandler1 => SAXResult2 => TransformerHandler2 => Result3
Here is how to build such a chain in a general manner :
// final result Result result3 = new StreamResult(out);
// second transformer TransformerHandler handler2 = factory.newTransformerHandler(templates2); // connect it to the final result handler2.setResult(result3);
// first transformer ... TransformerHandler handler1 = factory.newTransformerHandler(templates1); // connect it to second transformer ... handler1.setResult(new SAXResult(handler2));
// transform factory.newTransformer().transform(source, new SAXResult(handler1));
DelayedResult object implements the "chain of responsability" pattern :
DelayedResult.write( streamResult ) /* connect handler2 to streamResult, then */ /* Result result2 = new SAXResult(handler2) */ DelayedResult.write( result2 ) /* connect handler1 to result2, then */ /* Result result1 = new SAXResult(handler1) */ Delayed.write( result1 ) /* transform source to result1*/
Jonas Partner commented
Thanks for that Sebastien, would you be interested in submitting this as a patch with tests?
Sebastien Chatel commented
Hello Jonas,
I would be interested, but for the moment, i'm working on a more complete use of SAX. Not only for XSLT.
After reading this article "Implement complicated data transformations with SAX and XSLT" http://www.javaworld.com/javaworld/jw-09-2005/jw-0905-xslt.html?page=5
i had some ideas, what do you think of this :
------8<--------8<---------8<------------- <chain>
<!--!-- something before -->
<sax:transform-chain>
<sax:producer />
<sax:filter ref="myFilter" />
<sax:xsl-transformer xsl-resource="classpath:/file1.xsl" />
<sax:xsl-transformer xsl-resource="classpath:/file2.xsl" />
<sax:serializer to="string" />
</sax:transform-chain>
<!-- something after -->
</chain> ------8<--------8<---------8<-------------
Producer and Serializer elements are always required. I thing the SAX model is correctly formalized this way. Producer transforms any payload to a SAX Stream. When the payload in not in xml format (txt, csv, or any entreprise proprietary format), you can provide your own implementation : <sax:producer ref="myCustomProducer" />
Filters are standard XMLFilterImpl.
Serializer, serializes the SAX Stream into a result type : DOM, JDom, Dom4j, String, byte[], ... and for experimental, a DelayedResult.