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 "KHARE,MAYANK (HP-India,ex2)" <ma...@hp.com> on 2003/06/20 17:55:59 UTC

XalanNode.cloneNode() issue !!

Hi,

I'm new to XSL and related technologies. Was trying my hands on Xalan 1.5
library for C++ and faced the following issue:

Actually I tried to perform a Xpath query on a XML document. Xpath Query is
working fine. The problem is to encapsulate the query result(XObjectPtr)
into my own class to use it somewhere else later on. I've got a cloning
method in my QueryResult wrapper class(see attached code snippet below) to
clone all the XalanNodes which are available via XObjectPtr just after the
successful query(witin the scope of MyXPathQuery::query function). I'm
opting for cloning becoz as the XObjectPtr will go out of scope it's
reference count would be reduced to 0 and it will become invalid. I tried
making a copy of XObjectPtr(by assingment operator) returned by the query
but Xalan library is throwing an assertion immediately when query() function
is exiting and this is happening when XObjectPtr is getting deleted. (In
~XalanReferenceCountedObject()). According to my understanding it sud't
happen.

Deep Cloning works fine as long as I'm using the cloned object till original
Xpointer object is valid. After original Xpointer object dies(immediately
after MyXPathQuery::query exited) all the string based data in CLONED
XalanNodes becomes invalid (all attribute/element values and names). This is
happening inspite of DEEP CLONING.

Now my dilema is How can I use the QueryResult somewhere else outside the
scope of MyXPathQuery::query. Copying of XObjectPtr is not allowed(Assertion
failure) and Cloning just not seems to be working. :-(

I'm pasting the snippet of my code for better understanding. 
Any clue wud be of great help to me.

Thanks in advance
Mayank


Class UseQueryResultHere
{
   bool processResult
   {
       MyXPathQuery xpQuery;
       QueryResult result = xpQuery.query(......);
       
	 // This will access the cloned query result XalanNode's attribute
and will CRASH 
       result.doSomething()    
    }
}

Class MyXPathQuery
{
    QueryResult query(XMLinCharVector, context, path)
    {
	  QueryResult retObj; 
        // Do all the necessary Xpath related stuff
        xObj = xpath->execute(......);
	  retObj.setQueryResult(&xObj);
	  retObj.cloneXalanNodes();
 
        return retObj;
     }
}

Class QueryResult
{
    XObjectPtr m_objPtr;
    vector<XalanNode*> m_xalanNodes;	

Public:
    void cloneXalanNodes()
    {
       // Simply fetches
        if( (*m_xObjectPtr)->getType() == XObject::eTypeNodeSet )
        {
            const NodeRefListBase& nodeset = (*m_xObjectPtr)->nodeset();
            size_t len = nodeset.getLength();

            XalanNode* L_tmp = 0;
            for (size_t i=0; i<len; i++)
            {
                XalanNode* node = nodeset.item(i);
                L_tmp = node->cloneNode(true);
                m_xalanNodes.push_back(L_tmp);
            }
        }
     }
}

Re: XalanNode.cloneNode() issue !!

Posted by da...@us.ibm.com.



> I'm new to XSL and related technologies. Was trying my hands on Xalan 1.5
> library for C++ and faced the following issue:
>
> Actually I tried to perform a Xpath query on a XML document. Xpath Query
is
> working fine. The problem is to encapsulate the query result(XObjectPtr)
> into my own class to use it somewhere else later on. I've got a cloning
> method in my QueryResult wrapper class(see attached code snippet below)
to
> clone all the XalanNodes which are available via XObjectPtr just after
the
> successful query(witin the scope of MyXPathQuery::query function). I'm
> opting for cloning becoz as the XObjectPtr will go out of scope it's
> reference count would be reduced to 0 and it will become invalid. I tried
> making a copy of XObjectPtr(by assingment operator) returned by the query
> but Xalan library is throwing an assertion immediately when query()
function
> is exiting and this is happening when XObjectPtr is getting deleted. (In
> ~XalanReferenceCountedObject()). According to my understanding it sud't
> happen.

Cloning is almost never necessary, nor ever efficient.  The pointers
returned in the XObject are pointers into your instance document, so as
long as that is in scope, all you have to do is copy the pointers to your
own data structure.  Are you using the default implementation of Xalan's
source tree, or are you wrapping the Xerces DOM for these XPath searches?
The general rule is if you're going to modify the DOM instance, you should
use the Xerces DOM and wrap it for Xalan.  If you're not going to modify
the DOM, and you're just parsing a stream of XML to create it, use Xalan's
default source tree.

If you are wrapping the Xerces DOM, you need to recover the original Xerces
DOM nodes from the Xalan wrapper nodes.  Please provide a _small_ snippet
of code which shows how your are building the tree and how you do the XPath
query.  There are member functions provided to map Xalan nodes to Xerces
nodes so you can do this.

> Deep Cloning works fine as long as I'm using the cloned object till
original
> Xpointer object is valid. After original Xpointer object dies(immediately
> after MyXPathQuery::query exited) all the string based data in CLONED
> XalanNodes becomes invalid (all attribute/element values and names). This
is
> happening inspite of DEEP CLONING.

What is this Xpointer object you're talking about?  We don't have a class
by that name in Xalan-C.  As I said before, cloning is rarely necessary,
and it's irrelevant whether or not you're using deep cloning.

>        if( (*m_xObjectPtr)->getType() == XObject::eTypeNodeSet )

XObjectPtr has its own operator->() defined, so you can just do this:

   if( m_xObjectPtr->getType() == XObject::eTypeNodeSet )

Dave