Boost logo

Boost :

From: Hamish Mackenzie (hamish_at_[hidden])
Date: 2003-06-26 18:14:59


On Thu, 2003-06-26 at 21:39, Stefan Seefeld wrote:
> Hamish Mackenzie wrote:
>
> > dom::document doc;
> > dom::document_ref doc2( doc.root().document() );
> > assert( &doc2 == &doc );
> >
> > and...
> >
> > assert( doc2 == doc );
> >
> > Can be implemented but ideally it would compare all the nodes in the
> > document.
>
> well, that's different. Do you want to know whether both documents are
> equal, or whether they are identical, i.e. whether both references point
> to the same document ?

&doc2 == &doc would test if doc and doc2 refer to the same libxml2 doc
doc2 == doc would compare documents to see if they are equal

I think you could do the same for nodes. The equality check would look
only at child nodes (otherwise you might as well compare the documents)

> Hmm, just to check whether we are still talking about the same thing
> here: do we agree that there can't be a 'node' type, i.e. just a
> 'node_ref'/'node_ptr' ?
>
> Else it would be impossible to make that API a wrapper around libs like
> libxml2.

I can live without a node class. And I don't know if it would be any
easier to make a deep copy node in MSXML or any other xml lib.

I don't think it is "impossible" just not very easy or efficient. You
would have to copy the entire document into the node or at least part of
it. Even then you would still need node_ptr and node_ref. node could
look like this...

class node_ref
{
public:
  // All the node members
protected:
  xmlNode * raw_node_;
};

class node : public node_ref
{
public:
  node( node_ref source ) : doc_( source.document() )
  {
    raw_node_ = find_same_node_somehow( doc_, source );
    // find_same_node_somehow would look up the copy of
    // the source node in the copy of the document.
  }

private:
  document doc_;
};

document doc( "test.xml" );
node new_node( doc.root() );

node_ref root = doc.root();
assert( new_node == root );
assert( &new_node != &root );

document_ref new_doc = new_node.document();
assert( new_doc == doc );
assert( &new_doc != &doc ) ;

So even erasing the root node of doc would not invalidate new_node, as
new_node has it's own copy of the document which includes all the nodes
children, parents and siblings.

I think it would work but it seems a little bonkers for value_type to
require an entire copy of the container.

I suppose you could just implement 'element' and restrict the coying to
the child nodes and not other relatives. That way the node in question
would also be the root node of the copied document. Can any element be
made the root of a new libxml2 document? And does it make sense that
new_node.parent() would return null even if the original was not a root
node?

My gut feeling is that references, pointers and iterators only is best.

-- 
Hamish Mackenzie <hamish_at_[hidden]>

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk