Title: Message
 
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;
};

Attachment: test.xsl
Description: test.xsl

Reply via email to