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 Ashay Shende <as...@cisco.com> on 2003/03/04 17:05:14 UTC

Problem with executing XPath Expressions using Xalan

Hi,
I am working with Xerces 2.1 and Xalan 1.4. I have written a
function,findNodes(), for evaluating XPath expressions. It takes a ptr to a
DOM_Node(the context node), the XPath exprssion in string format and a ptr
to a vector of DOM_Nodes. Basically, i create a XercesDocumentBridge in the
function, map the DOM_Node to a XalanNode using the bridge, and evaluate the
XPath expression.

The problem that i am facing is that when I call the findNodes() function a
couple of times, it works fine. But it fails the third time I call it.
However, when I remove the 2nd call to findNodes(), the 3rd call strangely
succeeds.

Can someone give me pointers as to why this is happening ?? Am i going wrong
somewhere in the function ? 

I have given the code in detail below....



THE CODE:
****************************************************************************
*************
findNodes(DOM_Node* theContextNode, string paramXPathExpr,vector<DOM_Node>
*paramVect)
{
        DOM_Document* theOwnerDoc = new DOM_Document();
        *theOwnerDoc = theContextNode->getOwnerDocument();
        XercesDocumentBridge *theXDBridge  = new
XercesDocumentBridge(*theOwnerDoc,false,false);
        //map Xerces node of type DOM_Node to Xalan node
        XalanNode* xalContextNode = theXDBridge->mapNode(*theContextNode);
        //Evaluate the XPath Expr
	  char *buff = new char[500];
        memset(buff,0,500);
        paramXPathExpr.copy(buff, paramXPathExpr.length());
	  //theEvaluator is a member variable of the class of which
findNodes() is a member 	//function
        NodeRefList nodeList = theEvaluator->selectNodeList(theDOMSupport,
                                                            xalContextNode,
 
XalanDOMString(buff).c_str(),
 
theXDBridge->getDocumentElement());

        //Insert the nodes from the NodeList into the vector
        for(int i = 0; i < nodeList.getLength(); i++)
        {
                //Map the node to DOM_Node
                DOM_Node theNode = theXDBridge->mapNode(nodeList.item(i));
                paramVect->push_back(theNode);
        }


        delete xalContextNode;
        delete theXDBridge;
        delete theOwnerDoc;
	  delete buff;	

}
****************************************************************************
**************

Re: Problem with executing XPath Expressions using Xalan

Posted by Ashay <as...@yahoo.com>.
Hello David,Thank you for the detailed help. I appreciate it.  I have done away with the dynamic creation of objects in my function and it seems to be working fine. I am passing pointers to the Xerces objects mainly because in some functions I need to change the passed object like appending children to the passed DOM_Node etc. And this seems the only solution. And I am not deleting them in my functions. Also, in case there is a version change to a latter version where the DOM APIs are implemented as  pointers(DOMNode* rootNode = doc->getDocumentElement()), the interfaces probably wouldn't have to be changed where my functions are recieving pointers to objects. I have some more queries:1) would initializing and terminating the XPathEvaluator once rather than doing it in the function where I need it cause a considerable increase in speed ? 2) my XSL file looks for elements with prefixes ..eg abc:element_name.Also i have to apply a namespace to my DOM(DOM_Document class). How do i do it so that the namespace and prefix gets applied to the dom and the XSL file matches the DOM object and the transformation takes place properly.
 That's all for now. ( I am still learning :-) thanks again..cheersAS.
david_n_bertoni@us.ibm.com wrote:



This line of code is the problem:

delete xalContextNode;

You don't own that pointer, so you should not delete it. I'm surprised
it's not crashing your program.

You are also mis-using the old Xerces DOM. You should never pass DOM_Node
or its derivates around as pointers. They are smart-pointers to the
actually implementation instances, so they must be passed by value to
maintain the reference counts properly. Fix your code so these classes are
used by value, then see what happens. Also, a more complete description of
the problem, rather than "fails" will help diagnose the problem.

By the way, what is the value of copying the data from paramXPathExpr to a
dynamically allocated buffer, just for creating a XalanDOMString? You can
easily do that directly from paramXPathExpr:

XalanDOMString(paramXPathExpr.data(), paramXPathExpr.size()).c_str()

In fact, you seem to be using dynamically-allocated objects far more than
you need to be. Using stack-based instances is much more exception safe,
and much more efficient:

findNodes(DOM_Node theContextNode, const string&
paramXPathExpr,vector
*paramVect)
{
XercesDocumentBridge
theXDBridge(theContextNode.getOwnerDocument(),false,false);

....
}

Note there's no reason to pass paramXPathExpr by value either. Using by
(const) reference is the canonical way to pass something like a std::string
into a function.

Dave




"Ashay Shende" 

om> cc: (bcc: David N Bertoni/Cambridge/IBM) 
Subject: Problem with executing XPath Expressions using Xalan 
03/04/2003 08:05 
AM 




Hi,
I am working with Xerces 2.1 and Xalan 1.4. I have written a
function,findNodes(), for evaluating XPath expressions. It takes a ptr to a
DOM_Node(the context node), the XPath exprssion in string format and a ptr
to a vector of DOM_Nodes. Basically, i create a XercesDocumentBridge in the
function, map the DOM_Node to a XalanNode using the bridge, and evaluate
the
XPath expression.

The problem that i am facing is that when I call the findNodes() function a
couple of times, it works fine. But it fails the third time I call it.
However, when I remove the 2nd call to findNodes(), the 3rd call strangely
succeeds.

