xmlwrapp
Lightweight C++ XML parsing library
Tips, Tricks and Warnings

Iterators and Object Lifetimes

Because of the way xmlwrapp is implemented, you must be careful with pointers and references that you take from xmlwrapp iterators. The pointers and references will only be valid as long as the iterator is valid.

From the xmlwrapp-users mailing list:

From: Peter Jones xmlwr.nosp@m.app@.nosp@m.pmade.nosp@m..org
Subject: Re: [xmlwrapp-users] Potential bug in xml::node::iterator dereferencing?
Date: Fri, 21 Mar 2003 07:47:05 -0800
It does seem strange on the surface that xml::node::iterator has an
xml::node as a member variable. However, xml::node::iterator is really a
shell class that uses the pimpl idiom to contain another class, and that
class is what holds the xml::node.
I would much prefer to emulate the standard containers in this respect,
and I would love to hear any suggestions on how this might be done.
Let me explain the problem as I see it, and maybe you and others can
point me in the right direction.
xml::node is somewhat like a std::list. From the outside it looks as if
xml::node is a container for other xml::node objects, however, this is
not true. The objects that xml::node contains are really pointers to
libxml2 data structures.
I decided early on that, unlike other libxml2 C++ libraries, xmlwrapp
should not try to duplicate the XML tree using C++ containers, but
instead emulate that container interface and adapt it to the libxml2
function calls.
It is quite easy for the standard containers to return a valid
pointer/reference to their contained objects since those objects are
already in memory, and will be around until the container goes away or
an operation is preformed on that container that would invalidate those
pointers/references.
But, xml::node is keeping pointers to xmlNode structs, not xml::node
classes. This means that the xml::node::iterators could return pointers
to xmlNode structs that out live the iterator, but that is not what
users would expect.
Currently, the xml::node::iterator will use its xml::node member
variable as a way to pretend that xml::node objects are containers for
other xml::node objects. This is why the lifetime of the xml::node is
limited to the lifetime of the xml::node::iterator.

Debugging

Any xml::node object can be easily examined by dumping it to a string using its xml::node::node_to_string() method or by outputting it into any standard stream:

xml::node n = ...;
std::cout << "Contents of the node: " << n;

Notice that the node_to_string() function can even be called from a debugger to see the contents of the node during a debugging session.