Re: [xml] using xmlDocSetRootElement to move nodes between documents

On 27/07/04 20:17, Martijn Faassen wrote:
Igor Zlatkovic wrote:

On 27/07/04 19:11, Martijn Faassen wrote:


is moving nodes between documents in general not supported this way?

No, it isn't. You must call xmlUnlinkNode to get the node out of the first document. Then you can insert it into the new document. And take a good care about namespaces, should either document use them.

Unless I'm missing something, this cannot be it, as xmlDocSetRootElement() calls xmlUnlinkNode on the node in any case:

xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
    xmlNodePtr old = NULL;

    if (doc == NULL) return(NULL);
    if (root == NULL)

Okay, that is an argument :)

I also tried using xmlSetTreeDoc, but that doesn't help either (and it's hard to say what to call it in the original document, as I'm moving the document element).

A little debugging and I saw a nice thing. The text node which contains the text "Foo" still links to the first document after the call to xmlDocSetRootElement. Referring to your example, we have

Seeing it from the debugger's context, after the call to xmlDocSetRootElement we have:

  (gdb) print doc2->children->children->doc
  $1 = (struct _xmlDoc *) 0xa013228
  (gdb) print doc2
  $2 = (xmlDoc *) 0xa010008
  (gdb) print doc1
  $3 = (xmlDoc *) 0xa013228

The next statement frees the doc1, leaving the text node's doc to point to an address which has been freed. I guess something then tries to access this address during xmlFreeDoc(doc2).

Well, traversing the tree and resetting each node's doc pointer to the new document is easy enough, but it isn't a general solution. What if a node belongs to a namespace defined by one of its ancestors? What if the new document has a DTD different to the old? Considering all the possibilities in a generic way doesn't sound trivial to me.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]