blob: 3ed72366748a99336f9d692451b88eab24adba31 [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
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +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)
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000290 # FIXME: return original node if something changed.
Fred Drake55c38192000-06-29 19:39:57 +0000291
Fred Drake1f549022000-09-24 05:21:58 +0000292 def getAttributeNode(self, attrname):
293 return self._attrs.get(attrname)
Paul Prescod73678da2000-07-01 04:58:47 +0000294
Fred Drake1f549022000-09-24 05:21:58 +0000295 def getAttributeNodeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000296 return self._attrsNS[(namespaceURI, localName)]
297
Fred Drake1f549022000-09-24 05:21:58 +0000298 def setAttributeNode(self, attr):
299 old = self._attrs.get(attr.name, None)
Paul Prescod73678da2000-07-01 04:58:47 +0000300 if old:
301 old.unlink()
Fred Drake1f549022000-09-24 05:21:58 +0000302 self._attrs[attr.name] = attr
303 self._attrsNS[(attr.namespaceURI, attr.localName)] = attr
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000304 # FIXME: return old value if something changed
Fred Drake55c38192000-06-29 19:39:57 +0000305
Fred Drake1f549022000-09-24 05:21:58 +0000306 def removeAttribute(self, name):
Paul Prescod73678da2000-07-01 04:58:47 +0000307 attr = self._attrs[name]
Fred Drake1f549022000-09-24 05:21:58 +0000308 self.removeAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000309
Fred Drake1f549022000-09-24 05:21:58 +0000310 def removeAttributeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000311 attr = self._attrsNS[(namespaceURI, localName)]
Fred Drake1f549022000-09-24 05:21:58 +0000312 self.removeAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000313
Fred Drake1f549022000-09-24 05:21:58 +0000314 def removeAttributeNode(self, node):
Paul Prescod73678da2000-07-01 04:58:47 +0000315 node.unlink()
316 del self._attrs[node.name]
317 del self._attrsNS[(node.namespaceURI, node.localName)]
Fred Drake55c38192000-06-29 19:39:57 +0000318
Fred Drake1f549022000-09-24 05:21:58 +0000319 def getElementsByTagName(self, name):
320 return _getElementsByTagNameHelper(self, name, [])
Fred Drake55c38192000-06-29 19:39:57 +0000321
Fred Drake1f549022000-09-24 05:21:58 +0000322 def getElementsByTagNameNS(self, namespaceURI, localName):
323 _getElementsByTagNameNSHelper(self, namespaceURI, localName, [])
Fred Drake55c38192000-06-29 19:39:57 +0000324
Fred Drake1f549022000-09-24 05:21:58 +0000325 def __repr__(self):
326 return "<DOM Element: %s at %s>" % (self.tagName, id(self))
Fred Drake55c38192000-06-29 19:39:57 +0000327
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000328 # undocumented
Fred Drake55c38192000-06-29 19:39:57 +0000329 def writexml(self, writer):
Fred Drake1f549022000-09-24 05:21:58 +0000330 writer.write("<" + self.tagName)
Fred Drake55c38192000-06-29 19:39:57 +0000331
Fred Drake1f549022000-09-24 05:21:58 +0000332 a_names = self._get_attributes().keys()
Fred Drake55c38192000-06-29 19:39:57 +0000333 a_names.sort()
334
335 for a_name in a_names:
Fred Drake1f549022000-09-24 05:21:58 +0000336 writer.write(" %s=\"" % a_name)
Martin v. Löwis2c8a89c2000-10-06 22:36:03 +0000337 _write_data(writer, self._get_attributes()[a_name].value)
Fred Drake55c38192000-06-29 19:39:57 +0000338 writer.write("\"")
339 if self.childNodes:
340 writer.write(">")
341 for node in self.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000342 node.writexml(writer)
343 writer.write("</%s>" % self.tagName)
Fred Drake55c38192000-06-29 19:39:57 +0000344 else:
345 writer.write("/>")
346
Fred Drake1f549022000-09-24 05:21:58 +0000347 def _get_attributes(self):
348 return AttributeList(self._attrs, self._attrsNS)
Fred Drake55c38192000-06-29 19:39:57 +0000349
Fred Drake1f549022000-09-24 05:21:58 +0000350class Comment(Node):
351 nodeType = Node.COMMENT_NODE
Fred Drake55c38192000-06-29 19:39:57 +0000352
Fred Drake1f549022000-09-24 05:21:58 +0000353 def __init__(self, data):
354 Node.__init__(self)
355 self.data = self.nodeValue = data
356 self.nodeName = "#comment"
357 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000358
Fred Drake1f549022000-09-24 05:21:58 +0000359 def writexml(self, writer):
360 writer.write("<!--%s-->" % self.data)
361
362class ProcessingInstruction(Node):
363 nodeType = Node.PROCESSING_INSTRUCTION_NODE
364
365 def __init__(self, target, data):
366 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000367 self.target = self.nodeName = target
368 self.data = self.nodeValue = data
Fred Drake1f549022000-09-24 05:21:58 +0000369 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000370
Fred Drake1f549022000-09-24 05:21:58 +0000371 def writexml(self, writer):
372 writer.write("<?%s %s?>" % (self.target, self.data))
Fred Drake55c38192000-06-29 19:39:57 +0000373
Fred Drake1f549022000-09-24 05:21:58 +0000374class Text(Node):
375 nodeType = Node.TEXT_NODE
376 nodeName = "#text"
377
378 def __init__(self, data):
379 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000380 self.data = self.nodeValue = data
Fred Drake1f549022000-09-24 05:21:58 +0000381 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000382
383 def __repr__(self):
Fred Drake1f549022000-09-24 05:21:58 +0000384 if len(self.data) > 10:
385 dotdotdot = "..."
Fred Drake55c38192000-06-29 19:39:57 +0000386 else:
Fred Drake1f549022000-09-24 05:21:58 +0000387 dotdotdot = ""
388 return "<DOM Text node \"%s%s\">" % (self.data[0:10], dotdotdot)
Fred Drake55c38192000-06-29 19:39:57 +0000389
Fred Drake1f549022000-09-24 05:21:58 +0000390 def writexml(self, writer):
391 _write_data(writer, self.data)
Fred Drake55c38192000-06-29 19:39:57 +0000392
Fred Drake1f549022000-09-24 05:21:58 +0000393def _nssplit(qualifiedName):
Martin v. Löwis830b37b2000-10-07 19:03:20 +0000394 import string
395 fields = string.split(qualifiedName,':', 1)
Paul Prescod73678da2000-07-01 04:58:47 +0000396 if len(fields) == 2:
397 return fields
398 elif len(fields) == 1:
Fred Drake1f549022000-09-24 05:21:58 +0000399 return ('', fields[0])
Paul Prescod73678da2000-07-01 04:58:47 +0000400
Fred Drake1f549022000-09-24 05:21:58 +0000401class Document(Node):
402 nodeType = Node.DOCUMENT_NODE
403 documentElement = None
Fred Drake55c38192000-06-29 19:39:57 +0000404
Fred Drake1f549022000-09-24 05:21:58 +0000405 def __init__(self):
406 Node.__init__(self)
407 self.attributes = None
408 self.nodeName = "#document"
409 self.nodeValue = None
410
411 def appendChild(self, node):
412 if node.nodeType == Node.ELEMENT_NODE:
Paul Prescodce88db02000-09-15 17:09:19 +0000413 if self.documentElement:
414 raise TypeError, "Two document elements disallowed"
415 else:
Fred Drake1f549022000-09-24 05:21:58 +0000416 self.documentElement = node
417 Node.appendChild(self, node)
Paul Prescod73678da2000-07-01 04:58:47 +0000418 return node
419
Fred Drake1f549022000-09-24 05:21:58 +0000420 createElement = Element
Fred Drake55c38192000-06-29 19:39:57 +0000421
Fred Drake1f549022000-09-24 05:21:58 +0000422 createTextNode = Text
Fred Drake55c38192000-06-29 19:39:57 +0000423
Fred Drake1f549022000-09-24 05:21:58 +0000424 createComment = Comment
Fred Drake55c38192000-06-29 19:39:57 +0000425
Fred Drake1f549022000-09-24 05:21:58 +0000426 createProcessingInstruction = ProcessingInstruction
Fred Drake55c38192000-06-29 19:39:57 +0000427
Fred Drake1f549022000-09-24 05:21:58 +0000428 createAttribute = Attr
Fred Drake55c38192000-06-29 19:39:57 +0000429
430 def createElementNS(self, namespaceURI, qualifiedName):
Fred Drake1f549022000-09-24 05:21:58 +0000431 prefix,localName = _nssplit(qualifiedName)
Paul Prescod73678da2000-07-01 04:58:47 +0000432 return Element(qualifiedName, namespaceURI, prefix, localName)
Fred Drake55c38192000-06-29 19:39:57 +0000433
434 def createAttributeNS(self, namespaceURI, qualifiedName):
Fred Drake1f549022000-09-24 05:21:58 +0000435 prefix,localName = _nssplit(qualifiedName)
Martin v. Löwis2c8a89c2000-10-06 22:36:03 +0000436 return Attr(qualifiedName, namespaceURI, localName, prefix)
Fred Drake55c38192000-06-29 19:39:57 +0000437
Fred Drake1f549022000-09-24 05:21:58 +0000438 def getElementsByTagNameNS(self, namespaceURI, localName):
439 _getElementsByTagNameNSHelper(self, namespaceURI, localName)
Fred Drake55c38192000-06-29 19:39:57 +0000440
Fred Drake1f549022000-09-24 05:21:58 +0000441 def unlink(self):
442 self.documentElement = None
443 Node.unlink(self)
Fred Drake55c38192000-06-29 19:39:57 +0000444
Fred Drake1f549022000-09-24 05:21:58 +0000445 def getElementsByTagName(self, name):
446 rc = []
447 _getElementsByTagNameHelper(self, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000448 return rc
449
Fred Drake1f549022000-09-24 05:21:58 +0000450 def writexml(self, writer):
Fred Drake55c38192000-06-29 19:39:57 +0000451 for node in self.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000452 node.writexml(writer)
Fred Drake55c38192000-06-29 19:39:57 +0000453
Fred Drake1f549022000-09-24 05:21:58 +0000454def _doparse(func, args, kwargs):
455 events = apply(func, args, kwargs)
456 toktype, rootNode = events.getEvent()
457 events.expandNode(rootNode)
Fred Drake55c38192000-06-29 19:39:57 +0000458 return rootNode
459
Fred Drake1f549022000-09-24 05:21:58 +0000460def parse(*args, **kwargs):
Paul Prescod623511b2000-07-21 22:05:49 +0000461 "Parse a file into a DOM by filename or file object"
Fred Drake1f549022000-09-24 05:21:58 +0000462 return _doparse(pulldom.parse, args, kwargs)
Fred Drake55c38192000-06-29 19:39:57 +0000463
Fred Drake1f549022000-09-24 05:21:58 +0000464def parseString(*args, **kwargs):
Paul Prescod623511b2000-07-21 22:05:49 +0000465 "Parse a file into a DOM from a string"
Fred Drake1f549022000-09-24 05:21:58 +0000466 return _doparse(pulldom.parseString, args, kwargs)
Paul Prescod623511b2000-07-21 22:05:49 +0000467