Our application
implemented a Xalan 2-argument extension function.
The input arguments
to our function were a string, and a document fragment of the processed
XSL.
Our function needed
to get the document fragment (plus descendants) into string format for further
processing.
The function
returned a new DOM Document (as XObject nodeset).
When we used Xalan
1.3, this essentially worked ok, but leaked memory. Later I found recent
corroborating evidence of this problem in the xalanc mail
archive.
See following
thread: http://marc.theaimsgroup.com/?t=103431902900005&r=1&w=2
There seems to be a
patch recommended on Xalan 1.4 (written for Xalan 1.6 dev) to make this
work.
However, when we try
and use 1.4 (which we now prefer) we now get other another problem. It seems as
though it is now not possible to use a XSLTInputSource based on a XalanNode
as input to a transform. The transform throws an exception (when in Xalan 1.3 it
happily accepted this and performed the transform).
I have attached the
XSL and the source code of the extension function.
Any information or
suggestions to accomplish the same outcome.
Cheers,
Dean.
XSL ===
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:cl="http://whatever.com" exclude-result-prefixes="cl"> <xsl:template match="/"> <xsl:variable name="request"> <world/> </xsl:variable> <xsl:variable name="response" select="cl:sendRequest('/', $request)"/> <response><xsl:copy-of select="$response"/></response> </xsl:template> </xsl:stylesheet> EXTENSION FUNCION ================= class XSLSendRequest : public Function { public: virtual XObjectPtr execute( XPathExecutionContext& executionContext, XalanNode* context, const XObjectPtr arg1, const XObjectPtr arg2, const Locator* locator) const { XalanTransformer xalan; std::vector<char> vSpaceName = arg1.get()->str().transcode(); std::string spaceName(vSpaceName.begin(), vSpaceName.end()); const ResultTreeFragBase& inputFrag = arg2.get()->rtree(); // Set input sources XSLTInputSource inputFragSource((XalanNode*)&inputFrag); // create the copy-all XSL input source std::stringstream xslFragStream; xslFragStream << "<xsl:transform version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"; xslFragStream << "<xsl:template match='" << inputFrag.getFirstChild()->getNodeName() << "'>"; xslFragStream << "<xsl:copy-of select='.'/>"; xslFragStream << "</xsl:template>"; xslFragStream << "</xsl:transform>"; XSLTInputSource fragStylesheetSource(&xslFragStream); // Set output target std::stringstream resultStream; XSLTResultTarget resultStreamTarget(&resultStream); // do the transformation xalan.transform(inputFragSource, fragStylesheetSource, resultStreamTarget); // ..... body here uses result Stream to perform local processing ..... // Create result XML to return (fixed for now) std::stringstream xmlStream; xmlStream << "<response/>"; // create the copy-all XSL input source std::stringstream xslStream; xslStream << "<xsl:transform version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"; xslStream << "<xsl:template match='/'>"; xslStream << "<xsl:copy-of select='.'/>"; xslStream << "</xsl:template>"; xslStream << "</xsl:transform>"; XSLTInputSource stylesheetSource(&xslStream); // Set input sources XSLTInputSource inputSource(&xmlStream); //XalanDocument* xalanDoc = executionContext.getDOMFactory(); const DOM_Document theXercesDocument = DOM_Document::createDocument(); XalanDocument* xalanDoc = new XercesDocumentBridge(theXercesDocument, false, false); // Set output target XSLTResultTarget resultTarget(xalanDoc); // do the transformation ##### EXCEPTION RAISED HERE due to inputSource type !!!!! ###### xalan.transform(inputSource, stylesheetSource, resultTarget); XObjectPtr xObj = executionContext.createNodeSet(*xalanDoc->getDocumentElement()); return xObj; } XObjectPtr executeXPath(long hEl, const char *expr) { return NULL; } virtual Function* clone() const { return new XSLSendRequest(*this); } protected: XalanDOMString errorStr; virtual const XalanDOMString getError() const { return errorStr; } // hidden // hidden private: XSLSendRequest& operator=(const XSLSendRequest&); bool operator==(const XSLSendRequest&) const; };
test.xsl
Description: test.xsl
