Hi Martin,
You could create an Object that implements ContentHandler, and wrap it as
the SAXResult of each of the transformations. It would also be the
SAXSource the aggregated content (presumably the identity transformation).
Except for startDocument() and endDocument() this object would pass most of
its calls straight through to the aggregate transformation.
This object would need an extra API on it for the you to mark whether it is
the last transformation. That is the real problem here, knowing when the
last transformation occurs.
Your object would pass throught the first startDocument() call, but ignore
others. Likewise it would ignore all endDocument() calls except when it
is told not to ignore them. So just before your last endDocument() call you
call that method to let it know that it shouldn't ignore them.
So your code would look more like this:
TransformerHandler serializerHandler = factory.newTransformerHandler();
MyContentHandler x = new MyContentHandler(); // MyContentHandler
implements ContentHandler
TransformerHandler xslHandler1 = factory.newTransformerHandler(templates1);
TransformerHandler xslHandler2 = factory.newTransformerHandler(templates2);
xslHandler1.setResult(new SAXResult(x));
xslHandler2.setResult(new SAXResult(x));
x.startDocument();
x.startElement("", "html", "html", HTML_ATTRS);
// other initial elements
xslHandler1.startDocument();
// Generate SAX events for the first fragment
xslHandler1.endDocument();
x.theLastTransformationIsNext(); // don't ignore endDocument() anymore
xslHandler2.startDocument();
// Generate SAX events for the second fragment
xslHandler2.endDocument();
x.dontIgnoreEndDocument(); // don't ignore endDocument() anymore
serializerHandler.endElement("", "html", "html");
serializerHandler.endDocument();
I'm missing some glue code to have MyContentHandler be the input the the
identity transformation, but you should get the idea.
- Brian
- - - - - - - - - - - - - - - - - - - -
Brian Minchau
XSLT Development, IBM Toronto
e-mail: [EMAIL PROTECTED]
----- Forwarded by Joanne Tong/Toronto/IBM on 02/07/2006 10:54 AM -----
Martin Rusnak
<[EMAIL PROTECTED]
sk> To
[email protected]
02/06/2006 11:37 cc
AM
Subject
Implementing aggregation of
multiple XSLT results
Hello all,
I would like to use xalan to implement aggregated XML pipeline similar to
the
Cocoon pipeline aggregator. The final document shall be an HTML page
composed
of 2 or more XML fragments which are results of an XSLT transformations.
The problem is, that each XSLT transformer produces startDocument and
endDocument SAX events, so that they occur many times in the final
document.
According to SAX API, it is allowed to call startDocument/endDocument only
once. So, how to solve this problem?
Diagram showing the pipeline configuration:
+------------+
+----| XSLT Trf 1 |<- SAX Evts
+------------------------+ SAX Evts | +------------+
| Aggregated Content Trf |<----------+
+------------------------+ | +------------+
+----| XSLT Trf 2 |<- SAX Evts
+------------+
Simplified code:
TransformerHandler serializerHandler = factory.newTransformerHandler();
serializerHandler.setResult(new StreamResult(out));
TransformerHandler xslHandler1 = factory.newTransformerHandler(templates1);
TransformerHandler xslHandler2 = factory.newTransformerHandler(templates2);
xslHandler1.setResult(new SAXResult(serializerHandler));
xslHandler2.setResult(new SAXResult(serializerHandler));
serializerHandler.startDocument();
serializerHandler.startElement("", "html", "html", HTML_ATTRS);
// other initial elements
xslHandler1.startDocument();
// Generate SAX events for the first fragment
xslHandler1.endDocument();
xslHandler2.startDocument();
// Generate SAX events for the second fragment
xslHandler2.endDocument();
serializerHandler.endElement("", "html", "html");
serializerHandler.endDocument();
Martin