blob: 80771ad021160c740b8a4073eef4ea0efc10f1fd [file] [log] [blame]
Fred Drake1f549022000-09-24 05:21:58 +00001"""\
Fred Drake55c38192000-06-29 19:39:57 +00002minidom.py -- a lightweight DOM implementation based on SAX.
3
Paul Prescod623511b2000-07-21 22:05:49 +00004parse( "foo.xml" )
5
6parseString( "<foo><bar/></foo>" )
7
Fred Drake55c38192000-06-29 19:39:57 +00008Todo:
9=====
10 * convenience methods for getting elements and text.
11 * more testing
12 * bring some of the writer and linearizer code into conformance with this
13 interface
14 * SAX 2 namespaces
15"""
16
Fred Drake1f549022000-09-24 05:21:58 +000017import pulldom
18import string
19from StringIO import StringIO
20import types
21
Fred Drake55c38192000-06-29 19:39:57 +000022class Node:
23 ELEMENT_NODE = 1
24 ATTRIBUTE_NODE = 2
25 TEXT_NODE = 3
26 CDATA_SECTION_NODE = 4
27 ENTITY_REFERENCE_NODE = 5
28 ENTITY_NODE = 6
29 PROCESSING_INSTRUCTION_NODE = 7
30 COMMENT_NODE = 8
31 DOCUMENT_NODE = 9
32 DOCUMENT_TYPE_NODE = 10
33 DOCUMENT_FRAGMENT_NODE = 11
34 NOTATION_NODE = 12
35
Fred Drake1f549022000-09-24 05:21:58 +000036 allnodes = {}
37 _debug = 0
38 _makeParentNodes = 1
39 debug = None
Fred Drake55c38192000-06-29 19:39:57 +000040
Fred Drake1f549022000-09-24 05:21:58 +000041 def __init__(self):
42 self.childNodes = []
Paul Prescod73678da2000-07-01 04:58:47 +000043 if Node._debug:
Fred Drake1f549022000-09-24 05:21:58 +000044 index = repr(id(self)) + repr(self.__class__)
45 Node.allnodes[index] = repr(self.__dict__)
46 if Node.debug is None:
47 Node.debug = StringIO()
Paul Prescod6c4753f2000-07-04 03:39:33 +000048 #open( "debug4.out", "w" )
Fred Drake1f549022000-09-24 05:21:58 +000049 Node.debug.write("create %s\n" % index)
Fred Drake55c38192000-06-29 19:39:57 +000050
Fred Drake1f549022000-09-24 05:21:58 +000051 def __getattr__(self, key):
52 if key[0:2] == "__":
53 raise AttributeError
Fred Drake55c38192000-06-29 19:39:57 +000054 # getattr should never call getattr!
55 if self.__dict__.has_key("inGetAttr"):
56 del self.inGetAttr
57 raise AttributeError, key
58
Fred Drake1f549022000-09-24 05:21:58 +000059 prefix, attrname = key[:5], key[5:]
60 if prefix == "_get_":
61 self.inGetAttr = 1
62 if hasattr(self, attrname):
Fred Drake55c38192000-06-29 19:39:57 +000063 del self.inGetAttr
64 return (lambda self=self, attrname=attrname:
Fred Drake1f549022000-09-24 05:21:58 +000065 getattr(self, attrname))
Fred Drake55c38192000-06-29 19:39:57 +000066 else:
67 del self.inGetAttr
68 raise AttributeError, key
69 else:
Fred Drake1f549022000-09-24 05:21:58 +000070 self.inGetAttr = 1
Fred Drake55c38192000-06-29 19:39:57 +000071 try:
Fred Drake1f549022000-09-24 05:21:58 +000072 func = getattr(self, "_get_" + key)
Fred Drake55c38192000-06-29 19:39:57 +000073 except AttributeError:
74 raise AttributeError, key
75 del self.inGetAttr
76 return func()
77
Fred Drake1f549022000-09-24 05:21:58 +000078 def __nonzero__(self):
79 return 1
Fred Drake55c38192000-06-29 19:39:57 +000080
Fred Drake1f549022000-09-24 05:21:58 +000081 def toxml(self):
82 writer = StringIO()
83 self.writexml(writer)
Fred Drake55c38192000-06-29 19:39:57 +000084 return writer.getvalue()
85
Fred Drake1f549022000-09-24 05:21:58 +000086 def hasChildNodes(self):
87 if self.childNodes:
88 return 1
89 else:
90 return 0
Fred Drake55c38192000-06-29 19:39:57 +000091
Fred Drake1f549022000-09-24 05:21:58 +000092 def _get_firstChild(self):
Paul Prescod73678da2000-07-01 04:58:47 +000093 return self.childNodes[0]
94
Fred Drake1f549022000-09-24 05:21:58 +000095 def _get_lastChild(self):
Paul Prescod73678da2000-07-01 04:58:47 +000096 return self.childNodes[-1]
97
Fred Drake1f549022000-09-24 05:21:58 +000098 def insertBefore(self, newChild, refChild):
99 index = self.childNodes.index(refChild)
100 self.childNodes.insert(index, newChild)
Paul Prescod73678da2000-07-01 04:58:47 +0000101 if self._makeParentNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000102 newChild.parentNode = self
Fred Drake55c38192000-06-29 19:39:57 +0000103
Fred Drake1f549022000-09-24 05:21:58 +0000104 def appendChild(self, node):
105 self.childNodes.append(node)
Paul Prescod73678da2000-07-01 04:58:47 +0000106 return node
107
Fred Drake1f549022000-09-24 05:21:58 +0000108 def replaceChild(self, newChild, oldChild):
109 index = self.childNodes.index(oldChild)
110 self.childNodes[index] = oldChild
Paul Prescod73678da2000-07-01 04:58:47 +0000111
Fred Drake1f549022000-09-24 05:21:58 +0000112 def removeChild(self, oldChild):
113 index = self.childNodes.index(oldChild)
Paul Prescod73678da2000-07-01 04:58:47 +0000114 del self.childNodes[index]
115
Fred Drake1f549022000-09-24 05:21:58 +0000116 def cloneNode(self, deep):
Paul Prescod73678da2000-07-01 04:58:47 +0000117 import new
Fred Drake1f549022000-09-24 05:21:58 +0000118 clone = new.instance(self.__class__, self.__dict__)
119 clone.attributes = self.attributes.copy()
Paul Prescod73678da2000-07-01 04:58:47 +0000120 if not deep:
Fred Drake1f549022000-09-24 05:21:58 +0000121 clone.childNodes = []
Paul Prescod73678da2000-07-01 04:58:47 +0000122 else:
Fred Drake1f549022000-09-24 05:21:58 +0000123 clone.childNodes = map(lambda x: x.cloneNode, self.childNodes)
Paul Prescod73678da2000-07-01 04:58:47 +0000124 return clone
Fred Drake55c38192000-06-29 19:39:57 +0000125
Fred Drake1f549022000-09-24 05:21:58 +0000126 def unlink(self):
127 self.parentNode = None
Fred Drake55c38192000-06-29 19:39:57 +0000128 while self.childNodes:
129 self.childNodes[-1].unlink()
130 del self.childNodes[-1] # probably not most efficient!
Fred Drake1f549022000-09-24 05:21:58 +0000131 self.childNodes = None
Fred Drake55c38192000-06-29 19:39:57 +0000132 if self.attributes:
Paul Prescod73678da2000-07-01 04:58:47 +0000133 for attr in self._attrs.values():
Fred Drake1f549022000-09-24 05:21:58 +0000134 self.removeAttributeNode(attr)
135 assert not len(self._attrs)
136 assert not len(self._attrsNS)
Paul Prescod73678da2000-07-01 04:58:47 +0000137 if Node._debug:
Fred Drake1f549022000-09-24 05:21:58 +0000138 index = repr(id(self)) + repr(self.__class__)
139 self.debug.write("Deleting: %s\n" % index)
Paul Prescod73678da2000-07-01 04:58:47 +0000140 del Node.allnodes[index]
Fred Drake55c38192000-06-29 19:39:57 +0000141
Fred Drake1f549022000-09-24 05:21:58 +0000142def _write_data(writer, data):
Fred Drake55c38192000-06-29 19:39:57 +0000143 "Writes datachars to writer."
Fred Drake1f549022000-09-24 05:21:58 +0000144 data = string.replace(data, "&", "&amp;")
145 data = string.replace(data, "<", "&lt;")
146 data = string.replace(data, "\"", "&quot;")
147 data = string.replace(data, ">", "&gt;")
Fred Drake55c38192000-06-29 19:39:57 +0000148 writer.write(data)
149
Fred Drake1f549022000-09-24 05:21:58 +0000150def _getElementsByTagNameHelper(parent, name, rc):
Fred Drake55c38192000-06-29 19:39:57 +0000151 for node in parent.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000152 if node.nodeType == Node.ELEMENT_NODE and \
153 (name == "*" or node.tagName == name):
154 rc.append(node)
155 _getElementsByTagNameHelper(node, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000156 return rc
157
Fred Drake1f549022000-09-24 05:21:58 +0000158def _getElementsByTagNameNSHelper(parent, nsURI, localName, rc):
Fred Drake55c38192000-06-29 19:39:57 +0000159 for node in parent.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000160 if node.nodeType == Node.ELEMENT_NODE:
161 if ((localName == "*" or node.tagName == localName) and
162 (nsURI == "*" or node.namespaceURI == nsURI)):
163 rc.append(node)
164 _getElementsByTagNameNSHelper(node, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000165
166class Attr(Node):
Fred Drake1f549022000-09-24 05:21:58 +0000167 nodeType = Node.ATTRIBUTE_NODE
168
169 def __init__(self, qName, namespaceURI="", localName=None, prefix=None):
Fred Drake55c38192000-06-29 19:39:57 +0000170 # skip setattr for performance
Fred Drake1f549022000-09-24 05:21:58 +0000171 self.__dict__["localName"] = localName or qName
Paul Prescod73678da2000-07-01 04:58:47 +0000172 self.__dict__["nodeName"] = self.__dict__["name"] = qName
Fred Drake1f549022000-09-24 05:21:58 +0000173 self.__dict__["namespaceURI"] = namespaceURI
174 self.__dict__["prefix"] = prefix
175 self.attributes = None
176 Node.__init__(self)
Paul Prescod73678da2000-07-01 04:58:47 +0000177 # nodeValue and value are set elsewhere
Fred Drake55c38192000-06-29 19:39:57 +0000178
Fred Drake1f549022000-09-24 05:21:58 +0000179 def __setattr__(self, name, value):
180 if name in ("value", "nodeValue"):
181 self.__dict__["value"] = self.__dict__["nodeValue"] = value
Fred Drake55c38192000-06-29 19:39:57 +0000182 else:
Fred Drake1f549022000-09-24 05:21:58 +0000183 self.__dict__[name] = value
Fred Drake55c38192000-06-29 19:39:57 +0000184
185class AttributeList:
Paul Prescod73678da2000-07-01 04:58:47 +0000186 """the attribute list is a transient interface to the underlying
Fred Drake1f549022000-09-24 05:21:58 +0000187 dictionaries. mutations here will change the underlying element's
188 dictionary"""
189 def __init__(self, attrs, attrsNS):
190 self._attrs = attrs
191 self._attrsNS = attrsNS
192 self.length = len(self._attrs.keys())
Fred Drake55c38192000-06-29 19:39:57 +0000193
Fred Drake1f549022000-09-24 05:21:58 +0000194 def item(self, index):
Fred Drake55c38192000-06-29 19:39:57 +0000195 try:
196 return self[self.keys()[index]]
197 except IndexError:
198 return None
Fred Drake55c38192000-06-29 19:39:57 +0000199
Fred Drake1f549022000-09-24 05:21:58 +0000200 def items(self):
201 return map(lambda node: (node.tagName, node.value),
202 self._attrs.values())
203
204 def itemsNS(self):
205 return map(lambda node: ((node.URI, node.localName), node.value),
206 self._attrs.values())
Fred Drake55c38192000-06-29 19:39:57 +0000207
Fred Drake1f549022000-09-24 05:21:58 +0000208 def keys(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000209 return self._attrs.keys()
Fred Drake55c38192000-06-29 19:39:57 +0000210
Fred Drake1f549022000-09-24 05:21:58 +0000211 def keysNS(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000212 return self._attrsNS.keys()
Fred Drake55c38192000-06-29 19:39:57 +0000213
Fred Drake1f549022000-09-24 05:21:58 +0000214 def values(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000215 return self._attrs.values()
Fred Drake55c38192000-06-29 19:39:57 +0000216
Fred Drake1f549022000-09-24 05:21:58 +0000217 def __len__(self):
Fred Drake55c38192000-06-29 19:39:57 +0000218 return self.length
219
Fred Drake1f549022000-09-24 05:21:58 +0000220 def __cmp__(self, other):
221 if self._attrs is getattr(other, "_attrs", None):
Fred Drake55c38192000-06-29 19:39:57 +0000222 return 0
223 else:
Fred Drake1f549022000-09-24 05:21:58 +0000224 return cmp(id(self), id(other))
Fred Drake55c38192000-06-29 19:39:57 +0000225
226 #FIXME: is it appropriate to return .value?
Fred Drake1f549022000-09-24 05:21:58 +0000227 def __getitem__(self, attname_or_tuple):
228 if type(attname_or_tuple) is types.TupleType:
Paul Prescod73678da2000-07-01 04:58:47 +0000229 return self._attrsNS[attname_or_tuple]
Fred Drake55c38192000-06-29 19:39:57 +0000230 else:
Paul Prescod73678da2000-07-01 04:58:47 +0000231 return self._attrs[attname_or_tuple]
Fred Drake55c38192000-06-29 19:39:57 +0000232
Paul Prescod1e688272000-07-01 19:21:47 +0000233 # same as set
Fred Drake1f549022000-09-24 05:21:58 +0000234 def __setitem__(self, attname, value):
235 if type(value) is types.StringType:
236 node = Attr(attname)
Paul Prescod1e688272000-07-01 19:21:47 +0000237 node.value=value
238 else:
Fred Drake1f549022000-09-24 05:21:58 +0000239 assert isinstance(value, Attr) or type(value) is types.StringType
240 node = value
241 old = self._attrs.get(attname, None)
Paul Prescod1e688272000-07-01 19:21:47 +0000242 if old:
243 old.unlink()
Fred Drake1f549022000-09-24 05:21:58 +0000244 self._attrs[node.name] = node
245 self._attrsNS[(node.namespaceURI, node.localName)] = node
Paul Prescod73678da2000-07-01 04:58:47 +0000246
Fred Drake1f549022000-09-24 05:21:58 +0000247 def __delitem__(self, attname_or_tuple):
248 node = self[attname_or_tuple]
Paul Prescod73678da2000-07-01 04:58:47 +0000249 node.unlink()
250 del self._attrs[node.name]
251 del self._attrsNS[(node.namespaceURI, node.localName)]
Fred Drake1f549022000-09-24 05:21:58 +0000252
Fred Drake55c38192000-06-29 19:39:57 +0000253class Element( Node ):
Fred Drake1f549022000-09-24 05:21:58 +0000254 nodeType = Node.ELEMENT_NODE
255
256 def __init__(self, tagName, namespaceURI="", prefix="",
257 localName=None):
258 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000259 self.tagName = self.nodeName = tagName
Fred Drake1f549022000-09-24 05:21:58 +0000260 self.localName = localName or tagName
261 self.prefix = prefix
262 self.namespaceURI = namespaceURI
263 self.nodeValue = None
Fred Drake55c38192000-06-29 19:39:57 +0000264
Paul Prescod73678da2000-07-01 04:58:47 +0000265 self._attrs={} # attributes are double-indexed:
266 self._attrsNS={}# tagName -> Attribute
Fred Drake55c38192000-06-29 19:39:57 +0000267 # URI,localName -> Attribute
268 # in the future: consider lazy generation of attribute objects
269 # this is too tricky for now because of headaches
270 # with namespaces.
271
Fred Drake1f549022000-09-24 05:21:58 +0000272 def getAttribute(self, attname):
Paul Prescod73678da2000-07-01 04:58:47 +0000273 return self._attrs[attname].value
Fred Drake55c38192000-06-29 19:39:57 +0000274
Fred Drake1f549022000-09-24 05:21:58 +0000275 def getAttributeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000276 return self._attrsNS[(namespaceURI, localName)].value
Fred Drake1f549022000-09-24 05:21:58 +0000277
278 def setAttribute(self, attname, value):
279 attr = Attr(attname)
Fred Drake55c38192000-06-29 19:39:57 +0000280 # for performance
Fred Drake1f549022000-09-24 05:21:58 +0000281 attr.__dict__["value"] = attr.__dict__["nodeValue"] = value
282 self.setAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000283
Fred Drake1f549022000-09-24 05:21:58 +0000284 def setAttributeNS(self, namespaceURI, qualifiedName, value):
285 prefix, localname = _nssplit(qualifiedName)
Fred Drake55c38192000-06-29 19:39:57 +0000286 # for performance
Fred Drake1f549022000-09-24 05:21:58 +0000287 attr = Attr(qualifiedName, namespaceURI, localname, prefix)
288 attr.__dict__["value"] = attr.__dict__["nodeValue"] = value
289 self.setAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000290
Fred Drake1f549022000-09-24 05:21:58 +0000291 def getAttributeNode(self, attrname):
292 return self._attrs.get(attrname)
Paul Prescod73678da2000-07-01 04:58:47 +0000293
Fred Drake1f549022000-09-24 05:21:58 +0000294 def getAttributeNodeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000295 return self._attrsNS[(namespaceURI, localName)]
296
Fred Drake1f549022000-09-24 05:21:58 +0000297 def setAttributeNode(self, attr):
298 old = self._attrs.get(attr.name, None)
Paul Prescod73678da2000-07-01 04:58:47 +0000299 if old:
300 old.unlink()
Fred Drake1f549022000-09-24 05:21:58 +0000301 self._attrs[attr.name] = attr
302 self._attrsNS[(attr.namespaceURI, attr.localName)] = attr
Fred Drake55c38192000-06-29 19:39:57 +0000303
Fred Drake1f549022000-09-24 05:21:58 +0000304 def removeAttribute(self, name):
Paul Prescod73678da2000-07-01 04:58:47 +0000305 attr = self._attrs[name]
Fred Drake1f549022000-09-24 05:21:58 +0000306 self.removeAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000307
Fred Drake1f549022000-09-24 05:21:58 +0000308 def removeAttributeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000309 attr = self._attrsNS[(namespaceURI, localName)]
Fred Drake1f549022000-09-24 05:21:58 +0000310 self.removeAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000311
Fred Drake1f549022000-09-24 05:21:58 +0000312 def removeAttributeNode(self, node):
Paul Prescod73678da2000-07-01 04:58:47 +0000313 node.unlink()
314 del self._attrs[node.name]
315 del self._attrsNS[(node.namespaceURI, node.localName)]
Fred Drake55c38192000-06-29 19:39:57 +0000316
Fred Drake1f549022000-09-24 05:21:58 +0000317 def getElementsByTagName(self, name):
318 return _getElementsByTagNameHelper(self, name, [])
Fred Drake55c38192000-06-29 19:39:57 +0000319
Fred Drake1f549022000-09-24 05:21:58 +0000320 def getElementsByTagNameNS(self, namespaceURI, localName):
321 _getElementsByTagNameNSHelper(self, namespaceURI, localName, [])
Fred Drake55c38192000-06-29 19:39:57 +0000322
Fred Drake1f549022000-09-24 05:21:58 +0000323 def __repr__(self):
324 return "<DOM Element: %s at %s>" % (self.tagName, id(self))
Fred Drake55c38192000-06-29 19:39:57 +0000325
326 def writexml(self, writer):
Fred Drake1f549022000-09-24 05:21:58 +0000327 writer.write("<" + self.tagName)
Fred Drake55c38192000-06-29 19:39:57 +0000328
Fred Drake1f549022000-09-24 05:21:58 +0000329 a_names = self._get_attributes().keys()
Fred Drake55c38192000-06-29 19:39:57 +0000330 a_names.sort()
331
332 for a_name in a_names:
Fred Drake1f549022000-09-24 05:21:58 +0000333 writer.write(" %s=\"" % a_name)
Fred Drake55c38192000-06-29 19:39:57 +0000334 _write_data(writer, self._get_attributes()[a_name])
335 writer.write("\"")
336 if self.childNodes:
337 writer.write(">")
338 for node in self.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000339 node.writexml(writer)
340 writer.write("</%s>" % self.tagName)
Fred Drake55c38192000-06-29 19:39:57 +0000341 else:
342 writer.write("/>")
343
Fred Drake1f549022000-09-24 05:21:58 +0000344 def _get_attributes(self):
345 return AttributeList(self._attrs, self._attrsNS)
Fred Drake55c38192000-06-29 19:39:57 +0000346
Fred Drake1f549022000-09-24 05:21:58 +0000347class Comment(Node):
348 nodeType = Node.COMMENT_NODE
Fred Drake55c38192000-06-29 19:39:57 +0000349
Fred Drake1f549022000-09-24 05:21:58 +0000350 def __init__(self, data):
351 Node.__init__(self)
352 self.data = self.nodeValue = data
353 self.nodeName = "#comment"
354 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000355
Fred Drake1f549022000-09-24 05:21:58 +0000356 def writexml(self, writer):
357 writer.write("<!--%s-->" % self.data)
358
359class ProcessingInstruction(Node):
360 nodeType = Node.PROCESSING_INSTRUCTION_NODE
361
362 def __init__(self, target, data):
363 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000364 self.target = self.nodeName = target
365 self.data = self.nodeValue = data
Fred Drake1f549022000-09-24 05:21:58 +0000366 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000367
Fred Drake1f549022000-09-24 05:21:58 +0000368 def writexml(self, writer):
369 writer.write("<?%s %s?>" % (self.target, self.data))
Fred Drake55c38192000-06-29 19:39:57 +0000370
Fred Drake1f549022000-09-24 05:21:58 +0000371class Text(Node):
372 nodeType = Node.TEXT_NODE
373 nodeName = "#text"
374
375 def __init__(self, data):
376 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000377 self.data = self.nodeValue = data
Fred Drake1f549022000-09-24 05:21:58 +0000378 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000379
380 def __repr__(self):
Fred Drake1f549022000-09-24 05:21:58 +0000381 if len(self.data) > 10:
382 dotdotdot = "..."
Fred Drake55c38192000-06-29 19:39:57 +0000383 else:
Fred Drake1f549022000-09-24 05:21:58 +0000384 dotdotdot = ""
385 return "<DOM Text node \"%s%s\">" % (self.data[0:10], dotdotdot)
Fred Drake55c38192000-06-29 19:39:57 +0000386
Fred Drake1f549022000-09-24 05:21:58 +0000387 def writexml(self, writer):
388 _write_data(writer, self.data)
Fred Drake55c38192000-06-29 19:39:57 +0000389
Fred Drake1f549022000-09-24 05:21:58 +0000390def _nssplit(qualifiedName):
391 fields = qualifiedName.split(':', 1)
Paul Prescod73678da2000-07-01 04:58:47 +0000392 if len(fields) == 2:
393 return fields
394 elif len(fields) == 1:
Fred Drake1f549022000-09-24 05:21:58 +0000395 return ('', fields[0])
Paul Prescod73678da2000-07-01 04:58:47 +0000396
Fred Drake1f549022000-09-24 05:21:58 +0000397class Document(Node):
398 nodeType = Node.DOCUMENT_NODE
399 documentElement = None
Fred Drake55c38192000-06-29 19:39:57 +0000400
Fred Drake1f549022000-09-24 05:21:58 +0000401 def __init__(self):
402 Node.__init__(self)
403 self.attributes = None
404 self.nodeName = "#document"
405 self.nodeValue = None
406
407 def appendChild(self, node):
408 if node.nodeType == Node.ELEMENT_NODE:
Paul Prescodce88db02000-09-15 17:09:19 +0000409 if self.documentElement:
410 raise TypeError, "Two document elements disallowed"
411 else:
Fred Drake1f549022000-09-24 05:21:58 +0000412 self.documentElement = node
413 Node.appendChild(self, node)
Paul Prescod73678da2000-07-01 04:58:47 +0000414 return node
415
Fred Drake1f549022000-09-24 05:21:58 +0000416 createElement = Element
Fred Drake55c38192000-06-29 19:39:57 +0000417
Fred Drake1f549022000-09-24 05:21:58 +0000418 createTextNode = Text
Fred Drake55c38192000-06-29 19:39:57 +0000419
Fred Drake1f549022000-09-24 05:21:58 +0000420 createComment = Comment
Fred Drake55c38192000-06-29 19:39:57 +0000421
Fred Drake1f549022000-09-24 05:21:58 +0000422 createProcessingInstruction = ProcessingInstruction
Fred Drake55c38192000-06-29 19:39:57 +0000423
Fred Drake1f549022000-09-24 05:21:58 +0000424 createAttribute = Attr
Fred Drake55c38192000-06-29 19:39:57 +0000425
426 def createElementNS(self, namespaceURI, qualifiedName):
Fred Drake1f549022000-09-24 05:21:58 +0000427 prefix,localName = _nssplit(qualifiedName)
Paul Prescod73678da2000-07-01 04:58:47 +0000428 return Element(qualifiedName, namespaceURI, prefix, localName)
Fred Drake55c38192000-06-29 19:39:57 +0000429
430 def createAttributeNS(self, namespaceURI, qualifiedName):
Fred Drake1f549022000-09-24 05:21:58 +0000431 prefix,localName = _nssplit(qualifiedName)
Paul Prescod73678da2000-07-01 04:58:47 +0000432 return Attr(namespaceURI, qualifiedName, localName, prefix)
Fred Drake55c38192000-06-29 19:39:57 +0000433
Fred Drake1f549022000-09-24 05:21:58 +0000434 def getElementsByTagNameNS(self, namespaceURI, localName):
435 _getElementsByTagNameNSHelper(self, namespaceURI, localName)
Fred Drake55c38192000-06-29 19:39:57 +0000436
Fred Drake1f549022000-09-24 05:21:58 +0000437 def unlink(self):
438 self.documentElement = None
439 Node.unlink(self)
Fred Drake55c38192000-06-29 19:39:57 +0000440
Fred Drake1f549022000-09-24 05:21:58 +0000441 def getElementsByTagName(self, name):
442 rc = []
443 _getElementsByTagNameHelper(self, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000444 return rc
445
Fred Drake1f549022000-09-24 05:21:58 +0000446 def writexml(self, writer):
Fred Drake55c38192000-06-29 19:39:57 +0000447 for node in self.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000448 node.writexml(writer)
Fred Drake55c38192000-06-29 19:39:57 +0000449
Fred Drake1f549022000-09-24 05:21:58 +0000450def _doparse(func, args, kwargs):
451 events = apply(func, args, kwargs)
452 toktype, rootNode = events.getEvent()
453 events.expandNode(rootNode)
Fred Drake55c38192000-06-29 19:39:57 +0000454 return rootNode
455
Fred Drake1f549022000-09-24 05:21:58 +0000456def parse(*args, **kwargs):
Paul Prescod623511b2000-07-21 22:05:49 +0000457 "Parse a file into a DOM by filename or file object"
Fred Drake1f549022000-09-24 05:21:58 +0000458 return _doparse(pulldom.parse, args, kwargs)
Fred Drake55c38192000-06-29 19:39:57 +0000459
Fred Drake1f549022000-09-24 05:21:58 +0000460def parseString(*args, **kwargs):
Paul Prescod623511b2000-07-21 22:05:49 +0000461 "Parse a file into a DOM from a string"
Fred Drake1f549022000-09-24 05:21:58 +0000462 return _doparse(pulldom.parseString, args, kwargs)
Paul Prescod623511b2000-07-21 22:05:49 +0000463