[XML-SIG] merging two separate DOM trees.

Jeremy J. Sydik jsydik@virtualparadigm.com
Mon, 03 Apr 2000 00:53:10 -0500


I ran into the same issue ~a month ago.  The options you have is best
solved with the DOM Level 2 method
Document.importNode (not implemented in PyDOM), so your options are:

1: Reassign node._document for the nodes that you want to insert (But
this is not fun and, as I understand the specs
   a Bad Thing to do)
2: Use 4DOM.  It implements the importNode method you need and has
actually been officially brought in as the new
   XML-Sig tool of choice (correct?).  In this solution you would do
something like this (I apologize for the
   quality of this code, just a remnant of a proof of concept for work):

       # Load the file into a tree, and strip the whitespace.
       subdoc=Sax.FromXmlUrl('Content/'+node.getAttribute('obj')+'.xml')
       Ext.StripXml(subdoc)
       # Copy the new tree to the location of the include, changing
       # the node ownership to the main document.
       for all in subdoc.documentElement.childNodes:
           importedNode=node.ownerDocument.importNode(all,deep=1)
           includeParent.insertBefore(importedNode,node)
       # Delete the original include from the tree.
       includeParent.removeChild(node)

3: If you're tied to PyDOM, use this, courtesy of Sebastian Schneckener:
--------------------
#!/usr/bin/env python
# GPL type license
# www.science-factory.com
# 2000/14/03
# 
import re
import sys
import xml.dom.core
import xml.dom.utils

class CopyClass:
  def __init__(self, document):
    self.dom=document
  def copyElement (self, node):
    """ Returns a copy of the node without a reference to its document 
        to a new document dom. It is not recursive. It copies the name 
        of the node and the attributes incl. values """
    if isinstance(node,xml.dom.core.Text):
      e=self.dom.createTextNode(node.nodeValue)
      e.nodeValue=node.nodeValue
      return e
    e = self.dom.createElement(node.get_tagName())
    for i in node.get_attributes().values():
      e.setAttribute(i.get_name(), node.getAttribute (i.get_name()))
    return e
  def deepCopy (self, node):
    """copies a given node and all nodes childs. """
    copiedNode=self.copyElement(node)
    self.__recDCE(node,copiedNode)
    return copiedNode
  def __recDCE (self, node, copiedNode):
    for child in node.get_childNodes():
      cNode=self.copyElement(child)
      copiedNode.appendChild(cNode)
      self.__recDCE(child, cNode)
  def test(xmlFile ):
    # reading an existing xml file
    d = xml.dom.utils.FileReader()
    dom = d.readFile(xmlFile )
    # creating a new DOM tree
    newDom = xml.dom.core.createDocument()
    # instantiating a 'CopyClass'
    myCopyClass = CopyClass(newDom)
    # copying the old to the new tree
    newDom.appendChild (myCopyClass.deepCopy(dom.firstChild) )
    # printing
    print newDom.toxml()
    
if __name__ == '__main__':
  if len (sys.argv) == 2:
    test(sys.argv[1])
  else:
    print "usage:\n  ",sys.argv[0]," file.xml"
    sys.exit(255)
--------------------

      Jeremy J. Sydik
      jsydik@virtualparadigm.com
chris davis wrote:
> 
> I'm hoping someone can help me on this.  I'm using DOM in my application and
> I want to insert a xml document into another xml document at a specific
> node.   I'm using DOM and I tired the following.
> 
> reader = utils.FileReader(f.GetPath())
> new_doc = reader.document
> utils.strip_whitespace(doc)
> new_xml_node = doc.get_firstChild()
> old_xml_node.insertBefore(xml_node,None)
> ....
> 
> At this point I get the "Node created from a different document" error.
> I understand what's causing the error, but how can I merge two DOM trees
> together. I Use DOM extensively in my app, so I'd really like to accomplish
> this without having to move the XML data to a different abstraction, but
> I'll take any solution at this point.  Thanks.
> 
> chris davis
> chris@rpgarchive.com
> 
> http://www.rpgarchive.com
> adventure database and open news forum
> 
> http://www.openrpg.com
> check out OpenRPG! open source online rpg!
> 
> _______________________________________________
> XML-SIG maillist  -  XML-SIG@python.org
> http://www.python.org/mailman/listinfo/xml-sig