blob: 00bd4ca0831c6ef1eef84dcc1914d428f06cb7a1 [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):
Fred Drake13a30692000-10-09 20:04:16 +0000105 if self.childNodes:
106 last = self.lastChild
107 node.previousSibling = last
108 last.nextSibling = node
109 else:
110 node.previousSibling = None
111 node.nextSibling = None
Fred Drake1f549022000-09-24 05:21:58 +0000112 self.childNodes.append(node)
Paul Prescod73678da2000-07-01 04:58:47 +0000113 return node
114
Fred Drake1f549022000-09-24 05:21:58 +0000115 def replaceChild(self, newChild, oldChild):
116 index = self.childNodes.index(oldChild)
117 self.childNodes[index] = oldChild
Paul Prescod73678da2000-07-01 04:58:47 +0000118
Fred Drake1f549022000-09-24 05:21:58 +0000119 def removeChild(self, oldChild):
120 index = self.childNodes.index(oldChild)
Paul Prescod73678da2000-07-01 04:58:47 +0000121 del self.childNodes[index]
122
Fred Drake1f549022000-09-24 05:21:58 +0000123 def cloneNode(self, deep):
Paul Prescod73678da2000-07-01 04:58:47 +0000124 import new
Fred Drake1f549022000-09-24 05:21:58 +0000125 clone = new.instance(self.__class__, self.__dict__)
126 clone.attributes = self.attributes.copy()
Paul Prescod73678da2000-07-01 04:58:47 +0000127 if not deep:
Fred Drake1f549022000-09-24 05:21:58 +0000128 clone.childNodes = []
Paul Prescod73678da2000-07-01 04:58:47 +0000129 else:
Fred Drake1f549022000-09-24 05:21:58 +0000130 clone.childNodes = map(lambda x: x.cloneNode, self.childNodes)
Paul Prescod73678da2000-07-01 04:58:47 +0000131 return clone
Fred Drake55c38192000-06-29 19:39:57 +0000132
Fred Drake1f549022000-09-24 05:21:58 +0000133 def unlink(self):
134 self.parentNode = None
Fred Drake55c38192000-06-29 19:39:57 +0000135 while self.childNodes:
136 self.childNodes[-1].unlink()
137 del self.childNodes[-1] # probably not most efficient!
Fred Drake1f549022000-09-24 05:21:58 +0000138 self.childNodes = None
Paul Prescod4221ff02000-10-13 20:11:42 +0000139 self.previousSibling = None
140 self.nextSibling = None
Fred Drake55c38192000-06-29 19:39:57 +0000141 if self.attributes:
Paul Prescod73678da2000-07-01 04:58:47 +0000142 for attr in self._attrs.values():
Fred Drake1f549022000-09-24 05:21:58 +0000143 self.removeAttributeNode(attr)
144 assert not len(self._attrs)
145 assert not len(self._attrsNS)
Paul Prescod73678da2000-07-01 04:58:47 +0000146 if Node._debug:
Fred Drake1f549022000-09-24 05:21:58 +0000147 index = repr(id(self)) + repr(self.__class__)
148 self.debug.write("Deleting: %s\n" % index)
Paul Prescod73678da2000-07-01 04:58:47 +0000149 del Node.allnodes[index]
Fred Drake55c38192000-06-29 19:39:57 +0000150
Fred Drake1f549022000-09-24 05:21:58 +0000151def _write_data(writer, data):
Fred Drake55c38192000-06-29 19:39:57 +0000152 "Writes datachars to writer."
Fred Drake1f549022000-09-24 05:21:58 +0000153 data = string.replace(data, "&", "&amp;")
154 data = string.replace(data, "<", "&lt;")
155 data = string.replace(data, "\"", "&quot;")
156 data = string.replace(data, ">", "&gt;")
Fred Drake55c38192000-06-29 19:39:57 +0000157 writer.write(data)
158
Fred Drake1f549022000-09-24 05:21:58 +0000159def _getElementsByTagNameHelper(parent, name, rc):
Fred Drake55c38192000-06-29 19:39:57 +0000160 for node in parent.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000161 if node.nodeType == Node.ELEMENT_NODE and \
162 (name == "*" or node.tagName == name):
163 rc.append(node)
164 _getElementsByTagNameHelper(node, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000165 return rc
166
Fred Drake1f549022000-09-24 05:21:58 +0000167def _getElementsByTagNameNSHelper(parent, nsURI, localName, rc):
Fred Drake55c38192000-06-29 19:39:57 +0000168 for node in parent.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000169 if node.nodeType == Node.ELEMENT_NODE:
170 if ((localName == "*" or node.tagName == localName) and
171 (nsURI == "*" or node.namespaceURI == nsURI)):
172 rc.append(node)
173 _getElementsByTagNameNSHelper(node, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000174
175class Attr(Node):
Fred Drake1f549022000-09-24 05:21:58 +0000176 nodeType = Node.ATTRIBUTE_NODE
177
178 def __init__(self, qName, namespaceURI="", localName=None, prefix=None):
Fred Drake55c38192000-06-29 19:39:57 +0000179 # skip setattr for performance
Fred Drake1f549022000-09-24 05:21:58 +0000180 self.__dict__["localName"] = localName or qName
Paul Prescod73678da2000-07-01 04:58:47 +0000181 self.__dict__["nodeName"] = self.__dict__["name"] = qName
Fred Drake1f549022000-09-24 05:21:58 +0000182 self.__dict__["namespaceURI"] = namespaceURI
183 self.__dict__["prefix"] = prefix
184 self.attributes = None
185 Node.__init__(self)
Paul Prescod73678da2000-07-01 04:58:47 +0000186 # nodeValue and value are set elsewhere
Fred Drake55c38192000-06-29 19:39:57 +0000187
Fred Drake1f549022000-09-24 05:21:58 +0000188 def __setattr__(self, name, value):
189 if name in ("value", "nodeValue"):
190 self.__dict__["value"] = self.__dict__["nodeValue"] = value
Fred Drake55c38192000-06-29 19:39:57 +0000191 else:
Fred Drake1f549022000-09-24 05:21:58 +0000192 self.__dict__[name] = value
Fred Drake55c38192000-06-29 19:39:57 +0000193
194class AttributeList:
Paul Prescod73678da2000-07-01 04:58:47 +0000195 """the attribute list is a transient interface to the underlying
Fred Drake1f549022000-09-24 05:21:58 +0000196 dictionaries. mutations here will change the underlying element's
197 dictionary"""
198 def __init__(self, attrs, attrsNS):
199 self._attrs = attrs
200 self._attrsNS = attrsNS
201 self.length = len(self._attrs.keys())
Fred Drake55c38192000-06-29 19:39:57 +0000202
Fred Drake1f549022000-09-24 05:21:58 +0000203 def item(self, index):
Fred Drake55c38192000-06-29 19:39:57 +0000204 try:
205 return self[self.keys()[index]]
206 except IndexError:
207 return None
Fred Drake55c38192000-06-29 19:39:57 +0000208
Fred Drake1f549022000-09-24 05:21:58 +0000209 def items(self):
210 return map(lambda node: (node.tagName, node.value),
211 self._attrs.values())
212
213 def itemsNS(self):
214 return map(lambda node: ((node.URI, node.localName), node.value),
215 self._attrs.values())
Fred Drake55c38192000-06-29 19:39:57 +0000216
Fred Drake1f549022000-09-24 05:21:58 +0000217 def keys(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000218 return self._attrs.keys()
Fred Drake55c38192000-06-29 19:39:57 +0000219
Fred Drake1f549022000-09-24 05:21:58 +0000220 def keysNS(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000221 return self._attrsNS.keys()
Fred Drake55c38192000-06-29 19:39:57 +0000222
Fred Drake1f549022000-09-24 05:21:58 +0000223 def values(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000224 return self._attrs.values()
Fred Drake55c38192000-06-29 19:39:57 +0000225
Fred Drake1f549022000-09-24 05:21:58 +0000226 def __len__(self):
Fred Drake55c38192000-06-29 19:39:57 +0000227 return self.length
228
Fred Drake1f549022000-09-24 05:21:58 +0000229 def __cmp__(self, other):
230 if self._attrs is getattr(other, "_attrs", None):
Fred Drake55c38192000-06-29 19:39:57 +0000231 return 0
232 else:
Fred Drake1f549022000-09-24 05:21:58 +0000233 return cmp(id(self), id(other))
Fred Drake55c38192000-06-29 19:39:57 +0000234
235 #FIXME: is it appropriate to return .value?
Fred Drake1f549022000-09-24 05:21:58 +0000236 def __getitem__(self, attname_or_tuple):
237 if type(attname_or_tuple) is types.TupleType:
Paul Prescod73678da2000-07-01 04:58:47 +0000238 return self._attrsNS[attname_or_tuple]
Fred Drake55c38192000-06-29 19:39:57 +0000239 else:
Paul Prescod73678da2000-07-01 04:58:47 +0000240 return self._attrs[attname_or_tuple]
Fred Drake55c38192000-06-29 19:39:57 +0000241
Paul Prescod1e688272000-07-01 19:21:47 +0000242 # same as set
Fred Drake1f549022000-09-24 05:21:58 +0000243 def __setitem__(self, attname, value):
244 if type(value) is types.StringType:
245 node = Attr(attname)
Paul Prescod1e688272000-07-01 19:21:47 +0000246 node.value=value
247 else:
Fred Drake1f549022000-09-24 05:21:58 +0000248 assert isinstance(value, Attr) or type(value) is types.StringType
249 node = value
250 old = self._attrs.get(attname, None)
Paul Prescod1e688272000-07-01 19:21:47 +0000251 if old:
252 old.unlink()
Fred Drake1f549022000-09-24 05:21:58 +0000253 self._attrs[node.name] = node
254 self._attrsNS[(node.namespaceURI, node.localName)] = node
Paul Prescod73678da2000-07-01 04:58:47 +0000255
Fred Drake1f549022000-09-24 05:21:58 +0000256 def __delitem__(self, attname_or_tuple):
257 node = self[attname_or_tuple]
Paul Prescod73678da2000-07-01 04:58:47 +0000258 node.unlink()
259 del self._attrs[node.name]
260 del self._attrsNS[(node.namespaceURI, node.localName)]
Fred Drake1f549022000-09-24 05:21:58 +0000261
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000262class Element(Node):
Fred Drake1f549022000-09-24 05:21:58 +0000263 nodeType = Node.ELEMENT_NODE
264
265 def __init__(self, tagName, namespaceURI="", prefix="",
266 localName=None):
267 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000268 self.tagName = self.nodeName = tagName
Fred Drake1f549022000-09-24 05:21:58 +0000269 self.localName = localName or tagName
270 self.prefix = prefix
271 self.namespaceURI = namespaceURI
272 self.nodeValue = None
Fred Drake55c38192000-06-29 19:39:57 +0000273
Paul Prescod73678da2000-07-01 04:58:47 +0000274 self._attrs={} # attributes are double-indexed:
275 self._attrsNS={}# tagName -> Attribute
Fred Drake55c38192000-06-29 19:39:57 +0000276 # URI,localName -> Attribute
277 # in the future: consider lazy generation of attribute objects
278 # this is too tricky for now because of headaches
279 # with namespaces.
280
Fred Drake1f549022000-09-24 05:21:58 +0000281 def getAttribute(self, attname):
Paul Prescod73678da2000-07-01 04:58:47 +0000282 return self._attrs[attname].value
Fred Drake55c38192000-06-29 19:39:57 +0000283
Fred Drake1f549022000-09-24 05:21:58 +0000284 def getAttributeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000285 return self._attrsNS[(namespaceURI, localName)].value
Fred Drake1f549022000-09-24 05:21:58 +0000286
287 def setAttribute(self, attname, value):
288 attr = Attr(attname)
Fred Drake55c38192000-06-29 19:39:57 +0000289 # for performance
Fred Drake1f549022000-09-24 05:21:58 +0000290 attr.__dict__["value"] = attr.__dict__["nodeValue"] = value
291 self.setAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000292
Fred Drake1f549022000-09-24 05:21:58 +0000293 def setAttributeNS(self, namespaceURI, qualifiedName, value):
294 prefix, localname = _nssplit(qualifiedName)
Fred Drake55c38192000-06-29 19:39:57 +0000295 # for performance
Fred Drake1f549022000-09-24 05:21:58 +0000296 attr = Attr(qualifiedName, namespaceURI, localname, prefix)
297 attr.__dict__["value"] = attr.__dict__["nodeValue"] = value
298 self.setAttributeNode(attr)
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000299 # FIXME: return original node if something changed.
Fred Drake55c38192000-06-29 19:39:57 +0000300
Fred Drake1f549022000-09-24 05:21:58 +0000301 def getAttributeNode(self, attrname):
302 return self._attrs.get(attrname)
Paul Prescod73678da2000-07-01 04:58:47 +0000303
Fred Drake1f549022000-09-24 05:21:58 +0000304 def getAttributeNodeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000305 return self._attrsNS[(namespaceURI, localName)]
306
Fred Drake1f549022000-09-24 05:21:58 +0000307 def setAttributeNode(self, attr):
308 old = self._attrs.get(attr.name, None)
Paul Prescod73678da2000-07-01 04:58:47 +0000309 if old:
310 old.unlink()
Fred Drake1f549022000-09-24 05:21:58 +0000311 self._attrs[attr.name] = attr
312 self._attrsNS[(attr.namespaceURI, attr.localName)] = attr
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000313 # FIXME: return old value if something changed
Fred Drake55c38192000-06-29 19:39:57 +0000314
Fred Drake1f549022000-09-24 05:21:58 +0000315 def removeAttribute(self, name):
Paul Prescod73678da2000-07-01 04:58:47 +0000316 attr = self._attrs[name]
Fred Drake1f549022000-09-24 05:21:58 +0000317 self.removeAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000318
Fred Drake1f549022000-09-24 05:21:58 +0000319 def removeAttributeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000320 attr = self._attrsNS[(namespaceURI, localName)]
Fred Drake1f549022000-09-24 05:21:58 +0000321 self.removeAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000322
Fred Drake1f549022000-09-24 05:21:58 +0000323 def removeAttributeNode(self, node):
Paul Prescod73678da2000-07-01 04:58:47 +0000324 node.unlink()
325 del self._attrs[node.name]
326 del self._attrsNS[(node.namespaceURI, node.localName)]
Fred Drake55c38192000-06-29 19:39:57 +0000327
Fred Drake1f549022000-09-24 05:21:58 +0000328 def getElementsByTagName(self, name):
329 return _getElementsByTagNameHelper(self, name, [])
Fred Drake55c38192000-06-29 19:39:57 +0000330
Fred Drake1f549022000-09-24 05:21:58 +0000331 def getElementsByTagNameNS(self, namespaceURI, localName):
332 _getElementsByTagNameNSHelper(self, namespaceURI, localName, [])
Fred Drake55c38192000-06-29 19:39:57 +0000333
Fred Drake1f549022000-09-24 05:21:58 +0000334 def __repr__(self):
335 return "<DOM Element: %s at %s>" % (self.tagName, id(self))
Fred Drake55c38192000-06-29 19:39:57 +0000336
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000337 # undocumented
Fred Drake55c38192000-06-29 19:39:57 +0000338 def writexml(self, writer):
Fred Drake1f549022000-09-24 05:21:58 +0000339 writer.write("<" + self.tagName)
Fred Drake55c38192000-06-29 19:39:57 +0000340
Fred Drake1f549022000-09-24 05:21:58 +0000341 a_names = self._get_attributes().keys()
Fred Drake55c38192000-06-29 19:39:57 +0000342 a_names.sort()
343
344 for a_name in a_names:
Fred Drake1f549022000-09-24 05:21:58 +0000345 writer.write(" %s=\"" % a_name)
Martin v. Löwis2c8a89c2000-10-06 22:36:03 +0000346 _write_data(writer, self._get_attributes()[a_name].value)
Fred Drake55c38192000-06-29 19:39:57 +0000347 writer.write("\"")
348 if self.childNodes:
349 writer.write(">")
350 for node in self.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000351 node.writexml(writer)
352 writer.write("</%s>" % self.tagName)
Fred Drake55c38192000-06-29 19:39:57 +0000353 else:
354 writer.write("/>")
355
Fred Drake1f549022000-09-24 05:21:58 +0000356 def _get_attributes(self):
357 return AttributeList(self._attrs, self._attrsNS)
Fred Drake55c38192000-06-29 19:39:57 +0000358
Fred Drake1f549022000-09-24 05:21:58 +0000359class Comment(Node):
360 nodeType = Node.COMMENT_NODE
Fred Drake55c38192000-06-29 19:39:57 +0000361
Fred Drake1f549022000-09-24 05:21:58 +0000362 def __init__(self, data):
363 Node.__init__(self)
364 self.data = self.nodeValue = data
365 self.nodeName = "#comment"
366 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-->" % self.data)
370
371class ProcessingInstruction(Node):
372 nodeType = Node.PROCESSING_INSTRUCTION_NODE
373
374 def __init__(self, target, data):
375 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000376 self.target = self.nodeName = target
377 self.data = self.nodeValue = data
Fred Drake1f549022000-09-24 05:21:58 +0000378 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000379
Fred Drake1f549022000-09-24 05:21:58 +0000380 def writexml(self, writer):
381 writer.write("<?%s %s?>" % (self.target, self.data))
Fred Drake55c38192000-06-29 19:39:57 +0000382
Fred Drake1f549022000-09-24 05:21:58 +0000383class Text(Node):
384 nodeType = Node.TEXT_NODE
385 nodeName = "#text"
386
387 def __init__(self, data):
388 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000389 self.data = self.nodeValue = data
Fred Drake1f549022000-09-24 05:21:58 +0000390 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000391
392 def __repr__(self):
Fred Drake1f549022000-09-24 05:21:58 +0000393 if len(self.data) > 10:
394 dotdotdot = "..."
Fred Drake55c38192000-06-29 19:39:57 +0000395 else:
Fred Drake1f549022000-09-24 05:21:58 +0000396 dotdotdot = ""
397 return "<DOM Text node \"%s%s\">" % (self.data[0:10], dotdotdot)
Fred Drake55c38192000-06-29 19:39:57 +0000398
Fred Drake1f549022000-09-24 05:21:58 +0000399 def writexml(self, writer):
400 _write_data(writer, self.data)
Fred Drake55c38192000-06-29 19:39:57 +0000401
Fred Drake1f549022000-09-24 05:21:58 +0000402def _nssplit(qualifiedName):
Martin v. Löwis830b37b2000-10-07 19:03:20 +0000403 import string
404 fields = string.split(qualifiedName,':', 1)
Paul Prescod73678da2000-07-01 04:58:47 +0000405 if len(fields) == 2:
406 return fields
407 elif len(fields) == 1:
Fred Drake1f549022000-09-24 05:21:58 +0000408 return ('', fields[0])
Paul Prescod73678da2000-07-01 04:58:47 +0000409
Fred Drake1f549022000-09-24 05:21:58 +0000410class Document(Node):
411 nodeType = Node.DOCUMENT_NODE
412 documentElement = None
Fred Drake55c38192000-06-29 19:39:57 +0000413
Fred Drake1f549022000-09-24 05:21:58 +0000414 def __init__(self):
415 Node.__init__(self)
416 self.attributes = None
417 self.nodeName = "#document"
418 self.nodeValue = None
419
420 def appendChild(self, node):
421 if node.nodeType == Node.ELEMENT_NODE:
Paul Prescodce88db02000-09-15 17:09:19 +0000422 if self.documentElement:
423 raise TypeError, "Two document elements disallowed"
424 else:
Fred Drake1f549022000-09-24 05:21:58 +0000425 self.documentElement = node
426 Node.appendChild(self, node)
Paul Prescod73678da2000-07-01 04:58:47 +0000427 return node
428
Fred Drake1f549022000-09-24 05:21:58 +0000429 createElement = Element
Fred Drake55c38192000-06-29 19:39:57 +0000430
Fred Drake1f549022000-09-24 05:21:58 +0000431 createTextNode = Text
Fred Drake55c38192000-06-29 19:39:57 +0000432
Fred Drake1f549022000-09-24 05:21:58 +0000433 createComment = Comment
Fred Drake55c38192000-06-29 19:39:57 +0000434
Fred Drake1f549022000-09-24 05:21:58 +0000435 createProcessingInstruction = ProcessingInstruction
Fred Drake55c38192000-06-29 19:39:57 +0000436
Fred Drake1f549022000-09-24 05:21:58 +0000437 createAttribute = Attr
Fred Drake55c38192000-06-29 19:39:57 +0000438
439 def createElementNS(self, namespaceURI, qualifiedName):
Fred Drake1f549022000-09-24 05:21:58 +0000440 prefix,localName = _nssplit(qualifiedName)
Paul Prescod73678da2000-07-01 04:58:47 +0000441 return Element(qualifiedName, namespaceURI, prefix, localName)
Fred Drake55c38192000-06-29 19:39:57 +0000442
443 def createAttributeNS(self, namespaceURI, qualifiedName):
Fred Drake1f549022000-09-24 05:21:58 +0000444 prefix,localName = _nssplit(qualifiedName)
Martin v. Löwis2c8a89c2000-10-06 22:36:03 +0000445 return Attr(qualifiedName, namespaceURI, localName, prefix)
Fred Drake55c38192000-06-29 19:39:57 +0000446
Fred Drake1f549022000-09-24 05:21:58 +0000447 def getElementsByTagNameNS(self, namespaceURI, localName):
448 _getElementsByTagNameNSHelper(self, namespaceURI, localName)
Fred Drake55c38192000-06-29 19:39:57 +0000449
Fred Drake1f549022000-09-24 05:21:58 +0000450 def unlink(self):
451 self.documentElement = None
452 Node.unlink(self)
Fred Drake55c38192000-06-29 19:39:57 +0000453
Fred Drake1f549022000-09-24 05:21:58 +0000454 def getElementsByTagName(self, name):
455 rc = []
456 _getElementsByTagNameHelper(self, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000457 return rc
458
Fred Drake1f549022000-09-24 05:21:58 +0000459 def writexml(self, writer):
Fred Drake55c38192000-06-29 19:39:57 +0000460 for node in self.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000461 node.writexml(writer)
Fred Drake55c38192000-06-29 19:39:57 +0000462
Fred Drake1f549022000-09-24 05:21:58 +0000463def _doparse(func, args, kwargs):
464 events = apply(func, args, kwargs)
465 toktype, rootNode = events.getEvent()
466 events.expandNode(rootNode)
Fred Drake55c38192000-06-29 19:39:57 +0000467 return rootNode
468
Fred Drake1f549022000-09-24 05:21:58 +0000469def parse(*args, **kwargs):
Paul Prescod623511b2000-07-21 22:05:49 +0000470 "Parse a file into a DOM by filename or file object"
Fred Drake1f549022000-09-24 05:21:58 +0000471 return _doparse(pulldom.parse, args, kwargs)
Fred Drake55c38192000-06-29 19:39:57 +0000472
Fred Drake1f549022000-09-24 05:21:58 +0000473def parseString(*args, **kwargs):
Paul Prescod623511b2000-07-21 22:05:49 +0000474 "Parse a file into a DOM from a string"
Fred Drake1f549022000-09-24 05:21:58 +0000475 return _doparse(pulldom.parseString, args, kwargs)
Paul Prescod623511b2000-07-21 22:05:49 +0000476