[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