home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / minidom.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2003-12-30  |  92KB  |  2,119 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.3)
  3.  
  4. '''minidom.py -- a lightweight DOM implementation.
  5.  
  6. parse("foo.xml")
  7.  
  8. parseString("<foo><bar/></foo>")
  9.  
  10. Todo:
  11. =====
  12.  * convenience methods for getting elements and text.
  13.  * more testing
  14.  * bring some of the writer and linearizer code into conformance with this
  15.         interface
  16.  * SAX 2 namespaces
  17. '''
  18. import sys
  19. import xml.dom as xml
  20. from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE, domreg
  21. from xml.dom.minicompat import *
  22. from xml.dom.xmlbuilder import DOMImplementationLS, DocumentLS
  23. _TupleType = type(())
  24. _nodeTypes_with_children = (xml.dom.Node.ELEMENT_NODE, xml.dom.Node.ENTITY_REFERENCE_NODE)
  25.  
  26. class Node(xml.dom.Node, GetattrMagic):
  27.     namespaceURI = None
  28.     parentNode = None
  29.     ownerDocument = None
  30.     nextSibling = None
  31.     previousSibling = None
  32.     prefix = EMPTY_PREFIX
  33.     
  34.     def __nonzero__(self):
  35.         return True
  36.  
  37.     
  38.     def toxml(self, encoding = None):
  39.         return self.toprettyxml('', '', encoding)
  40.  
  41.     
  42.     def toprettyxml(self, indent = '\t', newl = '\n', encoding = None):
  43.         writer = _get_StringIO()
  44.         if encoding is not None:
  45.             import codecs
  46.             writer = codecs.lookup(encoding)[3](writer)
  47.         
  48.         if self.nodeType == Node.DOCUMENT_NODE:
  49.             self.writexml(writer, '', indent, newl, encoding)
  50.         else:
  51.             self.writexml(writer, '', indent, newl)
  52.         return writer.getvalue()
  53.  
  54.     
  55.     def hasChildNodes(self):
  56.         if self.childNodes:
  57.             return True
  58.         else:
  59.             return False
  60.  
  61.     
  62.     def _get_childNodes(self):
  63.         return self.childNodes
  64.  
  65.     
  66.     def _get_firstChild(self):
  67.         if self.childNodes:
  68.             return self.childNodes[0]
  69.         
  70.  
  71.     
  72.     def _get_lastChild(self):
  73.         if self.childNodes:
  74.             return self.childNodes[-1]
  75.         
  76.  
  77.     
  78.     def insertBefore(self, newChild, refChild):
  79.         if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
  80.             for c in tuple(newChild.childNodes):
  81.                 self.insertBefore(c, refChild)
  82.             
  83.             return newChild
  84.         
  85.         if newChild.nodeType not in self._child_node_types:
  86.             raise xml.dom.HierarchyRequestErr('%s cannot be child of %s' % (repr(newChild), repr(self)))
  87.         
  88.         if newChild.parentNode is not None:
  89.             newChild.parentNode.removeChild(newChild)
  90.         
  91.         if refChild is None:
  92.             self.appendChild(newChild)
  93.         else:
  94.             
  95.             try:
  96.                 index = self.childNodes.index(refChild)
  97.             except ValueError:
  98.                 raise xml.dom.NotFoundErr()
  99.  
  100.             if newChild.nodeType in _nodeTypes_with_children:
  101.                 _clear_id_cache(self)
  102.             
  103.             self.childNodes.insert(index, newChild)
  104.             newChild.nextSibling = refChild
  105.             refChild.previousSibling = newChild
  106.             if index:
  107.                 node = self.childNodes[index - 1]
  108.                 node.nextSibling = newChild
  109.                 newChild.previousSibling = node
  110.             else:
  111.                 newChild.previousSibling = None
  112.             newChild.parentNode = self
  113.         return newChild
  114.  
  115.     
  116.     def appendChild(self, node):
  117.         if node.nodeType == self.DOCUMENT_FRAGMENT_NODE:
  118.             for c in tuple(node.childNodes):
  119.                 self.appendChild(c)
  120.             
  121.             return node
  122.         
  123.         if node.nodeType not in self._child_node_types:
  124.             raise xml.dom.HierarchyRequestErr('%s cannot be child of %s' % (repr(node), repr(self)))
  125.         elif node.nodeType in _nodeTypes_with_children:
  126.             _clear_id_cache(self)
  127.         
  128.         if node.parentNode is not None:
  129.             node.parentNode.removeChild(node)
  130.         
  131.         _append_child(self, node)
  132.         node.nextSibling = None
  133.         return node
  134.  
  135.     
  136.     def replaceChild(self, newChild, oldChild):
  137.         if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
  138.             refChild = oldChild.nextSibling
  139.             self.removeChild(oldChild)
  140.             return self.insertBefore(newChild, refChild)
  141.         
  142.         if newChild.nodeType not in self._child_node_types:
  143.             raise xml.dom.HierarchyRequestErr('%s cannot be child of %s' % (repr(newChild), repr(self)))
  144.         
  145.         if newChild.parentNode is not None:
  146.             newChild.parentNode.removeChild(newChild)
  147.         
  148.         if newChild is oldChild:
  149.             return None
  150.         
  151.         
  152.         try:
  153.             index = self.childNodes.index(oldChild)
  154.         except ValueError:
  155.             raise xml.dom.NotFoundErr()
  156.  
  157.         self.childNodes[index] = newChild
  158.         newChild.parentNode = self
  159.         oldChild.parentNode = None
  160.         if newChild.nodeType in _nodeTypes_with_children or oldChild.nodeType in _nodeTypes_with_children:
  161.             _clear_id_cache(self)
  162.         
  163.         newChild.nextSibling = oldChild.nextSibling
  164.         newChild.previousSibling = oldChild.previousSibling
  165.         oldChild.nextSibling = None
  166.         oldChild.previousSibling = None
  167.         if newChild.previousSibling:
  168.             newChild.previousSibling.nextSibling = newChild
  169.         
  170.         if newChild.nextSibling:
  171.             newChild.nextSibling.previousSibling = newChild
  172.         
  173.         return oldChild
  174.  
  175.     
  176.     def removeChild(self, oldChild):
  177.         
  178.         try:
  179.             self.childNodes.remove(oldChild)
  180.         except ValueError:
  181.             raise xml.dom.NotFoundErr()
  182.  
  183.         if oldChild.nextSibling is not None:
  184.             oldChild.nextSibling.previousSibling = oldChild.previousSibling
  185.         
  186.         if oldChild.previousSibling is not None:
  187.             oldChild.previousSibling.nextSibling = oldChild.nextSibling
  188.         
  189.         oldChild.nextSibling = oldChild.previousSibling = None
  190.         if oldChild.nodeType in _nodeTypes_with_children:
  191.             _clear_id_cache(self)
  192.         
  193.         oldChild.parentNode = None
  194.         return oldChild
  195.  
  196.     
  197.     def normalize(self):
  198.         L = []
  199.         for child in self.childNodes:
  200.             if child.nodeType == Node.TEXT_NODE:
  201.                 data = child.data
  202.                 if data and L and L[-1].nodeType == child.nodeType:
  203.                     node = L[-1]
  204.                     node.data = node.data + child.data
  205.                     node.nextSibling = child.nextSibling
  206.                     child.unlink()
  207.                 elif data:
  208.                     if L:
  209.                         L[-1].nextSibling = child
  210.                         child.previousSibling = L[-1]
  211.                     else:
  212.                         child.previousSibling = None
  213.                     L.append(child)
  214.                 else:
  215.                     child.unlink()
  216.             L[-1].nodeType == child.nodeType
  217.             if L:
  218.                 L[-1].nextSibling = child
  219.                 child.previousSibling = L[-1]
  220.             else:
  221.                 child.previousSibling = None
  222.             L.append(child)
  223.             if child.nodeType == Node.ELEMENT_NODE:
  224.                 child.normalize()
  225.                 continue
  226.         
  227.         self.childNodes[:] = L
  228.  
  229.     
  230.     def cloneNode(self, deep):
  231.         if not self.ownerDocument:
  232.             pass
  233.         return _clone_node(self, deep, self)
  234.  
  235.     
  236.     def isSupported(self, feature, version):
  237.         return self.ownerDocument.implementation.hasFeature(feature, version)
  238.  
  239.     
  240.     def _get_localName(self):
  241.         return None
  242.  
  243.     
  244.     def isSameNode(self, other):
  245.         return self is other
  246.  
  247.     
  248.     def getInterface(self, feature):
  249.         if self.isSupported(feature, None):
  250.             return self
  251.         else:
  252.             return None
  253.  
  254.     
  255.     def getUserData(self, key):
  256.         
  257.         try:
  258.             return self._user_data[key][0]
  259.         except (AttributeError, KeyError):
  260.             return None
  261.  
  262.  
  263.     
  264.     def setUserData(self, key, data, handler):
  265.         old = None
  266.         
  267.         try:
  268.             d = self._user_data
  269.         except AttributeError:
  270.             d = { }
  271.             self._user_data = d
  272.  
  273.         if d.has_key(key):
  274.             old = d[key][0]
  275.         
  276.         if data is None:
  277.             handler = None
  278.             if old is not None:
  279.                 del d[key]
  280.             
  281.         else:
  282.             d[key] = (data, handler)
  283.         return old
  284.  
  285.     
  286.     def _call_user_data_handler(self, operation, src, dst):
  287.         if hasattr(self, '_user_data'):
  288.             for data, handler in self._user_data.items():
  289.                 if handler is not None:
  290.                     handler.handle(operation, key, data, src, dst)
  291.                     continue
  292.             
  293.         
  294.  
  295.     
  296.     def unlink(self):
  297.         self.parentNode = self.ownerDocument = None
  298.         if self.childNodes:
  299.             for child in self.childNodes:
  300.                 child.unlink()
  301.             
  302.             self.childNodes = NodeList()
  303.         
  304.         self.previousSibling = None
  305.         self.nextSibling = None
  306.  
  307.  
  308. defproperty(Node, 'firstChild', doc = 'First child node, or None.')
  309. defproperty(Node, 'lastChild', doc = 'Last child node, or None.')
  310. defproperty(Node, 'localName', doc = 'Namespace-local name of this node.')
  311.  
  312. def _append_child(self, node):
  313.     childNodes = self.childNodes
  314.     if childNodes:
  315.         last = childNodes[-1]
  316.         node.__dict__['previousSibling'] = last
  317.         last.__dict__['nextSibling'] = node
  318.     
  319.     childNodes.append(node)
  320.     node.__dict__['parentNode'] = self
  321.  
  322.  
  323. def _in_document(node):
  324.     while node is not None:
  325.         if node.nodeType == Node.DOCUMENT_NODE:
  326.             return True
  327.         
  328.         node = node.parentNode
  329.     return False
  330.  
  331.  
  332. def _write_data(writer, data):
  333.     '''Writes datachars to writer.'''
  334.     data = data.replace('&', '&').replace('<', '<')
  335.     data = data.replace('"', '"').replace('>', '>')
  336.     writer.write(data)
  337.  
  338.  
  339. def _get_elements_by_tagName_helper(parent, name, rc):
  340.     for node in parent.childNodes:
  341.         if node.nodeType == Node.ELEMENT_NODE and name == '*' or node.tagName == name:
  342.             rc.append(node)
  343.         
  344.         _get_elements_by_tagName_helper(node, name, rc)
  345.     
  346.     return rc
  347.  
  348.  
  349. def _get_elements_by_tagName_ns_helper(parent, nsURI, localName, rc):
  350.     for node in parent.childNodes:
  351.         if node.nodeType == Node.ELEMENT_NODE:
  352.             if (localName == '*' or node.localName == localName) and nsURI == '*' or node.namespaceURI == nsURI:
  353.                 rc.append(node)
  354.             
  355.             _get_elements_by_tagName_ns_helper(node, nsURI, localName, rc)
  356.             continue
  357.     
  358.     return rc
  359.  
  360.  
  361. class DocumentFragment(Node):
  362.     nodeType = Node.DOCUMENT_FRAGMENT_NODE
  363.     nodeName = '#document-fragment'
  364.     nodeValue = None
  365.     attributes = None
  366.     parentNode = None
  367.     _child_node_types = (Node.ELEMENT_NODE, Node.TEXT_NODE, Node.CDATA_SECTION_NODE, Node.ENTITY_REFERENCE_NODE, Node.PROCESSING_INSTRUCTION_NODE, Node.COMMENT_NODE, Node.NOTATION_NODE)
  368.     
  369.     def __init__(self):
  370.         self.childNodes = NodeList()
  371.  
  372.  
  373.  
  374. class Attr(Node):
  375.     nodeType = Node.ATTRIBUTE_NODE
  376.     attributes = None
  377.     ownerElement = None
  378.     specified = False
  379.     _is_id = False
  380.     _child_node_types = (Node.TEXT_NODE, Node.ENTITY_REFERENCE_NODE)
  381.     
  382.     def __init__(self, qName, namespaceURI = EMPTY_NAMESPACE, localName = None, prefix = None):
  383.         d = self.__dict__
  384.         d['nodeName'] = d['name'] = qName
  385.         d['namespaceURI'] = namespaceURI
  386.         d['prefix'] = prefix
  387.         d['childNodes'] = NodeList()
  388.         self.childNodes.append(Text())
  389.  
  390.     
  391.     def _get_localName(self):
  392.         return self.nodeName.split(':', 1)[-1]
  393.  
  394.     
  395.     def _get_name(self):
  396.         return self.name
  397.  
  398.     
  399.     def _get_specified(self):
  400.         return self.specified
  401.  
  402.     
  403.     def __setattr__(self, name, value):
  404.         d = self.__dict__
  405.         if name in ('value', 'nodeValue'):
  406.             d['value'] = d['nodeValue'] = value
  407.             d2 = self.childNodes[0].__dict__
  408.             d2['data'] = d2['nodeValue'] = value
  409.             if self.ownerElement is not None:
  410.                 _clear_id_cache(self.ownerElement)
  411.             
  412.         elif name in ('name', 'nodeName'):
  413.             d['name'] = d['nodeName'] = value
  414.             if self.ownerElement is not None:
  415.                 _clear_id_cache(self.ownerElement)
  416.             
  417.         else:
  418.             d[name] = value
  419.  
  420.     
  421.     def _set_prefix(self, prefix):
  422.         nsuri = self.namespaceURI
  423.         if prefix == 'xmlns':
  424.             if nsuri and nsuri != XMLNS_NAMESPACE:
  425.                 raise xml.dom.NamespaceErr("illegal use of 'xmlns' prefix for the wrong namespace")
  426.             
  427.         
  428.         d = self.__dict__
  429.         d['prefix'] = prefix
  430.         if prefix is None:
  431.             newName = self.localName
  432.         else:
  433.             newName = '%s:%s' % (prefix, self.localName)
  434.         if self.ownerElement:
  435.             _clear_id_cache(self.ownerElement)
  436.         
  437.         d['nodeName'] = d['name'] = newName
  438.  
  439.     
  440.     def _set_value(self, value):
  441.         d = self.__dict__
  442.         d['value'] = d['nodeValue'] = value
  443.         if self.ownerElement:
  444.             _clear_id_cache(self.ownerElement)
  445.         
  446.         self.childNodes[0].data = value
  447.  
  448.     
  449.     def unlink(self):
  450.         elem = self.ownerElement
  451.         if elem is not None:
  452.             del elem._attrs[self.nodeName]
  453.             del elem._attrsNS[(self.namespaceURI, self.localName)]
  454.             if self._is_id:
  455.                 self._is_id = False
  456.                 elem._magic_id_nodes -= 1
  457.                 self.ownerDocument._magic_id_count -= 1
  458.             
  459.         
  460.         for child in self.childNodes:
  461.             child.unlink()
  462.         
  463.         del self.childNodes[:]
  464.  
  465.     
  466.     def _get_isId(self):
  467.         if self._is_id:
  468.             return True
  469.         
  470.         doc = self.ownerDocument
  471.         elem = self.ownerElement
  472.         if doc is None or elem is None:
  473.             return False
  474.         
  475.         info = doc._get_elem_info(elem)
  476.         if info is None:
  477.             return False
  478.         
  479.         if self.namespaceURI:
  480.             return info.isIdNS(self.namespaceURI, self.localName)
  481.         else:
  482.             return info.isId(self.nodeName)
  483.  
  484.     
  485.     def _get_schemaType(self):
  486.         doc = self.ownerDocument
  487.         elem = self.ownerElement
  488.         if doc is None or elem is None:
  489.             return _no_type
  490.         
  491.         info = doc._get_elem_info(elem)
  492.         if info is None:
  493.             return _no_type
  494.         
  495.         if self.namespaceURI:
  496.             return info.getAttributeTypeNS(self.namespaceURI, self.localName)
  497.         else:
  498.             return info.getAttributeType(self.nodeName)
  499.  
  500.  
  501. defproperty(Attr, 'isId', doc = 'True if this attribute is an ID.')
  502. defproperty(Attr, 'localName', doc = 'Namespace-local name of this attribute.')
  503. defproperty(Attr, 'schemaType', doc = 'Schema type for this attribute.')
  504.  
  505. class NamedNodeMap(NewStyle, GetattrMagic):
  506.     """The attribute list is a transient interface to the underlying
  507.     dictionaries.  Mutations here will change the underlying element's
  508.     dictionary.
  509.  
  510.     Ordering is imposed artificially and does not reflect the order of
  511.     attributes as found in an input document.
  512.     """
  513.     __slots__ = ('_attrs', '_attrsNS', '_ownerElement')
  514.     
  515.     def __init__(self, attrs, attrsNS, ownerElement):
  516.         self._attrs = attrs
  517.         self._attrsNS = attrsNS
  518.         self._ownerElement = ownerElement
  519.  
  520.     
  521.     def _get_length(self):
  522.         return len(self._attrs)
  523.  
  524.     
  525.     def item(self, index):
  526.         
  527.         try:
  528.             return self[self._attrs.keys()[index]]
  529.         except IndexError:
  530.             return None
  531.  
  532.  
  533.     
  534.     def items(self):
  535.         L = []
  536.         for node in self._attrs.values():
  537.             L.append((node.nodeName, node.value))
  538.         
  539.         return L
  540.  
  541.     
  542.     def itemsNS(self):
  543.         L = []
  544.         for node in self._attrs.values():
  545.             L.append(((node.namespaceURI, node.localName), node.value))
  546.         
  547.         return L
  548.  
  549.     
  550.     def has_key(self, key):
  551.         if isinstance(key, StringTypes):
  552.             return self._attrs.has_key(key)
  553.         else:
  554.             return self._attrsNS.has_key(key)
  555.  
  556.     
  557.     def keys(self):
  558.         return self._attrs.keys()
  559.  
  560.     
  561.     def keysNS(self):
  562.         return self._attrsNS.keys()
  563.  
  564.     
  565.     def values(self):
  566.         return self._attrs.values()
  567.  
  568.     
  569.     def get(self, name, value = None):
  570.         return self._attrs.get(name, value)
  571.  
  572.     __len__ = _get_length
  573.     
  574.     def __cmp__(self, other):
  575.         if self._attrs is getattr(other, '_attrs', None):
  576.             return 0
  577.         else:
  578.             return cmp(id(self), id(other))
  579.  
  580.     
  581.     def __getitem__(self, attname_or_tuple):
  582.         if isinstance(attname_or_tuple, _TupleType):
  583.             return self._attrsNS[attname_or_tuple]
  584.         else:
  585.             return self._attrs[attname_or_tuple]
  586.  
  587.     
  588.     def __setitem__(self, attname, value):
  589.         if isinstance(value, StringTypes):
  590.             
  591.             try:
  592.                 node = self._attrs[attname]
  593.             except KeyError:
  594.                 node = Attr(attname)
  595.                 node.ownerDocument = self._ownerElement.ownerDocument
  596.                 self.setNamedItem(node)
  597.  
  598.             node.value = value
  599.         elif not isinstance(value, Attr):
  600.             raise TypeError, 'value must be a string or Attr object'
  601.         
  602.         node = value
  603.         self.setNamedItem(node)
  604.  
  605.     
  606.     def getNamedItem(self, name):
  607.         
  608.         try:
  609.             return self._attrs[name]
  610.         except KeyError:
  611.             return None
  612.  
  613.  
  614.     
  615.     def getNamedItemNS(self, namespaceURI, localName):
  616.         
  617.         try:
  618.             return self._attrsNS[(namespaceURI, localName)]
  619.         except KeyError:
  620.             return None
  621.  
  622.  
  623.     
  624.     def removeNamedItem(self, name):
  625.         n = self.getNamedItem(name)
  626.         if n is not None:
  627.             _clear_id_cache(self._ownerElement)
  628.             del self._attrs[n.nodeName]
  629.             del self._attrsNS[(n.namespaceURI, n.localName)]
  630.             if n.__dict__.has_key('ownerElement'):
  631.                 n.__dict__['ownerElement'] = None
  632.             
  633.             return n
  634.         else:
  635.             raise xml.dom.NotFoundErr()
  636.  
  637.     
  638.     def removeNamedItemNS(self, namespaceURI, localName):
  639.         n = self.getNamedItemNS(namespaceURI, localName)
  640.         if n is not None:
  641.             _clear_id_cache(self._ownerElement)
  642.             del self._attrsNS[(n.namespaceURI, n.localName)]
  643.             del self._attrs[n.nodeName]
  644.             if n.__dict__.has_key('ownerElement'):
  645.                 n.__dict__['ownerElement'] = None
  646.             
  647.             return n
  648.         else:
  649.             raise xml.dom.NotFoundErr()
  650.  
  651.     
  652.     def setNamedItem(self, node):
  653.         if not isinstance(node, Attr):
  654.             raise xml.dom.HierarchyRequestErr('%s cannot be child of %s' % (repr(node), repr(self)))
  655.         
  656.         old = self._attrs.get(node.name)
  657.         if old:
  658.             old.unlink()
  659.         
  660.         self._attrs[node.name] = node
  661.         self._attrsNS[(node.namespaceURI, node.localName)] = node
  662.         node.ownerElement = self._ownerElement
  663.         _clear_id_cache(node.ownerElement)
  664.         return old
  665.  
  666.     
  667.     def setNamedItemNS(self, node):
  668.         return self.setNamedItem(node)
  669.  
  670.     
  671.     def __delitem__(self, attname_or_tuple):
  672.         node = self[attname_or_tuple]
  673.         _clear_id_cache(node.ownerElement)
  674.         node.unlink()
  675.  
  676.     
  677.     def __getstate__(self):
  678.         return (self._attrs, self._attrsNS, self._ownerElement)
  679.  
  680.     
  681.     def __setstate__(self, state):
  682.         (self._attrs, self._attrsNS, self._ownerElement) = state
  683.  
  684.  
  685. defproperty(NamedNodeMap, 'length', doc = 'Number of nodes in the NamedNodeMap.')
  686. AttributeList = NamedNodeMap
  687.  
  688. class TypeInfo(NewStyle):
  689.     __slots__ = ('namespace', 'name')
  690.     
  691.     def __init__(self, namespace, name):
  692.         self.namespace = namespace
  693.         self.name = name
  694.  
  695.     
  696.     def __repr__(self):
  697.         if self.namespace:
  698.             return '<TypeInfo %s (from %s)>' % (`self.name`, `self.namespace`)
  699.         else:
  700.             return '<TypeInfo %s>' % `self.name`
  701.  
  702.     
  703.     def _get_name(self):
  704.         return self.name
  705.  
  706.     
  707.     def _get_namespace(self):
  708.         return self.namespace
  709.  
  710.  
  711. _no_type = TypeInfo(None, None)
  712.  
  713. class Element(Node):
  714.     nodeType = Node.ELEMENT_NODE
  715.     nodeValue = None
  716.     schemaType = _no_type
  717.     _magic_id_nodes = 0
  718.     _child_node_types = (Node.ELEMENT_NODE, Node.PROCESSING_INSTRUCTION_NODE, Node.COMMENT_NODE, Node.TEXT_NODE, Node.CDATA_SECTION_NODE, Node.ENTITY_REFERENCE_NODE)
  719.     
  720.     def __init__(self, tagName, namespaceURI = EMPTY_NAMESPACE, prefix = None, localName = None):
  721.         self.tagName = self.nodeName = tagName
  722.         self.prefix = prefix
  723.         self.namespaceURI = namespaceURI
  724.         self.childNodes = NodeList()
  725.         self._attrs = { }
  726.         self._attrsNS = { }
  727.  
  728.     
  729.     def _get_localName(self):
  730.         return self.tagName.split(':', 1)[-1]
  731.  
  732.     
  733.     def _get_tagName(self):
  734.         return self.tagName
  735.  
  736.     
  737.     def unlink(self):
  738.         for attr in self._attrs.values():
  739.             attr.unlink()
  740.         
  741.         self._attrs = None
  742.         self._attrsNS = None
  743.         Node.unlink(self)
  744.  
  745.     
  746.     def getAttribute(self, attname):
  747.         
  748.         try:
  749.             return self._attrs[attname].value
  750.         except KeyError:
  751.             return ''
  752.  
  753.  
  754.     
  755.     def getAttributeNS(self, namespaceURI, localName):
  756.         
  757.         try:
  758.             return self._attrsNS[(namespaceURI, localName)].value
  759.         except KeyError:
  760.             return ''
  761.  
  762.  
  763.     
  764.     def setAttribute(self, attname, value):
  765.         attr = self.getAttributeNode(attname)
  766.         if attr is None:
  767.             attr = Attr(attname)
  768.             d = attr.__dict__
  769.             d['value'] = d['nodeValue'] = value
  770.             d['ownerDocument'] = self.ownerDocument
  771.             self.setAttributeNode(attr)
  772.         elif value != attr.value:
  773.             d = attr.__dict__
  774.             d['value'] = d['nodeValue'] = value
  775.             if attr.isId:
  776.                 _clear_id_cache(self)
  777.             
  778.         
  779.  
  780.     
  781.     def setAttributeNS(self, namespaceURI, qualifiedName, value):
  782.         (prefix, localname) = _nssplit(qualifiedName)
  783.         attr = self.getAttributeNodeNS(namespaceURI, localname)
  784.         if attr is None:
  785.             attr = Attr(qualifiedName, namespaceURI, localname, prefix)
  786.             d = attr.__dict__
  787.             d['prefix'] = prefix
  788.             d['nodeName'] = qualifiedName
  789.             d['value'] = d['nodeValue'] = value
  790.             d['ownerDocument'] = self.ownerDocument
  791.             self.setAttributeNode(attr)
  792.         else:
  793.             d = attr.__dict__
  794.             if value != attr.value:
  795.                 d['value'] = d['nodeValue'] = value
  796.                 if attr.isId:
  797.                     _clear_id_cache(self)
  798.                 
  799.             
  800.             if attr.prefix != prefix:
  801.                 d['prefix'] = prefix
  802.                 d['nodeName'] = qualifiedName
  803.             
  804.  
  805.     
  806.     def getAttributeNode(self, attrname):
  807.         return self._attrs.get(attrname)
  808.  
  809.     
  810.     def getAttributeNodeNS(self, namespaceURI, localName):
  811.         return self._attrsNS.get((namespaceURI, localName))
  812.  
  813.     
  814.     def setAttributeNode(self, attr):
  815.         if attr.ownerElement not in (None, self):
  816.             raise xml.dom.InuseAttributeErr('attribute node already owned')
  817.         
  818.         old1 = self._attrs.get(attr.name, None)
  819.         if old1 is not None:
  820.             self.removeAttributeNode(old1)
  821.         
  822.         old2 = self._attrsNS.get((attr.namespaceURI, attr.localName), None)
  823.         if old2 is not None and old2 is not old1:
  824.             self.removeAttributeNode(old2)
  825.         
  826.         _set_attribute_node(self, attr)
  827.         if old1 is not attr:
  828.             return old1
  829.         
  830.         if old2 is not attr:
  831.             return old2
  832.         
  833.  
  834.     setAttributeNodeNS = setAttributeNode
  835.     
  836.     def removeAttribute(self, name):
  837.         
  838.         try:
  839.             attr = self._attrs[name]
  840.         except KeyError:
  841.             raise xml.dom.NotFoundErr()
  842.  
  843.         self.removeAttributeNode(attr)
  844.  
  845.     
  846.     def removeAttributeNS(self, namespaceURI, localName):
  847.         
  848.         try:
  849.             attr = self._attrsNS[(namespaceURI, localName)]
  850.         except KeyError:
  851.             raise xml.dom.NotFoundErr()
  852.  
  853.         self.removeAttributeNode(attr)
  854.  
  855.     
  856.     def removeAttributeNode(self, node):
  857.         if node is None:
  858.             raise xml.dom.NotFoundErr()
  859.         
  860.         
  861.         try:
  862.             self._attrs[node.name]
  863.         except KeyError:
  864.             raise xml.dom.NotFoundErr()
  865.  
  866.         _clear_id_cache(self)
  867.         node.unlink()
  868.         node.ownerDocument = self.ownerDocument
  869.  
  870.     removeAttributeNodeNS = removeAttributeNode
  871.     
  872.     def hasAttribute(self, name):
  873.         return self._attrs.has_key(name)
  874.  
  875.     
  876.     def hasAttributeNS(self, namespaceURI, localName):
  877.         return self._attrsNS.has_key((namespaceURI, localName))
  878.  
  879.     
  880.     def getElementsByTagName(self, name):
  881.         return _get_elements_by_tagName_helper(self, name, NodeList())
  882.  
  883.     
  884.     def getElementsByTagNameNS(self, namespaceURI, localName):
  885.         return _get_elements_by_tagName_ns_helper(self, namespaceURI, localName, NodeList())
  886.  
  887.     
  888.     def __repr__(self):
  889.         MAX = 0x2L * sys.maxint + 1
  890.         return '<DOM Element: %s at %#x>' % (self.tagName, id(self) & MAX)
  891.  
  892.     
  893.     def writexml(self, writer, indent = '', addindent = '', newl = ''):
  894.         writer.write(indent + '<' + self.tagName)
  895.         attrs = self._get_attributes()
  896.         a_names = attrs.keys()
  897.         a_names.sort()
  898.         for a_name in a_names:
  899.             writer.write(' %s="' % a_name)
  900.             _write_data(writer, attrs[a_name].value)
  901.             writer.write('"')
  902.         
  903.         if self.childNodes:
  904.             writer.write('>%s' % newl)
  905.             for node in self.childNodes:
  906.                 node.writexml(writer, indent + addindent, addindent, newl)
  907.             
  908.             writer.write('%s</%s>%s' % (indent, self.tagName, newl))
  909.         else:
  910.             writer.write('/>%s' % newl)
  911.  
  912.     
  913.     def _get_attributes(self):
  914.         return NamedNodeMap(self._attrs, self._attrsNS, self)
  915.  
  916.     
  917.     def hasAttributes(self):
  918.         if self._attrs:
  919.             return True
  920.         else:
  921.             return False
  922.  
  923.     
  924.     def setIdAttribute(self, name):
  925.         idAttr = self.getAttributeNode(name)
  926.         self.setIdAttributeNode(idAttr)
  927.  
  928.     
  929.     def setIdAttributeNS(self, namespaceURI, localName):
  930.         idAttr = self.getAttributeNodeNS(namespaceURI, localName)
  931.         self.setIdAttributeNode(idAttr)
  932.  
  933.     
  934.     def setIdAttributeNode(self, idAttr):
  935.         if idAttr is None or not self.isSameNode(idAttr.ownerElement):
  936.             raise xml.dom.NotFoundErr()
  937.         
  938.         if _get_containing_entref(self) is not None:
  939.             raise xml.dom.NoModificationAllowedErr()
  940.         
  941.  
  942.  
  943. defproperty(Element, 'attributes', doc = 'NamedNodeMap of attributes on the element.')
  944. defproperty(Element, 'localName', doc = 'Namespace-local name of this element.')
  945.  
  946. def _set_attribute_node(element, attr):
  947.     _clear_id_cache(element)
  948.     element._attrs[attr.name] = attr
  949.     element._attrsNS[(attr.namespaceURI, attr.localName)] = attr
  950.     attr.__dict__['ownerElement'] = element
  951.  
  952.  
  953. class Childless:
  954.     '''Mixin that makes childless-ness easy to implement and avoids
  955.     the complexity of the Node methods that deal with children.
  956.     '''
  957.     attributes = None
  958.     childNodes = EmptyNodeList()
  959.     firstChild = None
  960.     lastChild = None
  961.     
  962.     def _get_firstChild(self):
  963.         return None
  964.  
  965.     
  966.     def _get_lastChild(self):
  967.         return None
  968.  
  969.     
  970.     def appendChild(self, node):
  971.         raise xml.dom.HierarchyRequestErr(self.nodeName + ' nodes cannot have children')
  972.  
  973.     
  974.     def hasChildNodes(self):
  975.         return False
  976.  
  977.     
  978.     def insertBefore(self, newChild, refChild):
  979.         raise xml.dom.HierarchyRequestErr(self.nodeName + ' nodes do not have children')
  980.  
  981.     
  982.     def removeChild(self, oldChild):
  983.         raise xml.dom.NotFoundErr(self.nodeName + ' nodes do not have children')
  984.  
  985.     
  986.     def replaceChild(self, newChild, oldChild):
  987.         raise xml.dom.HierarchyRequestErr(self.nodeName + ' nodes do not have children')
  988.  
  989.  
  990.  
  991. class ProcessingInstruction(Childless, Node):
  992.     nodeType = Node.PROCESSING_INSTRUCTION_NODE
  993.     
  994.     def __init__(self, target, data):
  995.         self.target = self.nodeName = target
  996.         self.data = self.nodeValue = data
  997.  
  998.     
  999.     def _get_data(self):
  1000.         return self.data
  1001.  
  1002.     
  1003.     def _set_data(self, value):
  1004.         d = self.__dict__
  1005.         d['data'] = d['nodeValue'] = value
  1006.  
  1007.     
  1008.     def _get_target(self):
  1009.         return self.target
  1010.  
  1011.     
  1012.     def _set_target(self, value):
  1013.         d = self.__dict__
  1014.         d['target'] = d['nodeName'] = value
  1015.  
  1016.     
  1017.     def __setattr__(self, name, value):
  1018.         if name == 'data' or name == 'nodeValue':
  1019.             self.__dict__['data'] = self.__dict__['nodeValue'] = value
  1020.         elif name == 'target' or name == 'nodeName':
  1021.             self.__dict__['target'] = self.__dict__['nodeName'] = value
  1022.         else:
  1023.             self.__dict__[name] = value
  1024.  
  1025.     
  1026.     def writexml(self, writer, indent = '', addindent = '', newl = ''):
  1027.         writer.write('%s<?%s %s?>%s' % (indent, self.target, self.data, newl))
  1028.  
  1029.  
  1030.  
  1031. class CharacterData(Childless, Node):
  1032.     
  1033.     def _get_length(self):
  1034.         return len(self.data)
  1035.  
  1036.     __len__ = _get_length
  1037.     
  1038.     def _get_data(self):
  1039.         return self.__dict__['data']
  1040.  
  1041.     
  1042.     def _set_data(self, data):
  1043.         d = self.__dict__
  1044.         d['data'] = d['nodeValue'] = data
  1045.  
  1046.     _get_nodeValue = _get_data
  1047.     _set_nodeValue = _set_data
  1048.     
  1049.     def __setattr__(self, name, value):
  1050.         if name == 'data' or name == 'nodeValue':
  1051.             self.__dict__['data'] = self.__dict__['nodeValue'] = value
  1052.         else:
  1053.             self.__dict__[name] = value
  1054.  
  1055.     
  1056.     def __repr__(self):
  1057.         data = self.data
  1058.         if len(data) > 10:
  1059.             dotdotdot = '...'
  1060.         else:
  1061.             dotdotdot = ''
  1062.         return '<DOM %s node "%s%s">' % (self.__class__.__name__, data[0:10], dotdotdot)
  1063.  
  1064.     
  1065.     def substringData(self, offset, count):
  1066.         if offset < 0:
  1067.             raise xml.dom.IndexSizeErr('offset cannot be negative')
  1068.         
  1069.         if offset >= len(self.data):
  1070.             raise xml.dom.IndexSizeErr('offset cannot be beyond end of data')
  1071.         
  1072.         if count < 0:
  1073.             raise xml.dom.IndexSizeErr('count cannot be negative')
  1074.         
  1075.         return self.data[offset:offset + count]
  1076.  
  1077.     
  1078.     def appendData(self, arg):
  1079.         self.data = self.data + arg
  1080.  
  1081.     
  1082.     def insertData(self, offset, arg):
  1083.         if offset < 0:
  1084.             raise xml.dom.IndexSizeErr('offset cannot be negative')
  1085.         
  1086.         if offset >= len(self.data):
  1087.             raise xml.dom.IndexSizeErr('offset cannot be beyond end of data')
  1088.         
  1089.         if arg:
  1090.             self.data = '%s%s%s' % (self.data[:offset], arg, self.data[offset:])
  1091.         
  1092.  
  1093.     
  1094.     def deleteData(self, offset, count):
  1095.         if offset < 0:
  1096.             raise xml.dom.IndexSizeErr('offset cannot be negative')
  1097.         
  1098.         if offset >= len(self.data):
  1099.             raise xml.dom.IndexSizeErr('offset cannot be beyond end of data')
  1100.         
  1101.         if count < 0:
  1102.             raise xml.dom.IndexSizeErr('count cannot be negative')
  1103.         
  1104.         if count:
  1105.             self.data = self.data[:offset] + self.data[offset + count:]
  1106.         
  1107.  
  1108.     
  1109.     def replaceData(self, offset, count, arg):
  1110.         if offset < 0:
  1111.             raise xml.dom.IndexSizeErr('offset cannot be negative')
  1112.         
  1113.         if offset >= len(self.data):
  1114.             raise xml.dom.IndexSizeErr('offset cannot be beyond end of data')
  1115.         
  1116.         if count < 0:
  1117.             raise xml.dom.IndexSizeErr('count cannot be negative')
  1118.         
  1119.         if count:
  1120.             self.data = '%s%s%s' % (self.data[:offset], arg, self.data[offset + count:])
  1121.         
  1122.  
  1123.  
  1124. defproperty(CharacterData, 'length', doc = 'Length of the string data.')
  1125.  
  1126. class Text(CharacterData):
  1127.     nodeType = Node.TEXT_NODE
  1128.     nodeName = '#text'
  1129.     attributes = None
  1130.     
  1131.     def splitText(self, offset):
  1132.         if offset < 0 or offset > len(self.data):
  1133.             raise xml.dom.IndexSizeErr('illegal offset value')
  1134.         
  1135.         newText = self.__class__()
  1136.         newText.data = self.data[offset:]
  1137.         newText.ownerDocument = self.ownerDocument
  1138.         next = self.nextSibling
  1139.         if self.parentNode and self in self.parentNode.childNodes:
  1140.             if next is None:
  1141.                 self.parentNode.appendChild(newText)
  1142.             else:
  1143.                 self.parentNode.insertBefore(newText, next)
  1144.         
  1145.         self.data = self.data[:offset]
  1146.         return newText
  1147.  
  1148.     
  1149.     def writexml(self, writer, indent = '', addindent = '', newl = ''):
  1150.         _write_data(writer, '%s%s%s' % (indent, self.data, newl))
  1151.  
  1152.     
  1153.     def _get_wholeText(self):
  1154.         L = [
  1155.             self.data]
  1156.         n = self.previousSibling
  1157.         while n is not None:
  1158.             if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
  1159.                 L.insert(0, n.data)
  1160.                 n = n.previousSibling
  1161.                 continue
  1162.             break
  1163.         n = self.nextSibling
  1164.         while n is not None:
  1165.             if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
  1166.                 L.append(n.data)
  1167.                 n = n.nextSibling
  1168.                 continue
  1169.             break
  1170.         return ''.join(L)
  1171.  
  1172.     
  1173.     def replaceWholeText(self, content):
  1174.         parent = self.parentNode
  1175.         n = self.previousSibling
  1176.         while n is not None:
  1177.             if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
  1178.                 next = n.previousSibling
  1179.                 parent.removeChild(n)
  1180.                 n = next
  1181.                 continue
  1182.             break
  1183.         n = self.nextSibling
  1184.         if not content:
  1185.             parent.removeChild(self)
  1186.         
  1187.         while n is not None:
  1188.             if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
  1189.                 next = n.nextSibling
  1190.                 parent.removeChild(n)
  1191.                 n = next
  1192.                 continue
  1193.             break
  1194.         if content:
  1195.             d = self.__dict__
  1196.             d['data'] = content
  1197.             d['nodeValue'] = content
  1198.             return self
  1199.         else:
  1200.             return None
  1201.  
  1202.     
  1203.     def _get_isWhitespaceInElementContent(self):
  1204.         if self.data.strip():
  1205.             return False
  1206.         
  1207.         elem = _get_containing_element(self)
  1208.         if elem is None:
  1209.             return False
  1210.         
  1211.         info = self.ownerDocument._get_elem_info(elem)
  1212.         if info is None:
  1213.             return False
  1214.         else:
  1215.             return info.isElementContent()
  1216.  
  1217.  
  1218. defproperty(Text, 'isWhitespaceInElementContent', doc = 'True iff this text node contains only whitespace and is in element content.')
  1219. defproperty(Text, 'wholeText', doc = 'The text of all logically-adjacent text nodes.')
  1220.  
  1221. def _get_containing_element(node):
  1222.     c = node.parentNode
  1223.     while c is not None:
  1224.         if c.nodeType == Node.ELEMENT_NODE:
  1225.             return c
  1226.         
  1227.         c = c.parentNode
  1228.     return None
  1229.  
  1230.  
  1231. def _get_containing_entref(node):
  1232.     c = node.parentNode
  1233.     while c is not None:
  1234.         if c.nodeType == Node.ENTITY_REFERENCE_NODE:
  1235.             return c
  1236.         
  1237.         c = c.parentNode
  1238.     return None
  1239.  
  1240.  
  1241. class Comment(Childless, CharacterData):
  1242.     nodeType = Node.COMMENT_NODE
  1243.     nodeName = '#comment'
  1244.     
  1245.     def __init__(self, data):
  1246.         self.data = self.nodeValue = data
  1247.  
  1248.     
  1249.     def writexml(self, writer, indent = '', addindent = '', newl = ''):
  1250.         writer.write('%s<!--%s-->%s' % (indent, self.data, newl))
  1251.  
  1252.  
  1253.  
  1254. class CDATASection(Text):
  1255.     nodeType = Node.CDATA_SECTION_NODE
  1256.     nodeName = '#cdata-section'
  1257.     
  1258.     def writexml(self, writer, indent = '', addindent = '', newl = ''):
  1259.         if self.data.find(']]>') >= 0:
  1260.             raise ValueError("']]>' not allowed in a CDATA section")
  1261.         
  1262.         writer.write('<![CDATA[%s]]>' % self.data)
  1263.  
  1264.  
  1265.  
  1266. class ReadOnlySequentialNamedNodeMap(NewStyle, GetattrMagic):
  1267.     __slots__ = ('_seq',)
  1268.     
  1269.     def __init__(self, seq = ()):
  1270.         self._seq = seq
  1271.  
  1272.     
  1273.     def __len__(self):
  1274.         return len(self._seq)
  1275.  
  1276.     
  1277.     def _get_length(self):
  1278.         return len(self._seq)
  1279.  
  1280.     
  1281.     def getNamedItem(self, name):
  1282.         for n in self._seq:
  1283.             if n.nodeName == name:
  1284.                 return n
  1285.                 continue
  1286.         
  1287.  
  1288.     
  1289.     def getNamedItemNS(self, namespaceURI, localName):
  1290.         for n in self._seq:
  1291.             if n.namespaceURI == namespaceURI and n.localName == localName:
  1292.                 return n
  1293.                 continue
  1294.         
  1295.  
  1296.     
  1297.     def __getitem__(self, name_or_tuple):
  1298.         if isinstance(name_or_tuple, _TupleType):
  1299.             node = self.getNamedItemNS(*name_or_tuple)
  1300.         else:
  1301.             node = self.getNamedItem(name_or_tuple)
  1302.         if node is None:
  1303.             raise KeyError, name_or_tuple
  1304.         
  1305.         return node
  1306.  
  1307.     
  1308.     def item(self, index):
  1309.         if index < 0:
  1310.             return None
  1311.         
  1312.         
  1313.         try:
  1314.             return self._seq[index]
  1315.         except IndexError:
  1316.             return None
  1317.  
  1318.  
  1319.     
  1320.     def removeNamedItem(self, name):
  1321.         raise xml.dom.NoModificationAllowedErr('NamedNodeMap instance is read-only')
  1322.  
  1323.     
  1324.     def removeNamedItemNS(self, namespaceURI, localName):
  1325.         raise xml.dom.NoModificationAllowedErr('NamedNodeMap instance is read-only')
  1326.  
  1327.     
  1328.     def setNamedItem(self, node):
  1329.         raise xml.dom.NoModificationAllowedErr('NamedNodeMap instance is read-only')
  1330.  
  1331.     
  1332.     def setNamedItemNS(self, node):
  1333.         raise xml.dom.NoModificationAllowedErr('NamedNodeMap instance is read-only')
  1334.  
  1335.     
  1336.     def __getstate__(self):
  1337.         return [
  1338.             self._seq]
  1339.  
  1340.     
  1341.     def __setstate__(self, state):
  1342.         self._seq = state[0]
  1343.  
  1344.  
  1345. defproperty(ReadOnlySequentialNamedNodeMap, 'length', doc = 'Number of entries in the NamedNodeMap.')
  1346.  
  1347. class Identified:
  1348.     '''Mix-in class that supports the publicId and systemId attributes.'''
  1349.     
  1350.     def _identified_mixin_init(self, publicId, systemId):
  1351.         self.publicId = publicId
  1352.         self.systemId = systemId
  1353.  
  1354.     
  1355.     def _get_publicId(self):
  1356.         return self.publicId
  1357.  
  1358.     
  1359.     def _get_systemId(self):
  1360.         return self.systemId
  1361.  
  1362.  
  1363.  
  1364. class DocumentType(Identified, Childless, Node):
  1365.     nodeType = Node.DOCUMENT_TYPE_NODE
  1366.     nodeValue = None
  1367.     name = None
  1368.     publicId = None
  1369.     systemId = None
  1370.     internalSubset = None
  1371.     
  1372.     def __init__(self, qualifiedName):
  1373.         self.entities = ReadOnlySequentialNamedNodeMap()
  1374.         self.notations = ReadOnlySequentialNamedNodeMap()
  1375.         if qualifiedName:
  1376.             (prefix, localname) = _nssplit(qualifiedName)
  1377.             self.name = localname
  1378.         
  1379.         self.nodeName = self.name
  1380.  
  1381.     
  1382.     def _get_internalSubset(self):
  1383.         return self.internalSubset
  1384.  
  1385.     
  1386.     def cloneNode(self, deep):
  1387.         if self.ownerDocument is None:
  1388.             clone = DocumentType(None)
  1389.             clone.name = self.name
  1390.             clone.nodeName = self.name
  1391.             operation = xml.dom.UserDataHandler.NODE_CLONED
  1392.             if deep:
  1393.                 clone.entities._seq = []
  1394.                 clone.notations._seq = []
  1395.                 for n in self.notations._seq:
  1396.                     notation = Notation(n.nodeName, n.publicId, n.systemId)
  1397.                     clone.notations._seq.append(notation)
  1398.                     n._call_user_data_handler(operation, n, notation)
  1399.                 
  1400.                 for e in self.entities._seq:
  1401.                     entity = Entity(e.nodeName, e.publicId, e.systemId, e.notationName)
  1402.                     entity.actualEncoding = e.actualEncoding
  1403.                     entity.encoding = e.encoding
  1404.                     entity.version = e.version
  1405.                     clone.entities._seq.append(entity)
  1406.                     e._call_user_data_handler(operation, n, entity)
  1407.                 
  1408.             
  1409.             self._call_user_data_handler(operation, self, clone)
  1410.             return clone
  1411.         else:
  1412.             return None
  1413.  
  1414.     
  1415.     def writexml(self, writer, indent = '', addindent = '', newl = ''):
  1416.         writer.write('<!DOCTYPE ')
  1417.         writer.write(self.name)
  1418.         if self.publicId:
  1419.             writer.write("\n  PUBLIC '%s'\n  '%s'" % (self.publicId, self.systemId))
  1420.         elif self.systemId:
  1421.             writer.write("\n  SYSTEM '%s'" % self.systemId)
  1422.         
  1423.         if self.internalSubset is not None:
  1424.             writer.write(' [')
  1425.             writer.write(self.internalSubset)
  1426.             writer.write(']')
  1427.         
  1428.         writer.write('>\n')
  1429.  
  1430.  
  1431.  
  1432. class Entity(Identified, Node):
  1433.     attributes = None
  1434.     nodeType = Node.ENTITY_NODE
  1435.     nodeValue = None
  1436.     actualEncoding = None
  1437.     encoding = None
  1438.     version = None
  1439.     
  1440.     def __init__(self, name, publicId, systemId, notation):
  1441.         self.nodeName = name
  1442.         self.notationName = notation
  1443.         self.childNodes = NodeList()
  1444.         self._identified_mixin_init(publicId, systemId)
  1445.  
  1446.     
  1447.     def _get_actualEncoding(self):
  1448.         return self.actualEncoding
  1449.  
  1450.     
  1451.     def _get_encoding(self):
  1452.         return self.encoding
  1453.  
  1454.     
  1455.     def _get_version(self):
  1456.         return self.version
  1457.  
  1458.     
  1459.     def appendChild(self, newChild):
  1460.         raise xml.dom.HierarchyRequestErr('cannot append children to an entity node')
  1461.  
  1462.     
  1463.     def insertBefore(self, newChild, refChild):
  1464.         raise xml.dom.HierarchyRequestErr('cannot insert children below an entity node')
  1465.  
  1466.     
  1467.     def removeChild(self, oldChild):
  1468.         raise xml.dom.HierarchyRequestErr('cannot remove children from an entity node')
  1469.  
  1470.     
  1471.     def replaceChild(self, newChild, oldChild):
  1472.         raise xml.dom.HierarchyRequestErr('cannot replace children of an entity node')
  1473.  
  1474.  
  1475.  
  1476. class Notation(Identified, Childless, Node):
  1477.     nodeType = Node.NOTATION_NODE
  1478.     nodeValue = None
  1479.     
  1480.     def __init__(self, name, publicId, systemId):
  1481.         self.nodeName = name
  1482.         self._identified_mixin_init(publicId, systemId)
  1483.  
  1484.  
  1485.  
  1486. class DOMImplementation(DOMImplementationLS):
  1487.     _features = [
  1488.         ('core', '1.0'),
  1489.         ('core', '2.0'),
  1490.         ('core', '3.0'),
  1491.         ('core', None),
  1492.         ('xml', '1.0'),
  1493.         ('xml', '2.0'),
  1494.         ('xml', '3.0'),
  1495.         ('xml', None),
  1496.         ('ls-load', '3.0'),
  1497.         ('ls-load', None)]
  1498.     
  1499.     def hasFeature(self, feature, version):
  1500.         if version == '':
  1501.             version = None
  1502.         
  1503.         return (feature.lower(), version) in self._features
  1504.  
  1505.     
  1506.     def createDocument(self, namespaceURI, qualifiedName, doctype):
  1507.         if doctype and doctype.parentNode is not None:
  1508.             raise xml.dom.WrongDocumentErr('doctype object owned by another DOM tree')
  1509.         
  1510.         doc = self._create_document()
  1511.         if namespaceURI is None and qualifiedName is None:
  1512.             pass
  1513.         add_root_element = not (doctype is None)
  1514.         if not qualifiedName and add_root_element:
  1515.             raise xml.dom.InvalidCharacterErr('Element with no name')
  1516.         
  1517.         if add_root_element:
  1518.             (prefix, localname) = _nssplit(qualifiedName)
  1519.             if prefix == 'xml' and namespaceURI != 'http://www.w3.org/XML/1998/namespace':
  1520.                 raise xml.dom.NamespaceErr("illegal use of 'xml' prefix")
  1521.             
  1522.             if prefix and not namespaceURI:
  1523.                 raise xml.dom.NamespaceErr('illegal use of prefix without namespaces')
  1524.             
  1525.             element = doc.createElementNS(namespaceURI, qualifiedName)
  1526.             if doctype:
  1527.                 doc.appendChild(doctype)
  1528.             
  1529.             doc.appendChild(element)
  1530.         
  1531.         if doctype:
  1532.             doctype.parentNode = doctype.ownerDocument = doc
  1533.         
  1534.         doc.doctype = doctype
  1535.         doc.implementation = self
  1536.         return doc
  1537.  
  1538.     
  1539.     def createDocumentType(self, qualifiedName, publicId, systemId):
  1540.         doctype = DocumentType(qualifiedName)
  1541.         doctype.publicId = publicId
  1542.         doctype.systemId = systemId
  1543.         return doctype
  1544.  
  1545.     
  1546.     def getInterface(self, feature):
  1547.         if self.hasFeature(feature, None):
  1548.             return self
  1549.         else:
  1550.             return None
  1551.  
  1552.     
  1553.     def _create_document(self):
  1554.         return Document()
  1555.  
  1556.  
  1557.  
  1558. class ElementInfo(NewStyle):
  1559.     '''Object that represents content-model information for an element.
  1560.  
  1561.     This implementation is not expected to be used in practice; DOM
  1562.     builders should provide implementations which do the right thing
  1563.     using information available to it.
  1564.  
  1565.     '''
  1566.     __slots__ = ('tagName',)
  1567.     
  1568.     def __init__(self, name):
  1569.         self.tagName = name
  1570.  
  1571.     
  1572.     def getAttributeType(self, aname):
  1573.         return _no_type
  1574.  
  1575.     
  1576.     def getAttributeTypeNS(self, namespaceURI, localName):
  1577.         return _no_type
  1578.  
  1579.     
  1580.     def isElementContent(self):
  1581.         return False
  1582.  
  1583.     
  1584.     def isEmpty(self):
  1585.         '''Returns true iff this element is declared to have an EMPTY
  1586.         content model.'''
  1587.         return False
  1588.  
  1589.     
  1590.     def isId(self, aname):
  1591.         '''Returns true iff the named attribte is a DTD-style ID.'''
  1592.         return False
  1593.  
  1594.     
  1595.     def isIdNS(self, namespaceURI, localName):
  1596.         '''Returns true iff the identified attribute is a DTD-style ID.'''
  1597.         return False
  1598.  
  1599.     
  1600.     def __getstate__(self):
  1601.         return self.tagName
  1602.  
  1603.     
  1604.     def __setstate__(self, state):
  1605.         self.tagName = state
  1606.  
  1607.  
  1608.  
  1609. def _clear_id_cache(node):
  1610.     if node.nodeType == Node.DOCUMENT_NODE:
  1611.         node._id_cache.clear()
  1612.         node._id_search_stack = None
  1613.     elif _in_document(node):
  1614.         node.ownerDocument._id_cache.clear()
  1615.         node.ownerDocument._id_search_stack = None
  1616.     
  1617.  
  1618.  
  1619. class Document(Node, DocumentLS):
  1620.     _child_node_types = (Node.ELEMENT_NODE, Node.PROCESSING_INSTRUCTION_NODE, Node.COMMENT_NODE, Node.DOCUMENT_TYPE_NODE)
  1621.     nodeType = Node.DOCUMENT_NODE
  1622.     nodeName = '#document'
  1623.     nodeValue = None
  1624.     attributes = None
  1625.     doctype = None
  1626.     parentNode = None
  1627.     previousSibling = nextSibling = None
  1628.     implementation = DOMImplementation()
  1629.     actualEncoding = None
  1630.     encoding = None
  1631.     standalone = None
  1632.     version = None
  1633.     strictErrorChecking = False
  1634.     errorHandler = None
  1635.     documentURI = None
  1636.     _magic_id_count = 0
  1637.     
  1638.     def __init__(self):
  1639.         self.childNodes = NodeList()
  1640.         self._elem_info = { }
  1641.         self._id_cache = { }
  1642.         self._id_search_stack = None
  1643.  
  1644.     
  1645.     def _get_elem_info(self, element):
  1646.         if element.namespaceURI:
  1647.             key = (element.namespaceURI, element.localName)
  1648.         else:
  1649.             key = element.tagName
  1650.         return self._elem_info.get(key)
  1651.  
  1652.     
  1653.     def _get_actualEncoding(self):
  1654.         return self.actualEncoding
  1655.  
  1656.     
  1657.     def _get_doctype(self):
  1658.         return self.doctype
  1659.  
  1660.     
  1661.     def _get_documentURI(self):
  1662.         return self.documentURI
  1663.  
  1664.     
  1665.     def _get_encoding(self):
  1666.         return self.encoding
  1667.  
  1668.     
  1669.     def _get_errorHandler(self):
  1670.         return self.errorHandler
  1671.  
  1672.     
  1673.     def _get_standalone(self):
  1674.         return self.standalone
  1675.  
  1676.     
  1677.     def _get_strictErrorChecking(self):
  1678.         return self.strictErrorChecking
  1679.  
  1680.     
  1681.     def _get_version(self):
  1682.         return self.version
  1683.  
  1684.     
  1685.     def appendChild(self, node):
  1686.         if node.nodeType not in self._child_node_types:
  1687.             raise xml.dom.HierarchyRequestErr('%s cannot be child of %s' % (repr(node), repr(self)))
  1688.         
  1689.         if node.parentNode is not None:
  1690.             node.parentNode.removeChild(node)
  1691.         
  1692.         if node.nodeType == Node.ELEMENT_NODE and self._get_documentElement():
  1693.             raise xml.dom.HierarchyRequestErr('two document elements disallowed')
  1694.         
  1695.         return Node.appendChild(self, node)
  1696.  
  1697.     
  1698.     def removeChild(self, oldChild):
  1699.         
  1700.         try:
  1701.             self.childNodes.remove(oldChild)
  1702.         except ValueError:
  1703.             raise xml.dom.NotFoundErr()
  1704.  
  1705.         oldChild.nextSibling = oldChild.previousSibling = None
  1706.         oldChild.parentNode = None
  1707.         if self.documentElement is oldChild:
  1708.             self.documentElement = None
  1709.         
  1710.         return oldChild
  1711.  
  1712.     
  1713.     def _get_documentElement(self):
  1714.         for node in self.childNodes:
  1715.             if node.nodeType == Node.ELEMENT_NODE:
  1716.                 return node
  1717.                 continue
  1718.         
  1719.  
  1720.     
  1721.     def unlink(self):
  1722.         if self.doctype is not None:
  1723.             self.doctype.unlink()
  1724.             self.doctype = None
  1725.         
  1726.         Node.unlink(self)
  1727.  
  1728.     
  1729.     def cloneNode(self, deep):
  1730.         if not deep:
  1731.             return None
  1732.         
  1733.         clone = self.implementation.createDocument(None, None, None)
  1734.         clone.encoding = self.encoding
  1735.         clone.standalone = self.standalone
  1736.         clone.version = self.version
  1737.         for n in self.childNodes:
  1738.             childclone = _clone_node(n, deep, clone)
  1739.             clone.childNodes.append(childclone)
  1740.             if childclone.nodeType == Node.DOCUMENT_NODE:
  1741.                 pass
  1742.             elif childclone.nodeType == Node.DOCUMENT_TYPE_NODE:
  1743.                 clone.doctype = childclone
  1744.             
  1745.             childclone.parentNode = clone
  1746.         
  1747.         self._call_user_data_handler(xml.dom.UserDataHandler.NODE_CLONED, self, clone)
  1748.         return clone
  1749.  
  1750.     
  1751.     def createDocumentFragment(self):
  1752.         d = DocumentFragment()
  1753.         d.ownerDocument = self
  1754.         return d
  1755.  
  1756.     
  1757.     def createElement(self, tagName):
  1758.         e = Element(tagName)
  1759.         e.ownerDocument = self
  1760.         return e
  1761.  
  1762.     
  1763.     def createTextNode(self, data):
  1764.         if not isinstance(data, StringTypes):
  1765.             raise TypeError, 'node contents must be a string'
  1766.         
  1767.         t = Text()
  1768.         t.data = data
  1769.         t.ownerDocument = self
  1770.         return t
  1771.  
  1772.     
  1773.     def createCDATASection(self, data):
  1774.         if not isinstance(data, StringTypes):
  1775.             raise TypeError, 'node contents must be a string'
  1776.         
  1777.         c = CDATASection()
  1778.         c.data = data
  1779.         c.ownerDocument = self
  1780.         return c
  1781.  
  1782.     
  1783.     def createComment(self, data):
  1784.         c = Comment(data)
  1785.         c.ownerDocument = self
  1786.         return c
  1787.  
  1788.     
  1789.     def createProcessingInstruction(self, target, data):
  1790.         p = ProcessingInstruction(target, data)
  1791.         p.ownerDocument = self
  1792.         return p
  1793.  
  1794.     
  1795.     def createAttribute(self, qName):
  1796.         a = Attr(qName)
  1797.         a.ownerDocument = self
  1798.         a.value = ''
  1799.         return a
  1800.  
  1801.     
  1802.     def createElementNS(self, namespaceURI, qualifiedName):
  1803.         (prefix, localName) = _nssplit(qualifiedName)
  1804.         e = Element(qualifiedName, namespaceURI, prefix)
  1805.         e.ownerDocument = self
  1806.         return e
  1807.  
  1808.     
  1809.     def createAttributeNS(self, namespaceURI, qualifiedName):
  1810.         (prefix, localName) = _nssplit(qualifiedName)
  1811.         a = Attr(qualifiedName, namespaceURI, localName, prefix)
  1812.         a.ownerDocument = self
  1813.         a.value = ''
  1814.         return a
  1815.  
  1816.     
  1817.     def _create_entity(self, name, publicId, systemId, notationName):
  1818.         e = Entity(name, publicId, systemId, notationName)
  1819.         e.ownerDocument = self
  1820.         return e
  1821.  
  1822.     
  1823.     def _create_notation(self, name, publicId, systemId):
  1824.         n = Notation(name, publicId, systemId)
  1825.         n.ownerDocument = self
  1826.         return n
  1827.  
  1828.     
  1829.     def getElementById(self, id):
  1830.         if self._id_cache.has_key(id):
  1831.             return self._id_cache[id]
  1832.         
  1833.         if not self._elem_info:
  1834.             pass
  1835.         if not (self._magic_id_count):
  1836.             return None
  1837.         
  1838.         stack = self._id_search_stack
  1839.         if stack is None:
  1840.             stack = [
  1841.                 self.documentElement]
  1842.             self._id_search_stack = stack
  1843.         elif not stack:
  1844.             return None
  1845.         
  1846.         result = None
  1847.         for child in node.childNodes:
  1848.             if child.nodeType in _nodeTypes_with_children:
  1849.                 _[1](child)
  1850.                 continue
  1851.             []
  1852.             continue
  1853.             stack.extend([])
  1854.             info = self._get_elem_info(node)
  1855.             if info:
  1856.                 for attr in node.attributes.values():
  1857.                     if attr.namespaceURI:
  1858.                         if info.isIdNS(attr.namespaceURI, attr.localName):
  1859.                             self._id_cache[attr.value] = node
  1860.                             if attr.value == id:
  1861.                                 result = node
  1862.                             elif not (node._magic_id_nodes):
  1863.                                 break
  1864.                             
  1865.                         
  1866.                     info.isIdNS(attr.namespaceURI, attr.localName)
  1867.                     if info.isId(attr.name):
  1868.                         self._id_cache[attr.value] = node
  1869.                         if attr.value == id:
  1870.                             result = node
  1871.                         elif not (node._magic_id_nodes):
  1872.                             break
  1873.                         
  1874.                     attr.value == id
  1875.                     if attr._is_id:
  1876.                         self._id_cache[attr.value] = node
  1877.                         if attr.value == id:
  1878.                             result = node
  1879.                         elif node._magic_id_nodes == 1:
  1880.                             break
  1881.                         
  1882.                     attr.value == id
  1883.                 
  1884.             elif node._magic_id_nodes:
  1885.                 for attr in node.attributes.values():
  1886.                     if attr._is_id:
  1887.                         self._id_cache[attr.value] = node
  1888.                         if attr.value == id:
  1889.                             result = node
  1890.                         
  1891.                     attr.value == id
  1892.                 
  1893.             
  1894.             if result is not None:
  1895.                 break
  1896.                 continue
  1897.         return result
  1898.  
  1899.     
  1900.     def getElementsByTagName(self, name):
  1901.         return _get_elements_by_tagName_helper(self, name, NodeList())
  1902.  
  1903.     
  1904.     def getElementsByTagNameNS(self, namespaceURI, localName):
  1905.         return _get_elements_by_tagName_ns_helper(self, namespaceURI, localName, NodeList())
  1906.  
  1907.     
  1908.     def isSupported(self, feature, version):
  1909.         return self.implementation.hasFeature(feature, version)
  1910.  
  1911.     
  1912.     def importNode(self, node, deep):
  1913.         if node.nodeType == Node.DOCUMENT_NODE:
  1914.             raise xml.dom.NotSupportedErr('cannot import document nodes')
  1915.         elif node.nodeType == Node.DOCUMENT_TYPE_NODE:
  1916.             raise xml.dom.NotSupportedErr('cannot import document type nodes')
  1917.         
  1918.         return _clone_node(node, deep, self)
  1919.  
  1920.     
  1921.     def writexml(self, writer, indent = '', addindent = '', newl = '', encoding = None):
  1922.         if encoding is None:
  1923.             writer.write('<?xml version="1.0" ?>\n')
  1924.         else:
  1925.             writer.write('<?xml version="1.0" encoding="%s"?>\n' % encoding)
  1926.         for node in self.childNodes:
  1927.             node.writexml(writer, indent, addindent, newl)
  1928.         
  1929.  
  1930.     
  1931.     def renameNode(self, n, namespaceURI, name):
  1932.         if n.ownerDocument is not self:
  1933.             raise xml.dom.WrongDocumentErr('cannot rename nodes from other documents;\nexpected %s,\nfound %s' % (self, n.ownerDocument))
  1934.         
  1935.         if n.nodeType not in (Node.ELEMENT_NODE, Node.ATTRIBUTE_NODE):
  1936.             raise xml.dom.NotSupportedErr('renameNode() only applies to element and attribute nodes')
  1937.         
  1938.         if namespaceURI != EMPTY_NAMESPACE:
  1939.             if ':' in name:
  1940.                 (prefix, localName) = name.split(':', 1)
  1941.                 if prefix == 'xmlns' and namespaceURI != xml.dom.XMLNS_NAMESPACE:
  1942.                     raise xml.dom.NamespaceErr("illegal use of 'xmlns' prefix")
  1943.                 
  1944.             elif name == 'xmlns' and namespaceURI != xml.dom.XMLNS_NAMESPACE and n.nodeType == Node.ATTRIBUTE_NODE:
  1945.                 raise xml.dom.NamespaceErr("illegal use of the 'xmlns' attribute")
  1946.             
  1947.             prefix = None
  1948.             localName = name
  1949.         else:
  1950.             prefix = None
  1951.             localName = None
  1952.         if n.nodeType == Node.ATTRIBUTE_NODE:
  1953.             element = n.ownerElement
  1954.             if element is not None:
  1955.                 is_id = n._is_id
  1956.                 element.removeAttributeNode(n)
  1957.             
  1958.         else:
  1959.             element = None
  1960.         d = n.__dict__
  1961.         d['prefix'] = prefix
  1962.         d['localName'] = localName
  1963.         d['namespaceURI'] = namespaceURI
  1964.         d['nodeName'] = name
  1965.         if n.nodeType == Node.ELEMENT_NODE:
  1966.             d['tagName'] = name
  1967.         else:
  1968.             d['name'] = name
  1969.             if element is not None:
  1970.                 element.setAttributeNode(n)
  1971.                 if is_id:
  1972.                     element.setIdAttributeNode(n)
  1973.                 
  1974.             
  1975.         return n
  1976.  
  1977.  
  1978. defproperty(Document, 'documentElement', doc = 'Top-level element of this document.')
  1979.  
  1980. def _clone_node(node, deep, newOwnerDocument):
  1981.     '''
  1982.     Clone a node and give it the new owner document.
  1983.     Called by Node.cloneNode and Document.importNode
  1984.     '''
  1985.     if node.ownerDocument.isSameNode(newOwnerDocument):
  1986.         operation = xml.dom.UserDataHandler.NODE_CLONED
  1987.     else:
  1988.         operation = xml.dom.UserDataHandler.NODE_IMPORTED
  1989.     if node.nodeType == Node.ELEMENT_NODE:
  1990.         clone = newOwnerDocument.createElementNS(node.namespaceURI, node.nodeName)
  1991.         for attr in node.attributes.values():
  1992.             clone.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value)
  1993.             a = clone.getAttributeNodeNS(attr.namespaceURI, attr.localName)
  1994.             a.specified = attr.specified
  1995.         
  1996.         if deep:
  1997.             for child in node.childNodes:
  1998.                 c = _clone_node(child, deep, newOwnerDocument)
  1999.                 clone.appendChild(c)
  2000.             
  2001.         
  2002.     elif node.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
  2003.         clone = newOwnerDocument.createDocumentFragment()
  2004.         if deep:
  2005.             for child in node.childNodes:
  2006.                 c = _clone_node(child, deep, newOwnerDocument)
  2007.                 clone.appendChild(c)
  2008.             
  2009.         
  2010.     elif node.nodeType == Node.TEXT_NODE:
  2011.         clone = newOwnerDocument.createTextNode(node.data)
  2012.     elif node.nodeType == Node.CDATA_SECTION_NODE:
  2013.         clone = newOwnerDocument.createCDATASection(node.data)
  2014.     elif node.nodeType == Node.PROCESSING_INSTRUCTION_NODE:
  2015.         clone = newOwnerDocument.createProcessingInstruction(node.target, node.data)
  2016.     elif node.nodeType == Node.COMMENT_NODE:
  2017.         clone = newOwnerDocument.createComment(node.data)
  2018.     elif node.nodeType == Node.ATTRIBUTE_NODE:
  2019.         clone = newOwnerDocument.createAttributeNS(node.namespaceURI, node.nodeName)
  2020.         clone.specified = True
  2021.         clone.value = node.value
  2022.     elif node.nodeType == Node.DOCUMENT_TYPE_NODE:
  2023.         operation = xml.dom.UserDataHandler.NODE_IMPORTED
  2024.         clone = newOwnerDocument.implementation.createDocumentType(node.name, node.publicId, node.systemId)
  2025.         clone.ownerDocument = newOwnerDocument
  2026.         if deep:
  2027.             clone.entities._seq = []
  2028.             clone.notations._seq = []
  2029.             for n in node.notations._seq:
  2030.                 notation = Notation(n.nodeName, n.publicId, n.systemId)
  2031.                 notation.ownerDocument = newOwnerDocument
  2032.                 clone.notations._seq.append(notation)
  2033.                 if hasattr(n, '_call_user_data_handler'):
  2034.                     n._call_user_data_handler(operation, n, notation)
  2035.                     continue
  2036.             
  2037.             for e in node.entities._seq:
  2038.                 entity = Entity(e.nodeName, e.publicId, e.systemId, e.notationName)
  2039.                 entity.actualEncoding = e.actualEncoding
  2040.                 entity.encoding = e.encoding
  2041.                 entity.version = e.version
  2042.                 entity.ownerDocument = newOwnerDocument
  2043.                 clone.entities._seq.append(entity)
  2044.                 if hasattr(e, '_call_user_data_handler'):
  2045.                     e._call_user_data_handler(operation, n, entity)
  2046.                     continue
  2047.             
  2048.         
  2049.     else:
  2050.         raise xml.dom.NotSupportedErr('Cannot clone node %s' % repr(node))
  2051.     if hasattr(node, '_call_user_data_handler'):
  2052.         node._call_user_data_handler(operation, node, clone)
  2053.     
  2054.     return clone
  2055.  
  2056.  
  2057. def _nssplit(qualifiedName):
  2058.     fields = qualifiedName.split(':', 1)
  2059.     if len(fields) == 2:
  2060.         return fields
  2061.     else:
  2062.         return (None, fields[0])
  2063.  
  2064.  
  2065. def _get_StringIO():
  2066.     StringIO = StringIO
  2067.     import StringIO
  2068.     return StringIO()
  2069.  
  2070.  
  2071. def _do_pulldom_parse(func, args, kwargs):
  2072.     events = func(*args, **kwargs)
  2073.     (toktype, rootNode) = events.getEvent()
  2074.     events.expandNode(rootNode)
  2075.     events.clear()
  2076.     return rootNode
  2077.  
  2078.  
  2079. def parse(file, parser = None, bufsize = None):
  2080.     '''Parse a file into a DOM by filename or file object.'''
  2081.     if parser is None and not bufsize:
  2082.         expatbuilder = expatbuilder
  2083.         import xml.dom
  2084.         return expatbuilder.parse(file)
  2085.     else:
  2086.         pulldom = pulldom
  2087.         import xml.dom
  2088.         return _do_pulldom_parse(pulldom.parse, (file,), {
  2089.             'parser': parser,
  2090.             'bufsize': bufsize })
  2091.  
  2092.  
  2093. def parseString(string, parser = None):
  2094.     '''Parse a file into a DOM from a string.'''
  2095.     if parser is None:
  2096.         expatbuilder = expatbuilder
  2097.         import xml.dom
  2098.         return expatbuilder.parseString(string)
  2099.     else:
  2100.         pulldom = pulldom
  2101.         import xml.dom
  2102.         return _do_pulldom_parse(pulldom.parseString, (string,), {
  2103.             'parser': parser })
  2104.  
  2105.  
  2106. def getDOMImplementation(features = None):
  2107.     if features:
  2108.         if isinstance(features, StringTypes):
  2109.             features = domreg._parse_feature_string(features)
  2110.         
  2111.         for f, v in features:
  2112.             if not Document.implementation.hasFeature(f, v):
  2113.                 return None
  2114.                 continue
  2115.         
  2116.     
  2117.     return Document.implementation
  2118.  
  2119.