Can someone give me pointers as to why this is happening ?? Am i going
wrong
somewhere in the function ?

I have given the code in detail below....



THE CODE:
****************************************************************************

*************
findNodes(DOM_Node* theContextNode, string paramXPathExpr,vector
*paramVect)
{
DOM_Document* theOwnerDoc = new DOM_Document();
*theOwnerDoc = theContextNode->getOwnerDocument();
XercesDocumentBridge *theXDBridge = new
XercesDocumentBridge(*theOwnerDoc,false,false);
//map Xerces node of type DOM_Node to Xalan node
XalanNode* xalContextNode = theXDBridge->mapNode(*theContextNode);
//Evaluate the XPath Expr
char *buff = new char[500];
memset(buff,0,500);
paramXPathExpr.copy(buff, paramXPathExpr.length());
//theEvaluator is a member variable of the class of which
findNodes() is a member //function
NodeRefList nodeList = theEvaluator->selectNodeList(theDOMSupport,
xalContextNode,

XalanDOMString(buff).c_str(),

theXDBridge->getDocumentElement());

//Insert the nodes from the NodeList into the vector
for(int i = 0; i < nodeList.getLength(); i++)
{
//Map the node to DOM_Node
DOM_Node theNode = theXDBridge->mapNode(nodeList.item(i));
paramVect->push_back(theNode);
}


delete xalContextNode;
delete theXDBridge;
delete theOwnerDoc;
delete buff;

}
****************************************************************************

**************



---------------------------------
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.

Re: Problem with executing XPath Expressions using Xalan

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



This line of code is the problem:

        delete xalContextNode;

You don't own that pointer, so you should not delete it.  I'm surprised
it's not crashing your program.

You are also mis-using the old Xerces DOM.  You should never pass DOM_Node
or its derivates around as pointers.  They are smart-pointers to the
actually implementation instances, so they must be passed by value to
maintain the reference counts properly.  Fix your code so these classes are
used by value, then see what happens.  Also, a more complete description of
the problem, rather than "fails" will help diagnose the problem.

By the way, what is the value of copying the data from paramXPathExpr to a
dynamically allocated buffer, just for creating a XalanDOMString?  You can
easily do that directly from paramXPathExpr:

      XalanDOMString(paramXPathExpr.data(), paramXPathExpr.size()).c_str()

In fact, you seem to be using dynamically-allocated objects far more than
you need to be.  Using stack-based instances is much more exception safe,
and much more efficient:

   findNodes(DOM_Node theContextNode, const string&
   paramXPathExpr,vector<DOM_Node>
   *paramVect)
   {
       XercesDocumentBridge
   theXDBridge(theContextNode.getOwnerDocument(),false,false);

       ....
   }

Note there's no reason to pass paramXPathExpr by value either.  Using by
(const) reference is the canonical way to pass something like a std::string
into a function.

Dave



                                                                                                                                  
                      "Ashay Shende"                                                                                              
                      <ashende@cisco.c         To:      "xalan-c-users" <xa...@xml.apache.org>                            
                      om>                      cc:      (bcc: David N Bertoni/Cambridge/IBM)                                      
                                               Subject: Problem with executing XPath Expressions using Xalan                      
                      03/04/2003 08:05                                                                                            
                      AM                                                                                                          
                                                                                                                                  



Hi,
I am working with Xerces 2.1 and Xalan 1.4. I have written a
function,findNodes(), for evaluating XPath expressions. It takes a ptr to a
DOM_Node(the context node), the XPath exprssion in string format and a ptr
to a vector of DOM_Nodes. Basically, i create a XercesDocumentBridge in the
function, map the DOM_Node to a XalanNode using the bridge, and evaluate
the
XPath expression.

The problem that i am facing is that when I call the findNodes() function a
couple of times, it works fine. But it fails the third time I call it.
However, when I remove the 2nd call to findNodes(), the 3rd call strangely
succeeds.

Can someone give me pointers as to why this is happening ?? Am i going
wrong
somewhere in the function ?

I have given the code in detail below....



THE CODE:
****************************************************************************

*************
findNodes(DOM_Node* theContextNode, string paramXPathExpr,vector<DOM_Node>
*paramVect)
{
        DOM_Document* theOwnerDoc = new DOM_Document();
        *theOwnerDoc = theContextNode->getOwnerDocument();
        XercesDocumentBridge *theXDBridge  = new
XercesDocumentBridge(*theOwnerDoc,false,false);
        //map Xerces node of type DOM_Node to Xalan node
        XalanNode* xalContextNode = theXDBridge->mapNode(*theContextNode);
        //Evaluate the XPath Expr
               char *buff = new char[500];
        memset(buff,0,500);
        paramXPathExpr.copy(buff, paramXPathExpr.length());
               //theEvaluator is a member variable of the class of which
findNodes() is a member              //function
        NodeRefList nodeList = theEvaluator->selectNodeList(theDOMSupport,
                                                            xalContextNode,

XalanDOMString(buff).c_str(),

theXDBridge->getDocumentElement());

        //Insert the nodes from the NodeList into the vector
        for(int i = 0; i < nodeList.getLength(); i++)
        {
                //Map the node to DOM_Node
                DOM_Node theNode = theXDBridge->mapNode(nodeList.item(i));
                paramVect->push_back(theNode);
        }


        delete xalContextNode;
        delete theXDBridge;
        delete theOwnerDoc;
               delete buff;

}
****************************************************************************

**************