10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""Simple implementation of the Level 1 DOM. 20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiNamespaces and other minor Level 2 features are also supported. 40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiparse("foo.xml") 60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiparseString("<foo><bar/></foo>") 80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTodo: 100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi===== 110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi * convenience methods for getting elements and text. 120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi * more testing 130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi * bring some of the writer and linearizer code into conformance with this 140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi interface 150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi * SAX 2 namespaces 160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport xml.dom 190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE, domreg 210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom xml.dom.minicompat import * 220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom xml.dom.xmlbuilder import DOMImplementationLS, DocumentLS 230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# This is used by the ID-cache invalidation checks; the list isn't 250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# actually complete, since the nodes being checked will never be the 260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# DOCUMENT_NODE or DOCUMENT_FRAGMENT_NODE. (The node being checked is 270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# the node being added or removed, not the node being modified.) 280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_nodeTypes_with_children = (xml.dom.Node.ELEMENT_NODE, 300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xml.dom.Node.ENTITY_REFERENCE_NODE) 310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Node(xml.dom.Node): 340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi namespaceURI = None # this is non-null only for elements and attributes 350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parentNode = None 360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ownerDocument = None 370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nextSibling = None 380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi previousSibling = None 390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix = EMPTY_PREFIX # non-null only for NS elements and attributes 410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __nonzero__(self): 430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def toxml(self, encoding = None): 460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.toprettyxml("", "", encoding) 470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def toprettyxml(self, indent="\t", newl="\n", encoding = None): 490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # indent = the indentation string to prepend, per level 500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # newl = the newline string to append 510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer = _get_StringIO() 520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if encoding is not None: 530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi import codecs 540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Can't use codecs.getwriter to preserve 2.0 compatibility 550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer = codecs.lookup(encoding)[3](writer) 560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.nodeType == Node.DOCUMENT_NODE: 570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Can pass encoding only to document, to put it into XML header 580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.writexml(writer, "", indent, newl, encoding) 590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.writexml(writer, "", indent, newl) 610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return writer.getvalue() 620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def hasChildNodes(self): 640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.childNodes: 650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_childNodes(self): 700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.childNodes 710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_firstChild(self): 730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.childNodes: 740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.childNodes[0] 750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_lastChild(self): 770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.childNodes: 780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.childNodes[-1] 790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def insertBefore(self, newChild, refChild): 810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE: 820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in tuple(newChild.childNodes): 830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.insertBefore(c, refChild) 840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ### The DOM does not clearly specify what to return in this case 850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return newChild 860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.nodeType not in self._child_node_types: 870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "%s cannot be child of %s" % (repr(newChild), repr(self))) 890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.parentNode is not None: 900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.parentNode.removeChild(newChild) 910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if refChild is None: 920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.appendChild(newChild) 930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi index = self.childNodes.index(refChild) 960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except ValueError: 970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.nodeType in _nodeTypes_with_children: 990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self) 1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes.insert(index, newChild) 1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.nextSibling = refChild 1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi refChild.previousSibling = newChild 1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if index: 1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = self.childNodes[index-1] 1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.nextSibling = newChild 1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.previousSibling = node 1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.previousSibling = None 1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.parentNode = self 1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return newChild 1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def appendChild(self, node): 1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == self.DOCUMENT_FRAGMENT_NODE: 1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in tuple(node.childNodes): 1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.appendChild(c) 1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ### The DOM does not clearly specify what to return in this case 1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return node 1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType not in self._child_node_types: 1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "%s cannot be child of %s" % (repr(node), repr(self))) 1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType in _nodeTypes_with_children: 1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self) 1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.parentNode is not None: 1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.parentNode.removeChild(node) 1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _append_child(self, node) 1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.nextSibling = None 1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return node 1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def replaceChild(self, newChild, oldChild): 1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE: 1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi refChild = oldChild.nextSibling 1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.removeChild(oldChild) 1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.insertBefore(newChild, refChild) 1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.nodeType not in self._child_node_types: 1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "%s cannot be child of %s" % (repr(newChild), repr(self))) 1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild is oldChild: 1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.parentNode is not None: 1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.parentNode.removeChild(newChild) 1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi index = self.childNodes.index(oldChild) 1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except ValueError: 1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes[index] = newChild 1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.parentNode = self 1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.parentNode = None 1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if (newChild.nodeType in _nodeTypes_with_children 1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi or oldChild.nodeType in _nodeTypes_with_children): 1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self) 1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.nextSibling = oldChild.nextSibling 1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.previousSibling = oldChild.previousSibling 1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.nextSibling = None 1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.previousSibling = None 1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.previousSibling: 1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.previousSibling.nextSibling = newChild 1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if newChild.nextSibling: 1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newChild.nextSibling.previousSibling = newChild 1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return oldChild 1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeChild(self, oldChild): 1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes.remove(oldChild) 1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except ValueError: 1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if oldChild.nextSibling is not None: 1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.nextSibling.previousSibling = oldChild.previousSibling 1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if oldChild.previousSibling is not None: 1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.previousSibling.nextSibling = oldChild.nextSibling 1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.nextSibling = oldChild.previousSibling = None 1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if oldChild.nodeType in _nodeTypes_with_children: 1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self) 1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.parentNode = None 1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return oldChild 1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def normalize(self): 1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L = [] 1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for child in self.childNodes: 1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if child.nodeType == Node.TEXT_NODE: 1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not child.data: 1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # empty text node; discard 1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if L: 1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L[-1].nextSibling = child.nextSibling 1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if child.nextSibling: 1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi child.nextSibling.previousSibling = child.previousSibling 1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi child.unlink() 1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif L and L[-1].nodeType == child.nodeType: 1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # collapse text node 1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = L[-1] 1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.data = node.data + child.data 1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.nextSibling = child.nextSibling 1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if child.nextSibling: 1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi child.nextSibling.previousSibling = node 1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi child.unlink() 1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L.append(child) 1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L.append(child) 2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if child.nodeType == Node.ELEMENT_NODE: 2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi child.normalize() 2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes[:] = L 2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def cloneNode(self, deep): 2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _clone_node(self, deep, self.ownerDocument or self) 2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def isSupported(self, feature, version): 2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.ownerDocument.implementation.hasFeature(feature, version) 2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_localName(self): 2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Overridden in Element and Attr where localName can be Non-Null 2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Node interfaces from Level 3 (WD 9 April 2002) 2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def isSameNode(self, other): 2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self is other 2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getInterface(self, feature): 2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.isSupported(feature, None): 2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The "user data" functions use a dictionary that is only present 2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if some user data has been set, so be careful not to assume it 2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # exists. 2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getUserData(self, key): 2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._user_data[key][0] 2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except (AttributeError, KeyError): 2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setUserData(self, key, data, handler): 2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi old = None 2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self._user_data 2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except AttributeError: 2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = {} 2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._user_data = d 2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if key in d: 2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi old = d[key][0] 2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if data is None: 2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # ignore handlers passed for None 2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi handler = None 2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if old is not None: 2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del d[key] 2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d[key] = (data, handler) 2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return old 2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _call_user_data_handler(self, operation, src, dst): 2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if hasattr(self, "_user_data"): 2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for key, (data, handler) in self._user_data.items(): 2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if handler is not None: 2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi handler.handle(operation, key, data, src, dst) 2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # minidom-specific API: 2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def unlink(self): 2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.parentNode = self.ownerDocument = None 2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.childNodes: 2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for child in self.childNodes: 2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi child.unlink() 2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes = NodeList() 2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.previousSibling = None 2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.nextSibling = None 2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Node, "firstChild", doc="First child node, or None.") 2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Node, "lastChild", doc="Last child node, or None.") 2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Node, "localName", doc="Namespace-local name of this node.") 2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _append_child(self, node): 2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # fast path with less checks; usable by DOM builders if careful 2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi childNodes = self.childNodes 2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if childNodes: 2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi last = childNodes[-1] 2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.__dict__["previousSibling"] = last 2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi last.__dict__["nextSibling"] = node 2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi childNodes.append(node) 2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.__dict__["parentNode"] = self 2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _in_document(node): 2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # return True iff node is part of a document tree 2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while node is not None: 2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == Node.DOCUMENT_NODE: 2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = node.parentNode 2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _write_data(writer, data): 2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "Writes datachars to writer." 2950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if data: 2960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi data = data.replace("&", "&").replace("<", "<"). \ 2970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi replace("\"", """).replace(">", ">") 2980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(data) 2990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _get_elements_by_tagName_helper(parent, name, rc): 3010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for node in parent.childNodes: 3020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == Node.ELEMENT_NODE and \ 3030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (name == "*" or node.tagName == name): 3040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rc.append(node) 3050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _get_elements_by_tagName_helper(node, name, rc) 3060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return rc 3070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _get_elements_by_tagName_ns_helper(parent, nsURI, localName, rc): 3090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for node in parent.childNodes: 3100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == Node.ELEMENT_NODE: 3110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ((localName == "*" or node.localName == localName) and 3120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (nsURI == "*" or node.namespaceURI == nsURI)): 3130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rc.append(node) 3140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _get_elements_by_tagName_ns_helper(node, nsURI, localName, rc) 3150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return rc 3160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass DocumentFragment(Node): 3180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.DOCUMENT_FRAGMENT_NODE 3190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeName = "#document-fragment" 3200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeValue = None 3210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attributes = None 3220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parentNode = None 3230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _child_node_types = (Node.ELEMENT_NODE, 3240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.TEXT_NODE, 3250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.CDATA_SECTION_NODE, 3260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.ENTITY_REFERENCE_NODE, 3270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.PROCESSING_INSTRUCTION_NODE, 3280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.COMMENT_NODE, 3290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.NOTATION_NODE) 3300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self): 3320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes = NodeList() 3330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Attr(Node): 3360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.ATTRIBUTE_NODE 3370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attributes = None 3380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ownerElement = None 3390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi specified = False 3400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _is_id = False 3410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _child_node_types = (Node.TEXT_NODE, Node.ENTITY_REFERENCE_NODE) 3430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, qName, namespaceURI=EMPTY_NAMESPACE, localName=None, 3450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix=None): 3460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # skip setattr for performance 3470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self.__dict__ 3480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["nodeName"] = d["name"] = qName 3490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["namespaceURI"] = namespaceURI 3500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["prefix"] = prefix 3510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['childNodes'] = NodeList() 3520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Add the single child node that represents the value of the attr 3540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes.append(Text()) 3550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # nodeValue and value are set elsewhere 3570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_localName(self): 3590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.nodeName.split(":", 1)[-1] 3600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_name(self): 3620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.name 3630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_specified(self): 3650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.specified 3660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __setattr__(self, name, value): 3680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self.__dict__ 3690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if name in ("value", "nodeValue"): 3700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["value"] = d["nodeValue"] = value 3710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d2 = self.childNodes[0].__dict__ 3720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d2["data"] = d2["nodeValue"] = value 3730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.ownerElement is not None: 3740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self.ownerElement) 3750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif name in ("name", "nodeName"): 3760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["name"] = d["nodeName"] = value 3770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.ownerElement is not None: 3780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self.ownerElement) 3790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 3800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d[name] = value 3810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _set_prefix(self, prefix): 3830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nsuri = self.namespaceURI 3840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if prefix == "xmlns": 3850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if nsuri and nsuri != XMLNS_NAMESPACE: 3860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NamespaceErr( 3870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "illegal use of 'xmlns' prefix for the wrong namespace") 3880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self.__dict__ 3890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['prefix'] = prefix 3900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if prefix is None: 3910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newName = self.localName 3920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 3930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newName = "%s:%s" % (prefix, self.localName) 3940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.ownerElement: 3950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self.ownerElement) 3960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['nodeName'] = d['name'] = newName 3970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _set_value(self, value): 3990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self.__dict__ 4000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['value'] = d['nodeValue'] = value 4010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.ownerElement: 4020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self.ownerElement) 4030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes[0].data = value 4040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def unlink(self): 4060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This implementation does not call the base implementation 4070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # since most of that is not needed, and the expense of the 4080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # method call is not warranted. We duplicate the removal of 4090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # children, but that's all we needed from the base class. 4100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elem = self.ownerElement 4110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if elem is not None: 4120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del elem._attrs[self.nodeName] 4130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del elem._attrsNS[(self.namespaceURI, self.localName)] 4140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_id: 4150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._is_id = False 4160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elem._magic_id_nodes -= 1 4170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ownerDocument._magic_id_count -= 1 4180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for child in self.childNodes: 4190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi child.unlink() 4200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del self.childNodes[:] 4210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_isId(self): 4230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._is_id: 4240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 4250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc = self.ownerDocument 4260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elem = self.ownerElement 4270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if doc is None or elem is None: 4280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 4290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi info = doc._get_elem_info(elem) 4310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if info is None: 4320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 4330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.namespaceURI: 4340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return info.isIdNS(self.namespaceURI, self.localName) 4350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 4360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return info.isId(self.nodeName) 4370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_schemaType(self): 4390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc = self.ownerDocument 4400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elem = self.ownerElement 4410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if doc is None or elem is None: 4420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _no_type 4430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi info = doc._get_elem_info(elem) 4450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if info is None: 4460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _no_type 4470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.namespaceURI: 4480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return info.getAttributeTypeNS(self.namespaceURI, self.localName) 4490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 4500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return info.getAttributeType(self.nodeName) 4510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Attr, "isId", doc="True if this attribute is an ID.") 4530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Attr, "localName", doc="Namespace-local name of this attribute.") 4540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Attr, "schemaType", doc="Schema type for this attribute.") 4550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass NamedNodeMap(object): 4580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """The attribute list is a transient interface to the underlying 4590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dictionaries. Mutations here will change the underlying element's 4600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dictionary. 4610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Ordering is imposed artificially and does not reflect the order of 4630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attributes as found in an input document. 4640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 4650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __slots__ = ('_attrs', '_attrsNS', '_ownerElement') 4670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, attrs, attrsNS, ownerElement): 4690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrs = attrs 4700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrsNS = attrsNS 4710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._ownerElement = ownerElement 4720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_length(self): 4740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(self._attrs) 4750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def item(self, index): 4770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 4780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self[self._attrs.keys()[index]] 4790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except IndexError: 4800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 4810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def items(self): 4830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L = [] 4840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for node in self._attrs.values(): 4850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L.append((node.nodeName, node.value)) 4860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return L 4870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def itemsNS(self): 4890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L = [] 4900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for node in self._attrs.values(): 4910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L.append(((node.namespaceURI, node.localName), node.value)) 4920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return L 4930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def has_key(self, key): 4950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(key, StringTypes): 4960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return key in self._attrs 4970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 4980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return key in self._attrsNS 4990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def keys(self): 5010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrs.keys() 5020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def keysNS(self): 5040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrsNS.keys() 5050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def values(self): 5070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrs.values() 5080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def get(self, name, value=None): 5100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrs.get(name, value) 5110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __len__ = _get_length 5130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __hash__ = None # Mutable type can't be correctly hashed 5150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __cmp__(self, other): 5160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._attrs is getattr(other, "_attrs", None): 5170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 5180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return cmp(id(self), id(other)) 5200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __getitem__(self, attname_or_tuple): 5220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(attname_or_tuple, tuple): 5230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrsNS[attname_or_tuple] 5240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrs[attname_or_tuple] 5260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # same as set 5280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __setitem__(self, attname, value): 5290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(value, StringTypes): 5300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 5310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = self._attrs[attname] 5320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 5330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = Attr(attname) 5340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.ownerDocument = self._ownerElement.ownerDocument 5350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.setNamedItem(node) 5360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.value = value 5370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not isinstance(value, Attr): 5390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError, "value must be a string or Attr object" 5400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = value 5410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.setNamedItem(node) 5420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getNamedItem(self, name): 5440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 5450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrs[name] 5460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 5470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 5480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getNamedItemNS(self, namespaceURI, localName): 5500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 5510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrsNS[(namespaceURI, localName)] 5520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 5530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 5540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeNamedItem(self, name): 5560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = self.getNamedItem(name) 5570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n is not None: 5580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self._ownerElement) 5590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del self._attrs[n.nodeName] 5600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del self._attrsNS[(n.namespaceURI, n.localName)] 5610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if 'ownerElement' in n.__dict__: 5620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n.__dict__['ownerElement'] = None 5630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return n 5640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 5660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeNamedItemNS(self, namespaceURI, localName): 5680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = self.getNamedItemNS(namespaceURI, localName) 5690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n is not None: 5700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self._ownerElement) 5710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del self._attrsNS[(n.namespaceURI, n.localName)] 5720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del self._attrs[n.nodeName] 5730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if 'ownerElement' in n.__dict__: 5740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n.__dict__['ownerElement'] = None 5750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return n 5760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 5770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 5780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setNamedItem(self, node): 5800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not isinstance(node, Attr): 5810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 5820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "%s cannot be child of %s" % (repr(node), repr(self))) 5830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi old = self._attrs.get(node.name) 5840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if old: 5850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi old.unlink() 5860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrs[node.name] = node 5870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrsNS[(node.namespaceURI, node.localName)] = node 5880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.ownerElement = self._ownerElement 5890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(node.ownerElement) 5900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return old 5910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setNamedItemNS(self, node): 5930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.setNamedItem(node) 5940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __delitem__(self, attname_or_tuple): 5960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = self[attname_or_tuple] 5970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(node.ownerElement) 5980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.unlink() 5990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __getstate__(self): 6010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrs, self._attrsNS, self._ownerElement 6020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __setstate__(self, state): 6040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrs, self._attrsNS, self._ownerElement = state 6050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(NamedNodeMap, "length", 6070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc="Number of nodes in the NamedNodeMap.") 6080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiAttributeList = NamedNodeMap 6100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TypeInfo(object): 6130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __slots__ = 'namespace', 'name' 6140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, namespace, name): 6160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.namespace = namespace 6170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.name = name 6180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __repr__(self): 6200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.namespace: 6210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "<TypeInfo %r (from %r)>" % (self.name, self.namespace) 6220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 6230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "<TypeInfo %r>" % self.name 6240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_name(self): 6260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.name 6270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_namespace(self): 6290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.namespace 6300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_no_type = TypeInfo(None, None) 6320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Element(Node): 6340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.ELEMENT_NODE 6350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeValue = None 6360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi schemaType = _no_type 6370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _magic_id_nodes = 0 6390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _child_node_types = (Node.ELEMENT_NODE, 6410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.PROCESSING_INSTRUCTION_NODE, 6420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.COMMENT_NODE, 6430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.TEXT_NODE, 6440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.CDATA_SECTION_NODE, 6450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.ENTITY_REFERENCE_NODE) 6460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, tagName, namespaceURI=EMPTY_NAMESPACE, prefix=None, 6480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi localName=None): 6490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.tagName = self.nodeName = tagName 6500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.prefix = prefix 6510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.namespaceURI = namespaceURI 6520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes = NodeList() 6530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrs = {} # attributes are double-indexed: 6550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrsNS = {} # tagName -> Attribute 6560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # URI,localName -> Attribute 6570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # in the future: consider lazy generation 6580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # of attribute objects this is too tricky 6590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for now because of headaches with 6600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # namespaces. 6610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_localName(self): 6630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.tagName.split(":", 1)[-1] 6640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_tagName(self): 6660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.tagName 6670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def unlink(self): 6690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for attr in self._attrs.values(): 6700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attr.unlink() 6710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrs = None 6720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrsNS = None 6730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.unlink(self) 6740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getAttribute(self, attname): 6760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 6770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrs[attname].value 6780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 6790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "" 6800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getAttributeNS(self, namespaceURI, localName): 6820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 6830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrsNS[(namespaceURI, localName)].value 6840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 6850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "" 6860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setAttribute(self, attname, value): 6880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attr = self.getAttributeNode(attname) 6890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr is None: 6900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attr = Attr(attname) 6910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for performance 6920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = attr.__dict__ 6930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["value"] = d["nodeValue"] = value 6940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["ownerDocument"] = self.ownerDocument 6950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.setAttributeNode(attr) 6960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif value != attr.value: 6970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = attr.__dict__ 6980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["value"] = d["nodeValue"] = value 6990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.isId: 7000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self) 7010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setAttributeNS(self, namespaceURI, qualifiedName, value): 7030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix, localname = _nssplit(qualifiedName) 7040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attr = self.getAttributeNodeNS(namespaceURI, localname) 7050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr is None: 7060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for performance 7070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attr = Attr(qualifiedName, namespaceURI, localname, prefix) 7080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = attr.__dict__ 7090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["prefix"] = prefix 7100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["nodeName"] = qualifiedName 7110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["value"] = d["nodeValue"] = value 7120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["ownerDocument"] = self.ownerDocument 7130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.setAttributeNode(attr) 7140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 7150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = attr.__dict__ 7160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if value != attr.value: 7170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["value"] = d["nodeValue"] = value 7180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.isId: 7190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self) 7200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.prefix != prefix: 7210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["prefix"] = prefix 7220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d["nodeName"] = qualifiedName 7230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getAttributeNode(self, attrname): 7250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrs.get(attrname) 7260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getAttributeNodeNS(self, namespaceURI, localName): 7280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._attrsNS.get((namespaceURI, localName)) 7290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setAttributeNode(self, attr): 7310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.ownerElement not in (None, self): 7320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.InuseAttributeErr("attribute node already owned") 7330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi old1 = self._attrs.get(attr.name, None) 7340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if old1 is not None: 7350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.removeAttributeNode(old1) 7360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi old2 = self._attrsNS.get((attr.namespaceURI, attr.localName), None) 7370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if old2 is not None and old2 is not old1: 7380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.removeAttributeNode(old2) 7390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _set_attribute_node(self, attr) 7400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if old1 is not attr: 7420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # It might have already been part of this node, in which case 7430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # it doesn't represent a change, and should not be returned. 7440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return old1 7450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if old2 is not attr: 7460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return old2 7470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi setAttributeNodeNS = setAttributeNode 7490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeAttribute(self, name): 7510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 7520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attr = self._attrs[name] 7530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 7540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 7550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.removeAttributeNode(attr) 7560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeAttributeNS(self, namespaceURI, localName): 7580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 7590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attr = self._attrsNS[(namespaceURI, localName)] 7600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 7610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 7620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.removeAttributeNode(attr) 7630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeAttributeNode(self, node): 7650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node is None: 7660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 7670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 7680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._attrs[node.name] 7690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 7700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 7710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self) 7720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.unlink() 7730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Restore this since the node is still useful and otherwise 7740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # unlinked 7750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.ownerDocument = self.ownerDocument 7760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi removeAttributeNodeNS = removeAttributeNode 7780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def hasAttribute(self, name): 7800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return name in self._attrs 7810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def hasAttributeNS(self, namespaceURI, localName): 7830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (namespaceURI, localName) in self._attrsNS 7840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getElementsByTagName(self, name): 7860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _get_elements_by_tagName_helper(self, name, NodeList()) 7870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getElementsByTagNameNS(self, namespaceURI, localName): 7890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _get_elements_by_tagName_ns_helper( 7900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self, namespaceURI, localName, NodeList()) 7910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __repr__(self): 7930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return "<DOM Element: %s at %#x>" % (self.tagName, id(self)) 7940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def writexml(self, writer, indent="", addindent="", newl=""): 7960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # indent = current indentation 7970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # addindent = indentation to add to higher levels 7980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # newl = newline string 7990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(indent+"<" + self.tagName) 8000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attrs = self._get_attributes() 8020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a_names = attrs.keys() 8030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a_names.sort() 8040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for a_name in a_names: 8060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(" %s=\"" % a_name) 8070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _write_data(writer, attrs[a_name].value) 8080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("\"") 8090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.childNodes: 8100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(">") 8110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if (len(self.childNodes) == 1 and 8120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes[0].nodeType == Node.TEXT_NODE): 8130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes[0].writexml(writer, '', '', '') 8140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 8150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(newl) 8160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for node in self.childNodes: 8170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.writexml(writer, indent+addindent, addindent, newl) 8180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(indent) 8190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("</%s>%s" % (self.tagName, newl)) 8200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 8210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("/>%s"%(newl)) 8220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_attributes(self): 8240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return NamedNodeMap(self._attrs, self._attrsNS, self) 8250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def hasAttributes(self): 8270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self._attrs: 8280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return True 8290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 8300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 8310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # DOM Level 3 attributes, based on the 22 Oct 2002 draft 8330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setIdAttribute(self, name): 8350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi idAttr = self.getAttributeNode(name) 8360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.setIdAttributeNode(idAttr) 8370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setIdAttributeNS(self, namespaceURI, localName): 8390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi idAttr = self.getAttributeNodeNS(namespaceURI, localName) 8400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.setIdAttributeNode(idAttr) 8410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setIdAttributeNode(self, idAttr): 8430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if idAttr is None or not self.isSameNode(idAttr.ownerElement): 8440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 8450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _get_containing_entref(self) is not None: 8460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NoModificationAllowedErr() 8470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not idAttr._is_id: 8480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi idAttr.__dict__['_is_id'] = True 8490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._magic_id_nodes += 1 8500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ownerDocument._magic_id_count += 1 8510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(self) 8520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Element, "attributes", 8540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc="NamedNodeMap of attributes on the element.") 8550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Element, "localName", 8560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc="Namespace-local name of this element.") 8570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _set_attribute_node(element, attr): 8600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _clear_id_cache(element) 8610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi element._attrs[attr.name] = attr 8620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi element._attrsNS[(attr.namespaceURI, attr.localName)] = attr 8630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This creates a circular reference, but Element.unlink() 8650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # breaks the cycle since the references to the attribute 8660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # dictionaries are tossed. 8670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attr.__dict__['ownerElement'] = element 8680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Childless: 8710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Mixin that makes childless-ness easy to implement and avoids 8720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the complexity of the Node methods that deal with children. 8730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 8740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attributes = None 8760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi childNodes = EmptyNodeList() 8770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi firstChild = None 8780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lastChild = None 8790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_firstChild(self): 8810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 8820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_lastChild(self): 8840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 8850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def appendChild(self, node): 8870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 8880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.nodeName + " nodes cannot have children") 8890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def hasChildNodes(self): 8910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 8920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def insertBefore(self, newChild, refChild): 8940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 8950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.nodeName + " nodes do not have children") 8960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeChild(self, oldChild): 8980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr( 8990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.nodeName + " nodes do not have children") 9000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def normalize(self): 9020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # For childless nodes, normalize() has nothing to do. 9030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 9040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def replaceChild(self, newChild, oldChild): 9060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 9070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.nodeName + " nodes do not have children") 9080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ProcessingInstruction(Childless, Node): 9110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.PROCESSING_INSTRUCTION_NODE 9120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, target, data): 9140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.target = self.nodeName = target 9150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data = self.nodeValue = data 9160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_data(self): 9180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.data 9190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _set_data(self, value): 9200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self.__dict__ 9210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['data'] = d['nodeValue'] = value 9220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_target(self): 9240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.target 9250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _set_target(self, value): 9260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self.__dict__ 9270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['target'] = d['nodeName'] = value 9280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __setattr__(self, name, value): 9300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if name == "data" or name == "nodeValue": 9310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.__dict__['data'] = self.__dict__['nodeValue'] = value 9320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif name == "target" or name == "nodeName": 9330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.__dict__['target'] = self.__dict__['nodeName'] = value 9340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 9350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.__dict__[name] = value 9360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def writexml(self, writer, indent="", addindent="", newl=""): 9380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("%s<?%s %s?>%s" % (indent,self.target, self.data, newl)) 9390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass CharacterData(Childless, Node): 9420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_length(self): 9430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(self.data) 9440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __len__ = _get_length 9450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_data(self): 9470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.__dict__['data'] 9480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _set_data(self, data): 9490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self.__dict__ 9500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['data'] = d['nodeValue'] = data 9510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _get_nodeValue = _get_data 9530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _set_nodeValue = _set_data 9540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __setattr__(self, name, value): 9560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if name == "data" or name == "nodeValue": 9570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.__dict__['data'] = self.__dict__['nodeValue'] = value 9580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 9590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.__dict__[name] = value 9600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __repr__(self): 9620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi data = self.data 9630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if len(data) > 10: 9640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotdotdot = "..." 9650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 9660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dotdotdot = "" 9670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return '<DOM %s node "%r%s">' % ( 9680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.__class__.__name__, data[0:10], dotdotdot) 9690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def substringData(self, offset, count): 9710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset < 0: 9720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("offset cannot be negative") 9730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset >= len(self.data): 9740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("offset cannot be beyond end of data") 9750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if count < 0: 9760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("count cannot be negative") 9770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.data[offset:offset+count] 9780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def appendData(self, arg): 9800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data = self.data + arg 9810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def insertData(self, offset, arg): 9830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset < 0: 9840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("offset cannot be negative") 9850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset >= len(self.data): 9860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("offset cannot be beyond end of data") 9870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if arg: 9880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data = "%s%s%s" % ( 9890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data[:offset], arg, self.data[offset:]) 9900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def deleteData(self, offset, count): 9920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset < 0: 9930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("offset cannot be negative") 9940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset >= len(self.data): 9950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("offset cannot be beyond end of data") 9960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if count < 0: 9970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("count cannot be negative") 9980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if count: 9990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data = self.data[:offset] + self.data[offset+count:] 10000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def replaceData(self, offset, count, arg): 10020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset < 0: 10030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("offset cannot be negative") 10040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset >= len(self.data): 10050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("offset cannot be beyond end of data") 10060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if count < 0: 10070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("count cannot be negative") 10080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if count: 10090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data = "%s%s%s" % ( 10100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data[:offset], arg, self.data[offset+count:]) 10110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(CharacterData, "length", doc="Length of the string data.") 10130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Text(CharacterData): 10160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Make sure we don't add an instance __dict__ if we don't already 10170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # have one, at least when that's possible: 10180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # XXX this does not work, CharacterData is an old-style class 10190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # __slots__ = () 10200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.TEXT_NODE 10220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeName = "#text" 10230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attributes = None 10240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def splitText(self, offset): 10260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if offset < 0 or offset > len(self.data): 10270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.IndexSizeErr("illegal offset value") 10280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newText = self.__class__() 10290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newText.data = self.data[offset:] 10300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newText.ownerDocument = self.ownerDocument 10310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi next = self.nextSibling 10320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.parentNode and self in self.parentNode.childNodes: 10330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if next is None: 10340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.parentNode.appendChild(newText) 10350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.parentNode.insertBefore(newText, next) 10370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data = self.data[:offset] 10380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return newText 10390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def writexml(self, writer, indent="", addindent="", newl=""): 10410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _write_data(writer, "%s%s%s" % (indent, self.data, newl)) 10420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # DOM Level 3 (WD 9 April 2002) 10440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_wholeText(self): 10460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L = [self.data] 10470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = self.previousSibling 10480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while n is not None: 10490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): 10500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L.insert(0, n.data) 10510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = n.previousSibling 10520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 10540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = self.nextSibling 10550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while n is not None: 10560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): 10570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi L.append(n.data) 10580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = n.nextSibling 10590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 10610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return ''.join(L) 10620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def replaceWholeText(self, content): 10640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # XXX This needs to be seriously changed if minidom ever 10650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # supports EntityReference nodes. 10660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parent = self.parentNode 10670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = self.previousSibling 10680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while n is not None: 10690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): 10700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi next = n.previousSibling 10710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parent.removeChild(n) 10720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = next 10730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 10750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = self.nextSibling 10760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not content: 10770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parent.removeChild(self) 10780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while n is not None: 10790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): 10800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi next = n.nextSibling 10810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parent.removeChild(n) 10820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = next 10830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 10850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if content: 10860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = self.__dict__ 10870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['data'] = content 10880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['nodeValue'] = content 10890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 10900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 10920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_isWhitespaceInElementContent(self): 10940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.data.strip(): 10950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 10960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elem = _get_containing_element(self) 10970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if elem is None: 10980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 10990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi info = self.ownerDocument._get_elem_info(elem) 11000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if info is None: 11010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 11020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 11030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return info.isElementContent() 11040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Text, "isWhitespaceInElementContent", 11060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc="True iff this text node contains only whitespace" 11070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi " and is in element content.") 11080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Text, "wholeText", 11090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc="The text of all logically-adjacent text nodes.") 11100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _get_containing_element(node): 11130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = node.parentNode 11140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while c is not None: 11150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c.nodeType == Node.ELEMENT_NODE: 11160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return c 11170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = c.parentNode 11180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 11190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _get_containing_entref(node): 11210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = node.parentNode 11220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while c is not None: 11230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if c.nodeType == Node.ENTITY_REFERENCE_NODE: 11240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return c 11250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = c.parentNode 11260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 11270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Comment(Childless, CharacterData): 11300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.COMMENT_NODE 11310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeName = "#comment" 11320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, data): 11340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.data = self.nodeValue = data 11350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def writexml(self, writer, indent="", addindent="", newl=""): 11370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if "--" in self.data: 11380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("'--' is not allowed in a comment node") 11390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("%s<!--%s-->%s" % (indent, self.data, newl)) 11400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass CDATASection(Text): 11430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Make sure we don't add an instance __dict__ if we don't already 11440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # have one, at least when that's possible: 11450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # XXX this does not work, Text is an old-style class 11460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # __slots__ = () 11470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.CDATA_SECTION_NODE 11490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeName = "#cdata-section" 11500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def writexml(self, writer, indent="", addindent="", newl=""): 11520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.data.find("]]>") >= 0: 11530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError("']]>' not allowed in a CDATA section") 11540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("<![CDATA[%s]]>" % self.data) 11550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ReadOnlySequentialNamedNodeMap(object): 11580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __slots__ = '_seq', 11590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, seq=()): 11610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # seq should be a list or tuple 11620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._seq = seq 11630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __len__(self): 11650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(self._seq) 11660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_length(self): 11680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return len(self._seq) 11690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getNamedItem(self, name): 11710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for n in self._seq: 11720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.nodeName == name: 11730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return n 11740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getNamedItemNS(self, namespaceURI, localName): 11760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for n in self._seq: 11770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.namespaceURI == namespaceURI and n.localName == localName: 11780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return n 11790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __getitem__(self, name_or_tuple): 11810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(name_or_tuple, tuple): 11820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = self.getNamedItemNS(*name_or_tuple) 11830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 11840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = self.getNamedItem(name_or_tuple) 11850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node is None: 11860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise KeyError, name_or_tuple 11870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return node 11880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def item(self, index): 11900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if index < 0: 11910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 11920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 11930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._seq[index] 11940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except IndexError: 11950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 11960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeNamedItem(self, name): 11980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NoModificationAllowedErr( 11990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "NamedNodeMap instance is read-only") 12000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeNamedItemNS(self, namespaceURI, localName): 12020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NoModificationAllowedErr( 12030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "NamedNodeMap instance is read-only") 12040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setNamedItem(self, node): 12060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NoModificationAllowedErr( 12070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "NamedNodeMap instance is read-only") 12080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setNamedItemNS(self, node): 12100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NoModificationAllowedErr( 12110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "NamedNodeMap instance is read-only") 12120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __getstate__(self): 12140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return [self._seq] 12150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __setstate__(self, state): 12170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._seq = state[0] 12180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(ReadOnlySequentialNamedNodeMap, "length", 12200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc="Number of entries in the NamedNodeMap.") 12210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Identified: 12240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Mix-in class that supports the publicId and systemId attributes.""" 12250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # XXX this does not work, this is an old-style class 12270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # __slots__ = 'publicId', 'systemId' 12280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _identified_mixin_init(self, publicId, systemId): 12300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.publicId = publicId 12310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.systemId = systemId 12320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_publicId(self): 12340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.publicId 12350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_systemId(self): 12370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.systemId 12380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass DocumentType(Identified, Childless, Node): 12400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.DOCUMENT_TYPE_NODE 12410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeValue = None 12420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi name = None 12430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi publicId = None 12440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi systemId = None 12450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi internalSubset = None 12460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, qualifiedName): 12480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.entities = ReadOnlySequentialNamedNodeMap() 12490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.notations = ReadOnlySequentialNamedNodeMap() 12500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if qualifiedName: 12510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix, localname = _nssplit(qualifiedName) 12520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.name = localname 12530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.nodeName = self.name 12540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_internalSubset(self): 12560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.internalSubset 12570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def cloneNode(self, deep): 12590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.ownerDocument is None: 12600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # it's ok 12610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = DocumentType(None) 12620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.name = self.name 12630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.nodeName = self.name 12640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation = xml.dom.UserDataHandler.NODE_CLONED 12650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if deep: 12660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.entities._seq = [] 12670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.notations._seq = [] 12680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for n in self.notations._seq: 12690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi notation = Notation(n.nodeName, n.publicId, n.systemId) 12700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.notations._seq.append(notation) 12710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n._call_user_data_handler(operation, n, notation) 12720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for e in self.entities._seq: 12730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity = Entity(e.nodeName, e.publicId, e.systemId, 12740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e.notationName) 12750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity.actualEncoding = e.actualEncoding 12760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity.encoding = e.encoding 12770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity.version = e.version 12780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.entities._seq.append(entity) 12790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e._call_user_data_handler(operation, n, entity) 12800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._call_user_data_handler(operation, self, clone) 12810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return clone 12820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 12830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 12840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def writexml(self, writer, indent="", addindent="", newl=""): 12860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("<!DOCTYPE ") 12870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(self.name) 12880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.publicId: 12890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("%s PUBLIC '%s'%s '%s'" 12900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi % (newl, self.publicId, newl, self.systemId)) 12910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif self.systemId: 12920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("%s SYSTEM '%s'" % (newl, self.systemId)) 12930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.internalSubset is not None: 12940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(" [") 12950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(self.internalSubset) 12960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write("]") 12970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write(">"+newl) 12980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Entity(Identified, Node): 13000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attributes = None 13010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.ENTITY_NODE 13020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeValue = None 13030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi actualEncoding = None 13050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi encoding = None 13060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi version = None 13070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, name, publicId, systemId, notation): 13090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.nodeName = name 13100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.notationName = notation 13110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes = NodeList() 13120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._identified_mixin_init(publicId, systemId) 13130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_actualEncoding(self): 13150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.actualEncoding 13160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_encoding(self): 13180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.encoding 13190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_version(self): 13210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.version 13220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def appendChild(self, newChild): 13240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 13250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "cannot append children to an entity node") 13260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def insertBefore(self, newChild, refChild): 13280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 13290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "cannot insert children below an entity node") 13300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeChild(self, oldChild): 13320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 13330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "cannot remove children from an entity node") 13340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def replaceChild(self, newChild, oldChild): 13360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 13370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "cannot replace children of an entity node") 13380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Notation(Identified, Childless, Node): 13400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.NOTATION_NODE 13410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeValue = None 13420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, name, publicId, systemId): 13440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.nodeName = name 13450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._identified_mixin_init(publicId, systemId) 13460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass DOMImplementation(DOMImplementationLS): 13490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _features = [("core", "1.0"), 13500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ("core", "2.0"), 13510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ("core", None), 13520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ("xml", "1.0"), 13530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ("xml", "2.0"), 13540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ("xml", None), 13550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ("ls-load", "3.0"), 13560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ("ls-load", None), 13570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ] 13580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def hasFeature(self, feature, version): 13600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if version == "": 13610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi version = None 13620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (feature.lower(), version) in self._features 13630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createDocument(self, namespaceURI, qualifiedName, doctype): 13650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if doctype and doctype.parentNode is not None: 13660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.WrongDocumentErr( 13670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "doctype object owned by another DOM tree") 13680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc = self._create_document() 13690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi add_root_element = not (namespaceURI is None 13710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and qualifiedName is None 13720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and doctype is None) 13730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not qualifiedName and add_root_element: 13750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The spec is unclear what to raise here; SyntaxErr 13760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # would be the other obvious candidate. Since Xerces raises 13770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # InvalidCharacterErr, and since SyntaxErr is not listed 13780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # for createDocument, that seems to be the better choice. 13790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # XXX: need to check for illegal characters here and in 13800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # createElement. 13810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # DOM Level III clears this up when talking about the return value 13830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # of this function. If namespaceURI, qName and DocType are 13840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Null the document is returned without a document element 13850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Otherwise if doctype or namespaceURI are not None 13860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Then we go back to the above problem 13870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.InvalidCharacterErr("Element with no name") 13880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if add_root_element: 13900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix, localname = _nssplit(qualifiedName) 13910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if prefix == "xml" \ 13920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and namespaceURI != "http://www.w3.org/XML/1998/namespace": 13930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NamespaceErr("illegal use of 'xml' prefix") 13940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if prefix and not namespaceURI: 13950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NamespaceErr( 13960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "illegal use of prefix without namespaces") 13970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi element = doc.createElementNS(namespaceURI, qualifiedName) 13980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if doctype: 13990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc.appendChild(doctype) 14000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc.appendChild(element) 14010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if doctype: 14030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doctype.parentNode = doctype.ownerDocument = doc 14040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc.doctype = doctype 14060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc.implementation = self 14070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return doc 14080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createDocumentType(self, qualifiedName, publicId, systemId): 14100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doctype = DocumentType(qualifiedName) 14110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doctype.publicId = publicId 14120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doctype.systemId = systemId 14130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return doctype 14140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # DOM Level 3 (WD 9 April 2002) 14160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getInterface(self, feature): 14180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.hasFeature(feature, None): 14190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self 14200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 14210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 14220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # internal 14240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _create_document(self): 14250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Document() 14260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ElementInfo(object): 14280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Object that represents content-model information for an element. 14290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi This implementation is not expected to be used in practice; DOM 14310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi builders should provide implementations which do the right thing 14320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi using information available to it. 14330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 14350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __slots__ = 'tagName', 14370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self, name): 14390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.tagName = name 14400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getAttributeType(self, aname): 14420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _no_type 14430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getAttributeTypeNS(self, namespaceURI, localName): 14450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _no_type 14460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def isElementContent(self): 14480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 14490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def isEmpty(self): 14510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns true iff this element is declared to have an EMPTY 14520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi content model.""" 14530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 14540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def isId(self, aname): 14560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns true iff the named attribute is a DTD-style ID.""" 14570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 14580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def isIdNS(self, namespaceURI, localName): 14600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Returns true iff the identified attribute is a DTD-style ID.""" 14610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return False 14620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __getstate__(self): 14640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.tagName 14650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __setstate__(self, state): 14670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.tagName = state 14680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _clear_id_cache(node): 14700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == Node.DOCUMENT_NODE: 14710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node._id_cache.clear() 14720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node._id_search_stack = None 14730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif _in_document(node): 14740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.ownerDocument._id_cache.clear() 14750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.ownerDocument._id_search_stack= None 14760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Document(Node, DocumentLS): 14780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _child_node_types = (Node.ELEMENT_NODE, Node.PROCESSING_INSTRUCTION_NODE, 14790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.COMMENT_NODE, Node.DOCUMENT_TYPE_NODE) 14800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeType = Node.DOCUMENT_NODE 14820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeName = "#document" 14830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi nodeValue = None 14840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attributes = None 14850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doctype = None 14860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parentNode = None 14870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi previousSibling = nextSibling = None 14880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi implementation = DOMImplementation() 14900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Document attributes from Level 3 (WD 9 April 2002) 14920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi actualEncoding = None 14940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi encoding = None 14950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi standalone = None 14960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi version = None 14970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi strictErrorChecking = False 14980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi errorHandler = None 14990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi documentURI = None 15000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _magic_id_count = 0 15020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __init__(self): 15040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes = NodeList() 15050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # mapping of (namespaceURI, localName) -> ElementInfo 15060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # and tagName -> ElementInfo 15070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._elem_info = {} 15080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._id_cache = {} 15090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._id_search_stack = None 15100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_elem_info(self, element): 15120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if element.namespaceURI: 15130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi key = element.namespaceURI, element.localName 15140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 15150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi key = element.tagName 15160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._elem_info.get(key) 15170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_actualEncoding(self): 15190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.actualEncoding 15200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_doctype(self): 15220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.doctype 15230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_documentURI(self): 15250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.documentURI 15260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_encoding(self): 15280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.encoding 15290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_errorHandler(self): 15310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.errorHandler 15320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_standalone(self): 15340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.standalone 15350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_strictErrorChecking(self): 15370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.strictErrorChecking 15380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_version(self): 15400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.version 15410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def appendChild(self, node): 15430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType not in self._child_node_types: 15440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 15450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "%s cannot be child of %s" % (repr(node), repr(self))) 15460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.parentNode is not None: 15470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This needs to be done before the next test since this 15480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # may *be* the document element, in which case it should 15490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # end up re-ordered to the end. 15500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.parentNode.removeChild(node) 15510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == Node.ELEMENT_NODE \ 15530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and self._get_documentElement(): 15540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.HierarchyRequestErr( 15550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "two document elements disallowed") 15560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Node.appendChild(self, node) 15570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def removeChild(self, oldChild): 15590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 15600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.childNodes.remove(oldChild) 15610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except ValueError: 15620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotFoundErr() 15630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.nextSibling = oldChild.previousSibling = None 15640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi oldChild.parentNode = None 15650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.documentElement is oldChild: 15660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.documentElement = None 15670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return oldChild 15690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _get_documentElement(self): 15710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for node in self.childNodes: 15720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == Node.ELEMENT_NODE: 15730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return node 15740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def unlink(self): 15760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if self.doctype is not None: 15770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.doctype.unlink() 15780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.doctype = None 15790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Node.unlink(self) 15800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def cloneNode(self, deep): 15820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not deep: 15830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 15840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = self.implementation.createDocument(None, None, None) 15850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.encoding = self.encoding 15860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.standalone = self.standalone 15870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.version = self.version 15880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for n in self.childNodes: 15890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi childclone = _clone_node(n, deep, clone) 15900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi assert childclone.ownerDocument.isSameNode(clone) 15910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.childNodes.append(childclone) 15920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if childclone.nodeType == Node.DOCUMENT_NODE: 15930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi assert clone.documentElement is None 15940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif childclone.nodeType == Node.DOCUMENT_TYPE_NODE: 15950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi assert clone.doctype is None 15960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.doctype = childclone 15970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi childclone.parentNode = clone 15980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._call_user_data_handler(xml.dom.UserDataHandler.NODE_CLONED, 15990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self, clone) 16000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return clone 16010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createDocumentFragment(self): 16030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = DocumentFragment() 16040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d.ownerDocument = self 16050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return d 16060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createElement(self, tagName): 16080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e = Element(tagName) 16090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e.ownerDocument = self 16100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return e 16110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createTextNode(self, data): 16130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not isinstance(data, StringTypes): 16140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError, "node contents must be a string" 16150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t = Text() 16160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t.data = data 16170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t.ownerDocument = self 16180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return t 16190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createCDATASection(self, data): 16210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not isinstance(data, StringTypes): 16220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError, "node contents must be a string" 16230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = CDATASection() 16240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c.data = data 16250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c.ownerDocument = self 16260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return c 16270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createComment(self, data): 16290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = Comment(data) 16300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c.ownerDocument = self 16310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return c 16320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createProcessingInstruction(self, target, data): 16340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p = ProcessingInstruction(target, data) 16350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi p.ownerDocument = self 16360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return p 16370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createAttribute(self, qName): 16390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = Attr(qName) 16400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a.ownerDocument = self 16410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a.value = "" 16420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a 16430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createElementNS(self, namespaceURI, qualifiedName): 16450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix, localName = _nssplit(qualifiedName) 16460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e = Element(qualifiedName, namespaceURI, prefix) 16470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e.ownerDocument = self 16480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return e 16490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def createAttributeNS(self, namespaceURI, qualifiedName): 16510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix, localName = _nssplit(qualifiedName) 16520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = Attr(qualifiedName, namespaceURI, localName, prefix) 16530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a.ownerDocument = self 16540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a.value = "" 16550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return a 16560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # A couple of implementation-specific helpers to create node types 16580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # not supported by the W3C DOM specs: 16590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _create_entity(self, name, publicId, systemId, notationName): 16610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e = Entity(name, publicId, systemId, notationName) 16620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e.ownerDocument = self 16630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return e 16640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _create_notation(self, name, publicId, systemId): 16660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n = Notation(name, publicId, systemId) 16670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n.ownerDocument = self 16680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return n 16690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getElementById(self, id): 16710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if id in self._id_cache: 16720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self._id_cache[id] 16730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not (self._elem_info or self._magic_id_count): 16740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 16750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi stack = self._id_search_stack 16770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if stack is None: 16780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # we never searched before, or the cache has been cleared 16790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi stack = [self.documentElement] 16800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._id_search_stack = stack 16810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif not stack: 16820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Previous search was completed and cache is still valid; 16830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # no matching node. 16840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 16850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = None 16870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while stack: 16880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node = stack.pop() 16890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # add child elements to stack for continued searching 16900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi stack.extend([child for child in node.childNodes 16910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if child.nodeType in _nodeTypes_with_children]) 16920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # check this node 16930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi info = self._get_elem_info(node) 16940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if info: 16950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # We have to process all ID attributes before 16960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # returning in order to get all the attributes set to 16970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # be IDs using Element.setIdAttribute*(). 16980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for attr in node.attributes.values(): 16990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.namespaceURI: 17000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if info.isIdNS(attr.namespaceURI, attr.localName): 17010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._id_cache[attr.value] = node 17020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.value == id: 17030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = node 17040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif not node._magic_id_nodes: 17050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 17060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif info.isId(attr.name): 17070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._id_cache[attr.value] = node 17080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.value == id: 17090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = node 17100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif not node._magic_id_nodes: 17110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 17120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif attr._is_id: 17130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._id_cache[attr.value] = node 17140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.value == id: 17150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = node 17160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node._magic_id_nodes == 1: 17170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 17180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node._magic_id_nodes: 17190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for attr in node.attributes.values(): 17200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr._is_id: 17210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._id_cache[attr.value] = node 17220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attr.value == id: 17230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi result = node 17240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if result is not None: 17250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi break 17260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return result 17270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getElementsByTagName(self, name): 17290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _get_elements_by_tagName_helper(self, name, NodeList()) 17300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def getElementsByTagNameNS(self, namespaceURI, localName): 17320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _get_elements_by_tagName_ns_helper( 17330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self, namespaceURI, localName, NodeList()) 17340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def isSupported(self, feature, version): 17360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return self.implementation.hasFeature(feature, version) 17370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def importNode(self, node, deep): 17390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == Node.DOCUMENT_NODE: 17400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotSupportedErr("cannot import document nodes") 17410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType == Node.DOCUMENT_TYPE_NODE: 17420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotSupportedErr("cannot import document type nodes") 17430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _clone_node(node, deep, self) 17440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def writexml(self, writer, indent="", addindent="", newl="", 17460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi encoding = None): 17470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if encoding is None: 17480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write('<?xml version="1.0" ?>'+newl) 17490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi writer.write('<?xml version="1.0" encoding="%s"?>%s' % (encoding, newl)) 17510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for node in self.childNodes: 17520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.writexml(writer, indent, addindent, newl) 17530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # DOM Level 3 (WD 9 April 2002) 17550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def renameNode(self, n, namespaceURI, name): 17570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.ownerDocument is not self: 17580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.WrongDocumentErr( 17590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "cannot rename nodes from other documents;\n" 17600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "expected %s,\nfound %s" % (self, n.ownerDocument)) 17610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.nodeType not in (Node.ELEMENT_NODE, Node.ATTRIBUTE_NODE): 17620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotSupportedErr( 17630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "renameNode() only applies to element and attribute nodes") 17640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if namespaceURI != EMPTY_NAMESPACE: 17650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ':' in name: 17660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix, localName = name.split(':', 1) 17670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ( prefix == "xmlns" 17680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and namespaceURI != xml.dom.XMLNS_NAMESPACE): 17690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NamespaceErr( 17700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "illegal use of 'xmlns' prefix") 17710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if ( name == "xmlns" 17730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and namespaceURI != xml.dom.XMLNS_NAMESPACE 17740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and n.nodeType == Node.ATTRIBUTE_NODE): 17750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NamespaceErr( 17760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "illegal use of the 'xmlns' attribute") 17770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix = None 17780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi localName = name 17790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi prefix = None 17810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi localName = None 17820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.nodeType == Node.ATTRIBUTE_NODE: 17830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi element = n.ownerElement 17840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if element is not None: 17850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is_id = n._is_id 17860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi element.removeAttributeNode(n) 17870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi element = None 17890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # avoid __setattr__ 17900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d = n.__dict__ 17910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['prefix'] = prefix 17920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['localName'] = localName 17930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['namespaceURI'] = namespaceURI 17940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['nodeName'] = name 17950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if n.nodeType == Node.ELEMENT_NODE: 17960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['tagName'] = name 17970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 17980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # attribute node 17990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi d['name'] = name 18000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if element is not None: 18010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi element.setAttributeNode(n) 18020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if is_id: 18030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi element.setIdAttributeNode(n) 18040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # It's not clear from a semantic perspective whether we should 18050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # call the user data handlers for the NODE_RENAMED event since 18060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # we're re-using the existing node. The draft spec has been 18070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # interpreted as meaning "no, don't call the handler unless a 18080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # new node is created." 18090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return n 18100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidefproperty(Document, "documentElement", 18120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi doc="Top-level element of this document.") 18130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _clone_node(node, deep, newOwnerDocument): 18160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 18170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Clone a node and give it the new owner document. 18180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Called by Node.cloneNode and Document.importNode 18190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 18200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.ownerDocument.isSameNode(newOwnerDocument): 18210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation = xml.dom.UserDataHandler.NODE_CLONED 18220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 18230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation = xml.dom.UserDataHandler.NODE_IMPORTED 18240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if node.nodeType == Node.ELEMENT_NODE: 18250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = newOwnerDocument.createElementNS(node.namespaceURI, 18260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.nodeName) 18270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for attr in node.attributes.values(): 18280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value) 18290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = clone.getAttributeNodeNS(attr.namespaceURI, attr.localName) 18300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a.specified = attr.specified 18310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if deep: 18330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for child in node.childNodes: 18340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = _clone_node(child, deep, newOwnerDocument) 18350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.appendChild(c) 18360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType == Node.DOCUMENT_FRAGMENT_NODE: 18380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = newOwnerDocument.createDocumentFragment() 18390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if deep: 18400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for child in node.childNodes: 18410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = _clone_node(child, deep, newOwnerDocument) 18420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.appendChild(c) 18430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType == Node.TEXT_NODE: 18450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = newOwnerDocument.createTextNode(node.data) 18460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType == Node.CDATA_SECTION_NODE: 18470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = newOwnerDocument.createCDATASection(node.data) 18480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType == Node.PROCESSING_INSTRUCTION_NODE: 18490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = newOwnerDocument.createProcessingInstruction(node.target, 18500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.data) 18510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType == Node.COMMENT_NODE: 18520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = newOwnerDocument.createComment(node.data) 18530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType == Node.ATTRIBUTE_NODE: 18540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = newOwnerDocument.createAttributeNS(node.namespaceURI, 18550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.nodeName) 18560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.specified = True 18570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.value = node.value 18580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif node.nodeType == Node.DOCUMENT_TYPE_NODE: 18590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi assert node.ownerDocument is not newOwnerDocument 18600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi operation = xml.dom.UserDataHandler.NODE_IMPORTED 18610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone = newOwnerDocument.implementation.createDocumentType( 18620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node.name, node.publicId, node.systemId) 18630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.ownerDocument = newOwnerDocument 18640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if deep: 18650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.entities._seq = [] 18660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.notations._seq = [] 18670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for n in node.notations._seq: 18680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi notation = Notation(n.nodeName, n.publicId, n.systemId) 18690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi notation.ownerDocument = newOwnerDocument 18700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.notations._seq.append(notation) 18710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if hasattr(n, '_call_user_data_handler'): 18720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi n._call_user_data_handler(operation, n, notation) 18730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for e in node.entities._seq: 18740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity = Entity(e.nodeName, e.publicId, e.systemId, 18750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e.notationName) 18760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity.actualEncoding = e.actualEncoding 18770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity.encoding = e.encoding 18780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity.version = e.version 18790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi entity.ownerDocument = newOwnerDocument 18800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi clone.entities._seq.append(entity) 18810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if hasattr(e, '_call_user_data_handler'): 18820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi e._call_user_data_handler(operation, n, entity) 18830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 18840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Note the cloning of Document and DocumentType nodes is 18850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # implementation specific. minidom handles those cases 18860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # directly in the cloneNode() methods. 18870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise xml.dom.NotSupportedErr("Cannot clone node %s" % repr(node)) 18880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Check for _call_user_data_handler() since this could conceivably 18900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # used with other DOM implementations (one of the FourThought 18910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # DOMs, perhaps?). 18920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if hasattr(node, '_call_user_data_handler'): 18930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi node._call_user_data_handler(operation, node, clone) 18940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return clone 18950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _nssplit(qualifiedName): 18980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fields = qualifiedName.split(':', 1) 18990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if len(fields) == 2: 19000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return fields 19010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 19020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return (None, fields[0]) 19030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _get_StringIO(): 19060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # we can't use cStringIO since it doesn't support Unicode strings 19070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from StringIO import StringIO 19080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return StringIO() 19090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _do_pulldom_parse(func, args, kwargs): 19110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi events = func(*args, **kwargs) 19120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi toktype, rootNode = events.getEvent() 19130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi events.expandNode(rootNode) 19140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi events.clear() 19150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return rootNode 19160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef parse(file, parser=None, bufsize=None): 19180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Parse a file into a DOM by filename or file object.""" 19190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if parser is None and not bufsize: 19200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from xml.dom import expatbuilder 19210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return expatbuilder.parse(file) 19220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 19230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from xml.dom import pulldom 19240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _do_pulldom_parse(pulldom.parse, (file,), 19250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi {'parser': parser, 'bufsize': bufsize}) 19260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef parseString(string, parser=None): 19280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Parse a file into a DOM from a string.""" 19290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if parser is None: 19300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from xml.dom import expatbuilder 19310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return expatbuilder.parseString(string) 19320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 19330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from xml.dom import pulldom 19340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _do_pulldom_parse(pulldom.parseString, (string,), 19350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi {'parser': parser}) 19360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef getDOMImplementation(features=None): 19380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if features: 19390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(features, StringTypes): 19400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi features = domreg._parse_feature_string(features) 19410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for f, v in features: 19420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not Document.implementation.hasFeature(f, v): 19430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return None 19440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return Document.implementation 1945