Please read the documentation for XPathEvaluator very carefully.  Here's
what it says in the header file:

   "The user's XObjectPtr copy _must_ no longer be in scope when the
   XPathEvaluator
   instance goes out of scope, or another expression is evaluated."

You must not keep an XObjectPtr around between calls to
XPathEvaluator::evaluate().  The assignment is crashing because the
reference count for the XObject previously being pointed to by xpathResult
is decremented, but that instance has already been deleted.

You must save the value returned as a copy of the actual data type.  You
can do this by calling XObject::getType() and switching on the result to
know which casting function to call, or you can use
XObject::ProcessXObjectTypeCallback() with your own implementation of the
abstract class XObjectTypeCallback which does the right thing.  The first
option is more straightforward, but more implementation dependent.  The
second option involves more code, but is more object-oriented.  Xalan
itself uses both methods, so just grep the source code for examples.

Dave



                                                                                       
                                         
                      "Shang, Crystal"                                                 
                                         
                      <Cshang@rsasecur         To:      "'[EMAIL PROTECTED]'" 
<[EMAIL PROTECTED]>                 
                      ity.com>                 cc:      "Huynh, Dung" 
<[EMAIL PROTECTED]>, (bcc: David N                     
                                               Bertoni/Cambridge/IBM)                  
                                         
                      04/17/2002 06:29         Subject: RE: NodeRefList& operator=     
                                         
                      PM                                                               
                                         
                      Please respond                                                   
                                         
                      to xalan-dev                                                     
                                         
                                                                                       
                                         
                                                                                       
                                         



Hi,

I tried to keep the original XalanDocument around, but it still crashes
somehow. Basically I'm trying to implement on the return result from XPath
evaluation ( See My_Class down below, with nodeList being the return result
). Thinking maybe it's because "XObjectPtr theResult" goes out of scope
after Another_Function returns, so I save it as a member of Another_Class
object, which stays in scope during the whole operation. I have the crash
shown below.

However, if I define some local "XObjectPtr localResult = theResult", then
it doesn't crash. Can you let me know why it's behaving that way? Thanks a
lot!  -- Crystal

class Another_Class {
public:
             Another_Class ();
             virtual ~Another_Class ();

             Another_Function () {
                         ...
                         /* XPath evaluaction */
                         const XObjectPtr theResult (
                                     theEvaluator.evaluate(
                                     *theDOMSupport,
                                     theContextNode,
                                     XalanDOMString(expression).c_str(),
                                     theDocument->getDocumentElement()));

                         xpathResult = theResult;            <--- crashes
here
             }

private:
  XObjectPtr    xpathResult;
};

-----Original Message-----
From: David N Bertoni/Cambridge/IBM [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, April 17, 2002 11:27 AM
To: [EMAIL PROTECTED]
Subject: Re: NodeRefList& operator=



Hi Crystal,

NodeRefList does _not_ do a deep copy, since it's a list of "references" or
pointers to XalanNode instances.  Believe me, you do not want a deep copy
-- the expense would be enormous.

DOM_NodeList works because the Xerces DOM is reference-counted, so the
DOM_Node instances, which are smart-pointers, are copied and the references
counts are maintained.

The XalanDOM is _not_ reference-counted for performance reasons.  You need
to make sure that the XalanDocument instance you're using is in scope the
entire time you want to reference nodes from it.  You may want to make it a
member of your class, depending on the overall flow of data in your system.

By the way this constructor parameter:

             My_Class (const NodeRefList theSource) {

really ought to be:

             My_Class (const NodeRefList& theSource) {

There's no need for this parameter to be passed by value.

Dave



|---------+--------------------------->
|         |           "Shang, Crystal"|
|         |           <Cshang@rsasecur|
|         |           ity.com>        |
|         |                           |
|         |           04/17/2002 10:47|
|         |           AM              |
|         |           Please respond  |
|         |           to xalan-dev    |
|         |                           |
|---------+--------------------------->

>
---------------------------------------------------------------------------
------------------------------------------------|
  |
|
  |        To:      [EMAIL PROTECTED]
|
  |        cc:      "Huynh, Dung" <[EMAIL PROTECTED]>, (bcc: David N
Bertoni/Cambridge/IBM)                                |
  |        Subject: NodeRefList& operator=
|

>
---------------------------------------------------------------------------
------------------------------------------------|



Hi,

The following code crashes on my system. Note if I do the same operation in
the My_Class constructor ( ... xNode->getNodeType() ), everything is fine.
Looks like the copy constructor is not doing a "deep" copy? We're doing the
same thing on DOM_NodeList as well, seems everything works fine. Can you
let
me know if I'm implementing in the right way? Thanks!

class My_Class {
public:
             My_Class (const NodeRefList theSource) {
                         ...
                         nodeList = theSource;

                         /* check the nodeList.getLength() > 0 */
                         XalanNode *xNode = nodeList.item(0);
                         xNode->getNodeType();
 <----- everything is
fine here

             }

             ~My_Class ();

             My_Function() {
                         ...
                         /* check the nodeList.getLength() > 0 */
                         XalanNode *xNode = nodeList.item(0);
                         xNode->getNodeType();
 <----- crashes here
             }

private:
             NodeRefList nodeList;
};

- Crystal










Reply via email to