[xsd-users] <any> and xerces cloneNode

Boris Kolpackov boris at codesynthesis.com
Tue Dec 9 04:34:33 EST 2008


Hi Ray,

Ray Lischner <rlischner at proteus-technologies.com> writes:

> But it doesn't work. I keep getting memory errors. 

The way Xerces-C++ works, a DOMNode instance always belongs to
some DOMDocument. We implement wildcard mapping in XSD 3-series
by including a private DOMDocument object into each type that has
a wildcard. This document contains all the DOM nodes corresponding
to the wildcard content.

Your code, on the other hand, simply stores a pointer to the the
DOM node that belongs to the DOMDocument being parsed. This will
only work if you maintain DOM association which implies that the
DOM document is guaranteed to be available for as long as the
object model. Otherwise, your object model points to a DOMNode
that is destroyed as soon as parsing is finished.

If you are not maintaining the DOM association, then your code 
needs a major rework. I suggest that you grab XSD 3.2.0, compile
your Any type with --generate-wildcard, and copy the wildcard
storage logic to your XSD 2.3.1 code.

If you are maintaining the DOM association, then:

>   : AnyBase(dom, f, c), any_(dom.getFirstChild())

This is actually dangerous, since the first child can be a 
whitespace-only text node.


>   Any(Any const& other, xml_schema::flags f=0, xml_schema::type* c=0)
>   : Any(other, f, c), any_(other.any())

This is a shallow copy, which means the new instance will point to
the DOM node in another object model.


> void any(xercesc::DOMNode const* any) { any_ = any ? any->cloneNode() : 0; }

Unless you know for sure that 'any' belongs to the same document 
as the one associated with the object model, you will need to use 
importNode() here.


> void operator<<(xercesc::DOMElement& e, Any& a)
> {
>   e << static_cast<AnyBase const&>(a);
>   if (a.any() != 0) {
>     xercesc::DOMNode* n = e.getOwnerDocument()->importNode(a.any());

You will need to pass true as the second argument to make sure it
is a recursive copy:

xercesc::DOMNode* n = e.getOwnerDocument()->importNode(a.any(), true);

Boris




More information about the xsd-users mailing list