I don't know if this is pertinent to the original question, but I have scenario 
where I have
an XML with data to be transformed by XSL. However, in order to do this the XSL 
may need extra
information which I didn't want to import into the main XML due to having 
several XSL:s each needing
its own extra info.

So I solved it this way: For each XSL I create a new XalanDocument that 
contains the info that the
particular XSL need. Then I provide an extension function "myInfo(...)" that 
takes a string as argument.
This argument is then evaluated as an XPath in the new XalanDocument (external 
to transform) and returns a result tree 
fragment. And it seems to work nicely, not having to copy the XSL specific data 
into the main XML.

I've only tested returning nodesets, and that seems to be working nicely. 
However, I see no reason (yet)
why the function couldn't return an entire tree fragment that in turn would be 
XPath-able.

If this is different from creating XalanNodes from scratch, I apologize for the 
digression.

Note: The XObjectPtr returned from the XPathEvaluator must be cloned upon 
returning it from the 
extension function (but you all know this kind of stuff already... :)

Regards
/Rob

> -----Original Message-----
> From: Mark Weaver [mailto:[EMAIL PROTECTED]
> Sent: Monday, April 28, 2003 3:46 AM
> To: [email protected]
> Subject: RE: Best way to create a XalanNode inside an 
> extension function
> 
> 
> My code doesn't really do anything special.  If you want to 
> use it from a
> stock version (1.4/1.5), you can unintegrate quite easily -- 
> just remove the
> sections that allow you to get a cached nodeset or rtf 
> builder from the
> patch (anything that integrates into XPathExecutionContext,
> XPathExecutionContextDefault or 
> StyleSheetExecutionContextDefault).  (These
> just make the thing easier to use).  You then create a new 
> builder object of
> the appropriate type, passing the execution context to it 
> (which is provided
> to the extension function), and use it as normal, deleting 
> when done.  I can
> give more detail if required, but I'm pretty sure that this 
> is easier than
> reinventing the wheel...
> 
> > -----Original Message-----
> > From: Abram-Profeta, Emmanuel [mailto:[EMAIL PROTECTED]
> > Sent: 25 April 2003 19:21
> > To: [EMAIL PROTECTED]; [email protected]
> > Subject: RE: Best way to create a XalanNode inside an 
> extension function
> >
> >
> > Thanks Dave for your answer. It helps a lot to know that I wasn't
> > too much off-track :-)
> >
> > I'll try to come up with a work-around while working with 1.4 and
> > 1.5. If I manage to pull it off, I may send some user-code
> > snippets for feedback.
> >
> > Emmanuel
> >
> > -----Original Message-----
> > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> > Sent: Friday, April 25, 2003 8:38 AM
> > To: [email protected]
> > Subject: RE: Best way to create a XalanNode inside an 
> extension function
> >
> >
> >
> >
> >
> > 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
> >
> >
> 
> 

Reply via email to