[xml] 2 Problems

Date view Thread view Subject view Author view

From: Charlie Bozeman (cbozeman@HiWAAY.net)
Date: Sat Nov 25 2000 - 11:39:55 EST


I have discovered two problems, the first I have a solution for and the
second needs discussion.

First Problem:
If an application copies a tree or subtree the doc pointer for every
node does not get set to the proper document. Try: xmllint --copy
--debug test/ns. The properties of an element are not getting the doc
pointer set. I have investigated the code an bit and I have found that
when nodes get attached to a tree the doc pointer is only set in the
attached nodes if the doc pointers differ; the subtree that is being
attached may have new nodes that do not have a doc pointer set at all. I
have included a patch that a) modifies xmlSetTreeDoc so that it
unconditionally sets the doc pointer in all nodes of the given tree
(including properties), b) every routine that attaches a subtree will
set the doc pointer to the parent (or sibling) doc pointer if the parent
doc pointer is not NULL.

Second Problem:
My application copies a subtree from one part of the document to another
(possibly in multiple places) using the xmlCopyNode routine.
xmlStaticCopyNode creates an new namespace definition in the subtree to
match the one it was previously using. When I post-process the tree, the
test "if (cur->ns == ns) fails because the namespace pointers are
pointing to different namespace definitions in the tree even though
their content is the same. My workaround was to set the namespace
definition in the "copied" subtree to NULL and set the ns pointers to
the original.

I believe this is also the problem where a document with a DTD reference
cannot be copied with the xmlCopyDoc procedure; xmlStaticCopyNode
creates a new namespace definition on the top of the subtree even if it
is not an element or attribute node. Try xmllint --copy --debug
test/dtd1, it will segfault.

After looking at the code I can see why the namespace definition was
created but I don't think this is the best solution. I probably don't
know all the implications of the workings of namespaces but I have a
possible solution.

Create a global hash table that contains all the namespace uri's; this
is can be what the node ns pointers reference. This will allow the test
(cur->ns == ns) for namespace equality to still be used independent of
namespace declaration and document. The namespace definitions can remain
the same (or similar) but the prefix would have to be stored in the
element and attribute nodes.

I may be missing something but this could be an simple fix. What do
y'all think.

Charlie Bozeman

PS the patch is against libxml2-2.2.10

*** tree.c Sat Nov 25 09:42:41 2000
--- tree.orig Sat Nov 25 04:39:37 2000
*************** xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr
*** 1704,1714 ****
          return;
      if (tree->type == XML_ENTITY_DECL)
          return;
! if (tree->children != NULL)
! xmlSetListDoc(tree->children, doc);
! if ((tree->type == XML_ELEMENT_NODE) && (tree->properties != NULL))
! xmlSetListDoc((xmlNodePtr)tree->properties, doc);
! tree->doc = doc;
  }
  
  /**
--- 1704,1714 ----
          return;
      if (tree->type == XML_ENTITY_DECL)
          return;
! if (tree->doc != doc) {
! if (tree->children != NULL)
! xmlSetListDoc(tree->children, doc);
! tree->doc = doc;
! }
  }
  
  /**
*************** xmlSetListDoc(xmlNodePtr list, xmlDocPtr
*** 1726,1732 ****
          return;
      cur = list;
      while (cur != NULL) {
! xmlSetTreeDoc(cur, doc);
          cur = cur->next;
      }
  }
--- 1726,1733 ----
          return;
      cur = list;
      while (cur != NULL) {
! if (cur->doc != doc)
! xmlSetTreeDoc(cur, doc);
          cur = cur->next;
      }
  }
*************** xmlAddNextSibling(xmlNodePtr cur, xmlNod
*** 1857,1863 ****
          }
      }
  
! if (cur->doc != NULL) {
          xmlSetTreeDoc(elem, cur->doc);
      }
      elem->parent = cur->parent;
--- 1858,1864 ----
          }
      }
  
! if (elem->doc != cur->doc) {
          xmlSetTreeDoc(elem, cur->doc);
      }
      elem->parent = cur->parent;
*************** xmlAddPrevSibling(xmlNodePtr cur, xmlNod
*** 1929,1935 ****
          }
      }
  
! if (cur->doc != NULL) {
          xmlSetTreeDoc(elem, cur->doc);
      }
      elem->parent = cur->parent;
--- 1930,1936 ----
          }
      }
  
! if (elem->doc != cur->doc) {
          xmlSetTreeDoc(elem, cur->doc);
      }
      elem->parent = cur->parent;
*************** xmlAddSibling(xmlNodePtr cur, xmlNodePtr
*** 2000,2006 ****
          return(cur);
      }
  
! if (cur->doc != NULL) {
          xmlSetTreeDoc(elem, cur->doc);
      }
      parent = cur->parent;
--- 2001,2007 ----
          return(cur);
      }
  
! if (elem->doc != cur->doc) {
          xmlSetTreeDoc(elem, cur->doc);
      }
      parent = cur->parent;
*************** xmlAddChildList(xmlNodePtr parent, xmlNo
*** 2085,2091 ****
      }
      while (cur->next != NULL) {
          cur->parent = parent;
! if (parent->doc != NULL) {
              xmlSetTreeDoc(cur, parent->doc);
          }
          cur = cur->next;
--- 2086,2092 ----
      }
      while (cur->next != NULL) {
          cur->parent = parent;
! if (cur->doc != parent->doc) {
              xmlSetTreeDoc(cur, parent->doc);
          }
          cur = cur->next;
*************** xmlAddChild(xmlNodePtr parent, xmlNodePt
*** 2166,2172 ****
       * add the new element at the end of the children list.
       */
      cur->parent = parent;
! if (parent->doc != NULL) {
          xmlSetTreeDoc(cur, parent->doc);
      }
  
--- 2167,2173 ----
       * add the new element at the end of the children list.
       */
      cur->parent = parent;
! if (cur->doc != parent->doc) {
          xmlSetTreeDoc(cur, parent->doc);
      }
  
*************** xmlCopyDoc(xmlDocPtr doc, int recursive)
*** 2737,2743 ****
              tmp = tmp->next;
          }
      }
- xmlSetTreeDoc(ret->children, ret);
      return(ret);
  }
  
--- 2738,2743 ----

----
Message from the list xml@rpmfind.net
Archived at : http://xmlsoft.org/messages/
to unsubscribe: echo "unsubscribe xml" | mail  majordomo@rpmfind.net


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Sat Nov 25 2000 - 11:43:53 EST