Hi Emmanuel,
Mark Weaver has submitted code to introduce this functionality, but it did
not make it into 1.5. Once 1.5 is out, I will review the code and
integrate it into the CVS repository, so it will be available soon.
It's rather tricky, because you need a mechanism to track the owner
document of the nodes you create from scratch. Also, you have to build the
document through the use of SAX events, because the tree must be built in
document order.
Dave
"Abram-Profeta,
Emmanuel" To: "Abram-Profeta,
Emmanuel" <[EMAIL PROTECTED]>,
<[EMAIL PROTECTED] <[email protected]>
.com> cc: (bcc: David N
Bertoni/Cambridge/IBM)
Subject: RE: Best way to create
a XalanNode inside an extension function
04/24/2003 12:35
PM
Sorry for repeating this question. I thought Iâd try to clarify my problem
and see if someone has run into similar issue. Iâve had this question for a
while so I am eager to find out what others have to say.
Basically, Iâd like to create a node set inside an extension function. In
pseudo-code, hereâs whatâs going on:
In the stylesheet, I have something like
<xsl:copy-of select="external:myfunc($input)"/>
where $input is a node set defined as:
<xsl:variable name="input" select="/Elements/Element"/>
and documents are like
<?xml version="1.0" encoding="UTF-8"?>
<Elements>
<Element>1</Element>
<Element>2</Element>
</Elements>
In the extension function, the code (vastly simplified) is like
XObjectPtr FunctionPromoCache::execute(
XPathExecutionContext& executionContext, XalanNode* context, const
XObjectArgVectorType& args, const LocatorType* locator) const
{
â
const ResultTreeFragBase& theInput = args[0]->rtree();
std::vector<XalanNode*> theElements
//
// fill the vector with individual XalanNodes
//
XalanNode* pChild = pNode->getFirstChild();
if (!pChild)
{
â
}
do {
if (pChild->getNodeType() != XalanNode::ELEMENT_NODE)
{
continue;
}
theElements.push_back(pChild);
} while (pChild = pChild->getNextSibling());
//
// Create the result â for the sake of this example, without
any change
//
XObjectFactory::BorrowReturnMutableNodeRefList theResult(executionContext);
std::vector<XalanNode*>::const_iterator itNode =
theElements.begin(),endNode = theElements.end();
for (;itNode != endNode; ++itNode)
{
theResult->addNode(*itNode);
}
return executionContext.getXObjectFactory().createNodeSet(theResult);
}
So, this function works as long as the result contains pointers to existing
nodes created during the transform. Here, the XSL statement copy-of will
output
<Element>1</Element>
<Element>2</Element>
My problem is that I would like to create new nodes and embedded the
existing elements in them. For instance, Iâd like the <xsl:copy-of
select="external:myfunc($input)"/> to return something like
<MyElements>
<Element>1</Element>
â
<WeirdElements>
<Element>3</Element>
â
</WeirdElements>
</MyElements>
where Iâd create the MyElements and WeirdElements nodes inside the
extension function.
So my question is, what is the best way to generate new XalanNodes in such
a way that they get properly created and deleted inside the transformation.
Thanks in advance,
Emmanuel
-----Original Message-----
From: Abram-Profeta, Emmanuel
Sent: Wednesday, April 23, 2003 12:39 PM
To: [email protected]
Subject: Best way to create a XalanNode inside an extension function
Hi,
I looked at the extensionFunction sample in Xalan 1.4 and 1.5 and I
am trying to come up with a function that builds new elements
dynamically.
Background: The examples shown deal with string/number like results
(e.g., sqrt, cube, etc). For instance (sorry for the tabsâ)
virtual XObjectPtr
execute(
XPathExecutionContext&
executionContext,
XalanNode*
context,
const XObjectArgVectorType&
args,
const LocatorType*
locator) const
{
â.
return
executionContext.getXObjectFactory().createNumber(sqrt(args[0]->num()));
}
So far, Iâve been able to do the same thing and use the
executionContext.getXObjectFactory().createNodeSet() function to
return XalanNode* pointers belonging to XalanDocument objects output
by a transform or created from a xerces DOM using the
XercesDOMParserLiaison.
However, what Iâd like to do is manually create a XalanNode* that
would be an XML element with embedded elements within; The difference
here is that I am not reusing pointers to locations of existing
documents. Iâm aware that it may sound like a trivial question but
after experimenting with the XalanDOM and the XalanSourceTree
classes, I noticed that thereâs still a lot of functionality that
remains to be implemented. (Hence my questions.)
One trivial way I thought of was to just create a string containing
the XML I need and parse it inside the extension function. But Iâm
sure thereâs a smarter and better way to just say âcreate this
XalanNode with this name, append this node set, etc.â.
Thanks in advance for any help,
Emmanuel