Hi Dean,

A couple of points:

   1. Can you set your mail client for plain-text only?  It's really a pain
   for some of us when messages are sent in HTML, and it makes the archives
   harder to read.

   2. I don't see why Xalan would have a problem with either
   XSTLInputSource, since neither is created with a XalanNode instance.
   Aren't they both std::istream derivates?  Or are you really referring to
   the previous transformation which is using the RTF?

   3. Trying to use an RTF as the input to a transformation is going to be
   dicey at best.  I can't help but think there would be a better way to
   accomplish you goal with out resorting to an extension function which
   itself does two separate transformations.  Perhaps taking a few steps
   back and looking at the overall process would help?  One thing that
   comes to mind is that you can always use a meta-stylesheet to generate a
   more specific stylesheet, and not do transformations within your
   extension function.  Does that make any sense to you?  Also, it looks to
   me like your code is making a copy of _part_ of the input RTF.  Perhaps
   using the node-set() function to turn your RTF into a node-set, then
   doing something with that _within_ your stylesheet would be a better way
   to go.  Or am I completely misunderstanding what your function is doing?

By the way, this is the memory leak:

   XalanDocument* xalanDoc = new XercesDocumentBridge(theXercesDocument,
   false, false);

It's also not clear to me why you're using a Xerces DOM_Document instance
here.  An instance of Xalan's default source tree, populated using a
FormatterToSourceTree instance would be much more efficient.  At any rate,
because you create the XercesDocumentBridge instance, you are required to
destroy it.  I would suggest you keep track of anything you create in your
extension function, and delete it once the transformation has finished.
(That's a very difficult task to manage, which is why Mark has submitted
his code.)

Dave



                                                                                
                                        
                      "Dean O'Connor"                                           
                                        
                      <[EMAIL PROTECTED]         To:                            
                                          
                      e.com.au>                cc:      (bcc: David N 
Bertoni/Cambridge/IBM)                            
                                               Subject: Re: Xalan Exention 
function transforming document fragment      
                      04/10/2003 06:09                                          
                                        
                      PM                                                        
                                        
                                                                                
                                        



david,

thx for your response. I get the impression my attachments didn't get
distributed. So I have embedded them in this email, as I think it might
shed a little more light on what we are trying to do.

for anyone else with suggestions .... my original question is at the end of
this email.

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;
};

-----Original Message-----
From: Dean O'Connor
Sent: Thursday, 10 April 2003 6:34 PM
To: [email protected]
Subject: Q: Xalan Exention function transforming document fragment


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.[attachment "source.txt" deleted by David N Bertoni/Cambridge/IBM]

Reply via email to