[XML-SIG] Creating DOM fragments

Fred L. Drake Fred L. Drake, Jr." <fdrake@acm.org
Tue, 1 Jun 1999 14:59:18 -0400 (EDT)


  In the spirit of making changes to the DOM builder, here's something 
I've played with a little.
  When I started working on the conversion of the Python documentation 
to SGML/XML, I was building DOM objects that weren't legal: the LaTeX
files don't map to hierarchical structures, even if you ignore the
document preamble.  While the documents themselves can be treated as
hierachical in this specific case, that's not the case for individual
files, which is the level I want to work at.  When Andrew fixed the
Document class to be less forgiving, I had to change the way I used
it, building the more reasonable DocumentFragment objects instead.
I'm driving the whole conversion across ESIS streams, so I wanted the
ESIS builder to be able to build fragments instead of documents.  I've 
been using a custom subclass that added the needed functionality for
this (and some other stuff), but this would probably be very useful
for others doing conversion processes.
  I think the appended patch would be useful for others.  It adds a
method to xml.dom.builder.Builder called buildFragment(); it has to be 
called before document construction starts and causes a fragment to be 
built instead.  The fragment can be found as the "fragment" attribute
of the builder or the return value of buildFragment().
  Does this make sense as part of the base class?  Or is this too
special a situation?


  -Fred

--
Fred L. Drake, Jr.	     <fdrake@acm.org>
Corporation for National Research Initiatives


diff -c -r1.10 builder.py
*** builder.py	1999/03/18 12:38:28	1.10
--- builder.py	1999/06/01 18:58:29
***************
*** 15,22 ****
--- 15,31 ----
  
      def __init__(self):
          self.document = createDocument()
+         self.fragment = None
+         self.target = self.document
          self.current_element = None
  
+     def buildFragment(self):
+         if self.fragment or len(self.document.childNodes):
+             raise RuntimeError, \
+                   "cannot build fragment once document has been started"
+         self.fragment = self.document.createDocumentFragment()
+         self.target = self.fragment
+         return self.fragment
  
      def push(self, node):
          "Add node to current node and move to new node."
***************
*** 24,35 ****
          nodetype = node.get_nodeType()
          if self.current_element:
              self.current_element.insertBefore(node, None)
!         elif nodetype in _LEGAL_DOCUMENT_CHILDREN:
              if nodetype == TEXT_NODE:
                  if string.strip(node.get_nodeValue()) != "":
!                     self.document.appendChild(node)
              else:
!                 self.document.appendChild(node)
  
          if nodetype == ELEMENT_NODE:
              self.current_element = node
--- 33,44 ----
          nodetype = node.get_nodeType()
          if self.current_element:
              self.current_element.insertBefore(node, None)
!         elif self.fragment or nodetype in _LEGAL_DOCUMENT_CHILDREN:
              if nodetype == TEXT_NODE:
                  if string.strip(node.get_nodeValue()) != "":
!                     self.target.appendChild(node)
              else:
!                 self.target.appendChild(node)
  
          if nodetype == ELEMENT_NODE:
              self.current_element = node