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]