You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-users@xalan.apache.org by David N Bertoni/Cambridge/IBM <da...@us.ibm.com> on 2002/10/11 18:55:38 UTC
RE: returning xml nodes from extensions functions
"Mark Weaver" <ma...@npsl.co.uk> wrote:
> Sorry about the massive delay on this, I got pulled off onto a very
> lengthy sidetrack. My original question was:
>
No problem, I've been keeping busy! ;-)
> > The second question is that I have some extension functions that return
> > nodesets, containing dynamically generated nodes (these are in fact SQL
> > lookups). I do this by creating a XalanSourceTreeDocument and adding
> > nodes
> > onto this, e.g.:
> >
> >
> > XalanSourceTreeDocument* theDocument = new
XalanSourceTreeDocument(1);
> > XalanSourceTreeElement* sql =
theDocument->createElementNode(L"sql",
> > emptyAttributes, theDocument);
> > theDocument->appendChildNode(sql);
> > XPathExecutionContext::BorrowReturnMutableNodeRefList
> > theNodeList(executionContext);
> > theNodeList->addNode(theDocument);
> > return
executionContext.getXObjectFactory().createNodeSet(theNodeList);
>
> > Now my problem is that this document does not belong to the execution
> > context, and in fact here it belongs to nothing (and is leaked).
Should I
> > just have the function object cache the generated documents, or is
there a
> > better way of doing this?
>
> And your reply of several months ago:
>
> # 2. There are several ways I can think of to accomplish what you're
trying
> # to do. May other folks have some opinions as well.
> #
> # The first is to create your own XNodeSet derivation that contains a
> # pointer to the XalanSourceTreeDocument instance. It can then delete the
> # instance in its destructor. I'm actually thinking of implementing a
> # standard way for extension functions to produce node-sets and result
tree
> # fragments, and this is probably the way I would go, although I think I
> # would use SAX interfaces instead of the DOM interfaces. Any opinions?
> #
> # The other is as you've stated: hold all of the instance in the function
> # instance and have it delete them in its destructor. That has several
> # disadvantages. One is that your function is only thread-safe if you
> # synchronize access to this cache. The other is that the instance live
> # until the function instance is destroyed. This is OK if you're using
> # locally installed extension function instances, but is a disaster if
> # you're using one that's globally installed.
>
> And finally my current thoughts...
>
> The first seems OK to me, although I find the SAX interfaces to be a
little
> clunky. If you end up with a pointer to the XalanSourceTreeDocument, is
> it not reasonable to create the document object by any means?
Well, the interface for building documents _looks_ something like the DOM,
but since the document can only be built in document order, I hesitate to
expose DOM-like interfaces, for fear people will get confused and start
trying to manipulate it like a DOM. That will result in exceptions being
thrown, user confusion, and a support nightmare.
Packaging everything up into a class with a factory in it, and just SAX
interfaces will just be so much easier, I think.
> The main problem I have with this is that in order to create an XNodeSet,
> I have the code as above, where the XNodeSet object is created and
managed by
> the xobject factory, which is in turn managed by the execution context.
In
> order to create a custom XNodeSet, you need to dive into XObjectFactory
> (otherwise its lifetime is not managed by the execution context, which
implies
> the same problem).
Not true. These XObject-derivatives are reference-counted, so yours can
simply destroy itself, along with anything it might own. Take a look at
XSLT/XResultTreeFrag.cpp for an example of what I'm saying.
> Were you suggesting modifying XObjectFactory to allow you to pass in a
custom
> XNodeSet pointer, or maybe a XalanSourceTreeDocument pointer, or perhaps
exposing
> SAX/DOM interfaces from the standard (or a non-standard) nodeset object?
I am
> happy to implement which ever method is viewed as most useful.
If something seems extremely useful, then I'm not at all averse to
integrating into the XOjbectFactory interfaces, if that makes for a more
efficient and straightforward implementation. However, I'd rather
integrate it into the execution context, since I think that will be
cleaner.
I'm very much interested in seeing this happen, so if you want to help with
the implementation, I'm all for it. One thing I've got on the radar is a
version of XalanSourceTreeDocument that allows for nodes to be recycled.
That will be more efficient for things like this, and for result tree
fragments as well.
Dave
RE: returning xml nodes from extensions functions
Posted by David N Bertoni/Cambridge/IBM <da...@us.ibm.com>.
Hi Mark,
Yes, that's very close what I'm thinking. That way, users never need to
know how it's implemented, they just need to understand the interfaces. It
also prevents them from thinking of it as a DOM tree, which it isn't.
One thing that needs to be examined is the "createNodeSet()" aspect. I
think we might have to know about this _before_ we start creating the
nodes, so we may want to have two separate things, each of which is
specialized to do the right thing:
XalanDynamicBuilder*
XPathExecutionContext::getNodeSetBuilder();
XalanDynamicBuilder*
XPathExecutionContext::getResultTreeFragmentBuilder();
That way, we can structure the object we're building while it's being
built, and not after, which might be tricky, and would require more code.
What do you think?
Dave
"Mark Weaver"
<mark@npsl.co.uk To: <xa...@xml.apache.org>
> cc: (bcc: David N Bertoni/Cambridge/IBM)
Subject: RE: returning xml nodes from extensions functions
10/22/2002 03:43
AM
OK, let me see if I've got the right idea. You're suggesting something
like
having a class available from XPathExecutionContext that returns something
that packages a FormatterToDOM along with a couple of functions that can
return either a result tree fragment or a nodeset? So in use, something
like:
ThingyBuilder theThingyBuilder = theExecutionContext.getThingyBuilder();
FormatterToDOM theFormatter = theThingyBuilder.getFormatter();
theFormatter.startElement("blah", AttributeList());
...
theFormatter.endElement();
return theThingyBuilder.createNodeSet();
return theThingyBuilder.createResultTreeFragment();
Does that make sense or am I off the mark here?
Mark
> -----Original Message-----
> From: David N Bertoni/Cambridge/IBM [mailto:david_n_bertoni@us.ibm.com]
> Sent: 11 October 2002 17:56
> To: xalan-c-users@xml.apache.org
> Subject: RE: returning xml nodes from extensions functions
>
>
>
>
>
>
>
> "Mark Weaver" <ma...@npsl.co.uk> wrote:
> > Sorry about the massive delay on this, I got pulled off onto a very
> > lengthy sidetrack. My original question was:
> >
>
> No problem, I've been keeping busy! ;-)
>
> > > The second question is that I have some extension functions
> that return
> > > nodesets, containing dynamically generated nodes (these are
> in fact SQL
> > > lookups). I do this by creating a XalanSourceTreeDocument and adding
> > > nodes
> > > onto this, e.g.:
> > >
> > >
> > > XalanSourceTreeDocument* theDocument = new
> XalanSourceTreeDocument(1);
> > > XalanSourceTreeElement* sql =
> theDocument->createElementNode(L"sql",
> > > emptyAttributes, theDocument);
> > > theDocument->appendChildNode(sql);
> > > XPathExecutionContext::BorrowReturnMutableNodeRefList
> > > theNodeList(executionContext);
> > > theNodeList->addNode(theDocument);
> > > return
> executionContext.getXObjectFactory().createNodeSet(theNodeList);
> >
> > > Now my problem is that this document does not belong to the execution
> > > context, and in fact here it belongs to nothing (and is leaked).
> Should I
> > > just have the function object cache the generated documents, or is
> there a
> > > better way of doing this?
> >
> > And your reply of several months ago:
> >
> > # 2. There are several ways I can think of to accomplish what you're
> trying
> > # to do. May other folks have some opinions as well.
> > #
> > # The first is to create your own XNodeSet derivation that contains a
> > # pointer to the XalanSourceTreeDocument instance. It can then
> delete the
> > # instance in its destructor. I'm actually thinking of implementing a
> > # standard way for extension functions to produce node-sets and result
> tree
> > # fragments, and this is probably the way I would go, although I think
I
> > # would use SAX interfaces instead of the DOM interfaces. Any opinions?
> > #
> > # The other is as you've stated: hold all of the instance in
> the function
> > # instance and have it delete them in its destructor. That has several
> > # disadvantages. One is that your function is only thread-safe if you
> > # synchronize access to this cache. The other is that the instance live
> > # until the function instance is destroyed. This is OK if you're using
> > # locally installed extension function instances, but is a disaster if
> > # you're using one that's globally installed.
> >
> > And finally my current thoughts...
> >
> > The first seems OK to me, although I find the SAX interfaces to be a
> little
> > clunky. If you end up with a pointer to the XalanSourceTreeDocument,
is
> > it not reasonable to create the document object by any means?
>
> Well, the interface for building documents _looks_ something like the
DOM,
> but since the document can only be built in document order, I hesitate to
> expose DOM-like interfaces, for fear people will get confused and start
> trying to manipulate it like a DOM. That will result in exceptions being
> thrown, user confusion, and a support nightmare.
>
> Packaging everything up into a class with a factory in it, and just SAX
> interfaces will just be so much easier, I think.
>
> > The main problem I have with this is that in order to create an
> XNodeSet,
> > I have the code as above, where the XNodeSet object is created and
> managed by
> > the xobject factory, which is in turn managed by the execution context.
> In
> > order to create a custom XNodeSet, you need to dive into XObjectFactory
> > (otherwise its lifetime is not managed by the execution context, which
> implies
> > the same problem).
>
> Not true. These XObject-derivatives are reference-counted, so yours can
> simply destroy itself, along with anything it might own. Take a look at
> XSLT/XResultTreeFrag.cpp for an example of what I'm saying.
>
> > Were you suggesting modifying XObjectFactory to allow you to pass in a
> custom
> > XNodeSet pointer, or maybe a XalanSourceTreeDocument pointer, or
perhaps
> exposing
> > SAX/DOM interfaces from the standard (or a non-standard) nodeset
object?
> I am
> > happy to implement which ever method is viewed as most useful.
>
> If something seems extremely useful, then I'm not at all averse to
> integrating into the XOjbectFactory interfaces, if that makes for a more
> efficient and straightforward implementation. However, I'd rather
> integrate it into the execution context, since I think that will be
> cleaner.
>
> I'm very much interested in seeing this happen, so if you want to
> help with
> the implementation, I'm all for it. One thing I've got on the radar is a
> version of XalanSourceTreeDocument that allows for nodes to be recycled.
> That will be more efficient for things like this, and for result tree
> fragments as well.
>
> Dave
>
>
RE: returning xml nodes from extensions functions
Posted by Mark Weaver <ma...@npsl.co.uk>.
OK, let me see if I've got the right idea. You're suggesting something like
having a class available from XPathExecutionContext that returns something
that packages a FormatterToDOM along with a couple of functions that can
return either a result tree fragment or a nodeset? So in use, something
like:
ThingyBuilder theThingyBuilder = theExecutionContext.getThingyBuilder();
FormatterToDOM theFormatter = theThingyBuilder.getFormatter();
theFormatter.startElement("blah", AttributeList());
...
theFormatter.endElement();
return theThingyBuilder.createNodeSet();
return theThingyBuilder.createResultTreeFragment();
Does that make sense or am I off the mark here?
Mark
> -----Original Message-----
> From: David N Bertoni/Cambridge/IBM [mailto:david_n_bertoni@us.ibm.com]
> Sent: 11 October 2002 17:56
> To: xalan-c-users@xml.apache.org
> Subject: RE: returning xml nodes from extensions functions
>
>
>
>
>
>
>
> "Mark Weaver" <ma...@npsl.co.uk> wrote:
> > Sorry about the massive delay on this, I got pulled off onto a very
> > lengthy sidetrack. My original question was:
> >
>
> No problem, I've been keeping busy! ;-)
>
> > > The second question is that I have some extension functions
> that return
> > > nodesets, containing dynamically generated nodes (these are
> in fact SQL
> > > lookups). I do this by creating a XalanSourceTreeDocument and adding
> > > nodes
> > > onto this, e.g.:
> > >
> > >
> > > XalanSourceTreeDocument* theDocument = new
> XalanSourceTreeDocument(1);
> > > XalanSourceTreeElement* sql =
> theDocument->createElementNode(L"sql",
> > > emptyAttributes, theDocument);
> > > theDocument->appendChildNode(sql);
> > > XPathExecutionContext::BorrowReturnMutableNodeRefList
> > > theNodeList(executionContext);
> > > theNodeList->addNode(theDocument);
> > > return
> executionContext.getXObjectFactory().createNodeSet(theNodeList);
> >
> > > Now my problem is that this document does not belong to the execution
> > > context, and in fact here it belongs to nothing (and is leaked).
> Should I
> > > just have the function object cache the generated documents, or is
> there a
> > > better way of doing this?
> >
> > And your reply of several months ago:
> >
> > # 2. There are several ways I can think of to accomplish what you're
> trying
> > # to do. May other folks have some opinions as well.
> > #
> > # The first is to create your own XNodeSet derivation that contains a
> > # pointer to the XalanSourceTreeDocument instance. It can then
> delete the
> > # instance in its destructor. I'm actually thinking of implementing a
> > # standard way for extension functions to produce node-sets and result
> tree
> > # fragments, and this is probably the way I would go, although I think I
> > # would use SAX interfaces instead of the DOM interfaces. Any opinions?
> > #
> > # The other is as you've stated: hold all of the instance in
> the function
> > # instance and have it delete them in its destructor. That has several
> > # disadvantages. One is that your function is only thread-safe if you
> > # synchronize access to this cache. The other is that the instance live
> > # until the function instance is destroyed. This is OK if you're using
> > # locally installed extension function instances, but is a disaster if
> > # you're using one that's globally installed.
> >
> > And finally my current thoughts...
> >
> > The first seems OK to me, although I find the SAX interfaces to be a
> little
> > clunky. If you end up with a pointer to the XalanSourceTreeDocument, is
> > it not reasonable to create the document object by any means?
>
> Well, the interface for building documents _looks_ something like the DOM,
> but since the document can only be built in document order, I hesitate to
> expose DOM-like interfaces, for fear people will get confused and start
> trying to manipulate it like a DOM. That will result in exceptions being
> thrown, user confusion, and a support nightmare.
>
> Packaging everything up into a class with a factory in it, and just SAX
> interfaces will just be so much easier, I think.
>
> > The main problem I have with this is that in order to create an
> XNodeSet,
> > I have the code as above, where the XNodeSet object is created and
> managed by
> > the xobject factory, which is in turn managed by the execution context.
> In
> > order to create a custom XNodeSet, you need to dive into XObjectFactory
> > (otherwise its lifetime is not managed by the execution context, which
> implies
> > the same problem).
>
> Not true. These XObject-derivatives are reference-counted, so yours can
> simply destroy itself, along with anything it might own. Take a look at
> XSLT/XResultTreeFrag.cpp for an example of what I'm saying.
>
> > Were you suggesting modifying XObjectFactory to allow you to pass in a
> custom
> > XNodeSet pointer, or maybe a XalanSourceTreeDocument pointer, or perhaps
> exposing
> > SAX/DOM interfaces from the standard (or a non-standard) nodeset object?
> I am
> > happy to implement which ever method is viewed as most useful.
>
> If something seems extremely useful, then I'm not at all averse to
> integrating into the XOjbectFactory interfaces, if that makes for a more
> efficient and straightforward implementation. However, I'd rather
> integrate it into the execution context, since I think that will be
> cleaner.
>
> I'm very much interested in seeing this happen, so if you want to
> help with
> the implementation, I'm all for it. One thing I've got on the radar is a
> version of XalanSourceTreeDocument that allows for nodes to be recycled.
> That will be more efficient for things like this, and for result tree
> fragments as well.
>
> Dave
>
>