blob: 6dc3a524301bfc4887ea3e1040a8da49316f75e6 [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
Fred Drake55c38192000-06-29 19:39:57 +0000139 if self.attributes:
Paul Prescod73678da2000-07-01 04:58:47 +0000140 for attr in self._attrs.values():
Fred Drake1f549022000-09-24 05:21:58 +0000141 self.removeAttributeNode(attr)
142 assert not len(self._attrs)
143 assert not len(self._attrsNS)
Paul Prescod73678da2000-07-01 04:58:47 +0000144 if Node._debug:
Fred Drake1f549022000-09-24 05:21:58 +0000145 index = repr(id(self)) + repr(self.__class__)
146 self.debug.write("Deleting: %s\n" % index)
Paul Prescod73678da2000-07-01 04:58:47 +0000147 del Node.allnodes[index]
Fred Drake55c38192000-06-29 19:39:57 +0000148
Fred Drake1f549022000-09-24 05:21:58 +0000149def _write_data(writer, data):
Fred Drake55c38192000-06-29 19:39:57 +0000150 "Writes datachars to writer."
Fred Drake1f549022000-09-24 05:21:58 +0000151 data = string.replace(data, "&", "&amp;")
152 data = string.replace(data, "<", "&lt;")
153 data = string.replace(data, "\"", "&quot;")
154 data = string.replace(data, ">", "&gt;")
Fred Drake55c38192000-06-29 19:39:57 +0000155 writer.write(data)
156
Fred Drake1f549022000-09-24 05:21:58 +0000157def _getElementsByTagNameHelper(parent, name, rc):
Fred Drake55c38192000-06-29 19:39:57 +0000158 for node in parent.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000159 if node.nodeType == Node.ELEMENT_NODE and \
160 (name == "*" or node.tagName == name):
161 rc.append(node)
162 _getElementsByTagNameHelper(node, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000163 return rc
164
Fred Drake1f549022000-09-24 05:21:58 +0000165def _getElementsByTagNameNSHelper(parent, nsURI, localName, rc):
Fred Drake55c38192000-06-29 19:39:57 +0000166 for node in parent.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000167 if node.nodeType == Node.ELEMENT_NODE:
168 if ((localName == "*" or node.tagName == localName) and
169 (nsURI == "*" or node.namespaceURI == nsURI)):
170 rc.append(node)
171 _getElementsByTagNameNSHelper(node, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000172
173class Attr(Node):
Fred Drake1f549022000-09-24 05:21:58 +0000174 nodeType = Node.ATTRIBUTE_NODE
175
176 def __init__(self, qName, namespaceURI="", localName=None, prefix=None):
Fred Drake55c38192000-06-29 19:39:57 +0000177 # skip setattr for performance
Fred Drake1f549022000-09-24 05:21:58 +0000178 self.__dict__["localName"] = localName or qName
Paul Prescod73678da2000-07-01 04:58:47 +0000179 self.__dict__["nodeName"] = self.__dict__["name"] = qName
Fred Drake1f549022000-09-24 05:21:58 +0000180 self.__dict__["namespaceURI"] = namespaceURI
181 self.__dict__["prefix"] = prefix
182 self.attributes = None
183 Node.__init__(self)
Paul Prescod73678da2000-07-01 04:58:47 +0000184 # nodeValue and value are set elsewhere
Fred Drake55c38192000-06-29 19:39:57 +0000185
Fred Drake1f549022000-09-24 05:21:58 +0000186 def __setattr__(self, name, value):
187 if name in ("value", "nodeValue"):
188 self.__dict__["value"] = self.__dict__["nodeValue"] = value
Fred Drake55c38192000-06-29 19:39:57 +0000189 else:
Fred Drake1f549022000-09-24 05:21:58 +0000190 self.__dict__[name] = value
Fred Drake55c38192000-06-29 19:39:57 +0000191
192class AttributeList:
Paul Prescod73678da2000-07-01 04:58:47 +0000193 """the attribute list is a transient interface to the underlying
Fred Drake1f549022000-09-24 05:21:58 +0000194 dictionaries. mutations here will change the underlying element's
195 dictionary"""
196 def __init__(self, attrs, attrsNS):
197 self._attrs = attrs
198 self._attrsNS = attrsNS
199 self.length = len(self._attrs.keys())
Fred Drake55c38192000-06-29 19:39:57 +0000200
Fred Drake1f549022000-09-24 05:21:58 +0000201 def item(self, index):
Fred Drake55c38192000-06-29 19:39:57 +0000202 try:
203 return self[self.keys()[index]]
204 except IndexError:
205 return None
Fred Drake55c38192000-06-29 19:39:57 +0000206
Fred Drake1f549022000-09-24 05:21:58 +0000207 def items(self):
208 return map(lambda node: (node.tagName, node.value),
209 self._attrs.values())
210
211 def itemsNS(self):
212 return map(lambda node: ((node.URI, node.localName), node.value),
213 self._attrs.values())
Fred Drake55c38192000-06-29 19:39:57 +0000214
Fred Drake1f549022000-09-24 05:21:58 +0000215 def keys(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000216 return self._attrs.keys()
Fred Drake55c38192000-06-29 19:39:57 +0000217
Fred Drake1f549022000-09-24 05:21:58 +0000218 def keysNS(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000219 return self._attrsNS.keys()
Fred Drake55c38192000-06-29 19:39:57 +0000220
Fred Drake1f549022000-09-24 05:21:58 +0000221 def values(self):
Paul Prescod73678da2000-07-01 04:58:47 +0000222 return self._attrs.values()
Fred Drake55c38192000-06-29 19:39:57 +0000223
Fred Drake1f549022000-09-24 05:21:58 +0000224 def __len__(self):
Fred Drake55c38192000-06-29 19:39:57 +0000225 return self.length
226
Fred Drake1f549022000-09-24 05:21:58 +0000227 def __cmp__(self, other):
228 if self._attrs is getattr(other, "_attrs", None):
Fred Drake55c38192000-06-29 19:39:57 +0000229 return 0
230 else:
Fred Drake1f549022000-09-24 05:21:58 +0000231 return cmp(id(self), id(other))
Fred Drake55c38192000-06-29 19:39:57 +0000232
233 #FIXME: is it appropriate to return .value?
Fred Drake1f549022000-09-24 05:21:58 +0000234 def __getitem__(self, attname_or_tuple):
235 if type(attname_or_tuple) is types.TupleType:
Paul Prescod73678da2000-07-01 04:58:47 +0000236 return self._attrsNS[attname_or_tuple]
Fred Drake55c38192000-06-29 19:39:57 +0000237 else:
Paul Prescod73678da2000-07-01 04:58:47 +0000238 return self._attrs[attname_or_tuple]
Fred Drake55c38192000-06-29 19:39:57 +0000239
Paul Prescod1e688272000-07-01 19:21:47 +0000240 # same as set
Fred Drake1f549022000-09-24 05:21:58 +0000241 def __setitem__(self, attname, value):
242 if type(value) is types.StringType:
243 node = Attr(attname)
Paul Prescod1e688272000-07-01 19:21:47 +0000244 node.value=value
245 else:
Fred Drake1f549022000-09-24 05:21:58 +0000246 assert isinstance(value, Attr) or type(value) is types.StringType
247 node = value
248 old = self._attrs.get(attname, None)
Paul Prescod1e688272000-07-01 19:21:47 +0000249 if old:
250 old.unlink()
Fred Drake1f549022000-09-24 05:21:58 +0000251 self._attrs[node.name] = node
252 self._attrsNS[(node.namespaceURI, node.localName)] = node
Paul Prescod73678da2000-07-01 04:58:47 +0000253
Fred Drake1f549022000-09-24 05:21:58 +0000254 def __delitem__(self, attname_or_tuple):
255 node = self[attname_or_tuple]
Paul Prescod73678da2000-07-01 04:58:47 +0000256 node.unlink()
257 del self._attrs[node.name]
258 del self._attrsNS[(node.namespaceURI, node.localName)]
Fred Drake1f549022000-09-24 05:21:58 +0000259
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000260class Element(Node):
Fred Drake1f549022000-09-24 05:21:58 +0000261 nodeType = Node.ELEMENT_NODE
262
263 def __init__(self, tagName, namespaceURI="", prefix="",
264 localName=None):
265 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000266 self.tagName = self.nodeName = tagName
Fred Drake1f549022000-09-24 05:21:58 +0000267 self.localName = localName or tagName
268 self.prefix = prefix
269 self.namespaceURI = namespaceURI
270 self.nodeValue = None
Fred Drake55c38192000-06-29 19:39:57 +0000271
Paul Prescod73678da2000-07-01 04:58:47 +0000272 self._attrs={} # attributes are double-indexed:
273 self._attrsNS={}# tagName -> Attribute
Fred Drake55c38192000-06-29 19:39:57 +0000274 # URI,localName -> Attribute
275 # in the future: consider lazy generation of attribute objects
276 # this is too tricky for now because of headaches
277 # with namespaces.
278
Fred Drake1f549022000-09-24 05:21:58 +0000279 def getAttribute(self, attname):
Paul Prescod73678da2000-07-01 04:58:47 +0000280 return self._attrs[attname].value
Fred Drake55c38192000-06-29 19:39:57 +0000281
Fred Drake1f549022000-09-24 05:21:58 +0000282 def getAttributeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000283 return self._attrsNS[(namespaceURI, localName)].value
Fred Drake1f549022000-09-24 05:21:58 +0000284
285 def setAttribute(self, attname, value):
286 attr = Attr(attname)
Fred Drake55c38192000-06-29 19:39:57 +0000287 # for performance
Fred Drake1f549022000-09-24 05:21:58 +0000288 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 setAttributeNS(self, namespaceURI, qualifiedName, value):
292 prefix, localname = _nssplit(qualifiedName)
Fred Drake55c38192000-06-29 19:39:57 +0000293 # for performance
Fred Drake1f549022000-09-24 05:21:58 +0000294 attr = Attr(qualifiedName, namespaceURI, localname, prefix)
295 attr.__dict__["value"] = attr.__dict__["nodeValue"] = value
296 self.setAttributeNode(attr)
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000297 # FIXME: return original node if something changed.
Fred Drake55c38192000-06-29 19:39:57 +0000298
Fred Drake1f549022000-09-24 05:21:58 +0000299 def getAttributeNode(self, attrname):
300 return self._attrs.get(attrname)
Paul Prescod73678da2000-07-01 04:58:47 +0000301
Fred Drake1f549022000-09-24 05:21:58 +0000302 def getAttributeNodeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000303 return self._attrsNS[(namespaceURI, localName)]
304
Fred Drake1f549022000-09-24 05:21:58 +0000305 def setAttributeNode(self, attr):
306 old = self._attrs.get(attr.name, None)
Paul Prescod73678da2000-07-01 04:58:47 +0000307 if old:
308 old.unlink()
Fred Drake1f549022000-09-24 05:21:58 +0000309 self._attrs[attr.name] = attr
310 self._attrsNS[(attr.namespaceURI, attr.localName)] = attr
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000311 # FIXME: return old value if something changed
Fred Drake55c38192000-06-29 19:39:57 +0000312
Fred Drake1f549022000-09-24 05:21:58 +0000313 def removeAttribute(self, name):
Paul Prescod73678da2000-07-01 04:58:47 +0000314 attr = self._attrs[name]
Fred Drake1f549022000-09-24 05:21:58 +0000315 self.removeAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000316
Fred Drake1f549022000-09-24 05:21:58 +0000317 def removeAttributeNS(self, namespaceURI, localName):
Paul Prescod73678da2000-07-01 04:58:47 +0000318 attr = self._attrsNS[(namespaceURI, localName)]
Fred Drake1f549022000-09-24 05:21:58 +0000319 self.removeAttributeNode(attr)
Fred Drake55c38192000-06-29 19:39:57 +0000320
Fred Drake1f549022000-09-24 05:21:58 +0000321 def removeAttributeNode(self, node):
Paul Prescod73678da2000-07-01 04:58:47 +0000322 node.unlink()
323 del self._attrs[node.name]
324 del self._attrsNS[(node.namespaceURI, node.localName)]
Fred Drake55c38192000-06-29 19:39:57 +0000325
Fred Drake1f549022000-09-24 05:21:58 +0000326 def getElementsByTagName(self, name):
327 return _getElementsByTagNameHelper(self, name, [])
Fred Drake55c38192000-06-29 19:39:57 +0000328
Fred Drake1f549022000-09-24 05:21:58 +0000329 def getElementsByTagNameNS(self, namespaceURI, localName):
330 _getElementsByTagNameNSHelper(self, namespaceURI, localName, [])
Fred Drake55c38192000-06-29 19:39:57 +0000331
Fred Drake1f549022000-09-24 05:21:58 +0000332 def __repr__(self):
333 return "<DOM Element: %s at %s>" % (self.tagName, id(self))
Fred Drake55c38192000-06-29 19:39:57 +0000334
Martin v. Löwisa2fda0d2000-10-07 12:10:28 +0000335 # undocumented
Fred Drake55c38192000-06-29 19:39:57 +0000336 def writexml(self, writer):
Fred Drake1f549022000-09-24 05:21:58 +0000337 writer.write("<" + self.tagName)
Fred Drake55c38192000-06-29 19:39:57 +0000338
Fred Drake1f549022000-09-24 05:21:58 +0000339 a_names = self._get_attributes().keys()
Fred Drake55c38192000-06-29 19:39:57 +0000340 a_names.sort()
341
342 for a_name in a_names:
Fred Drake1f549022000-09-24 05:21:58 +0000343 writer.write(" %s=\"" % a_name)
Martin v. Löwis2c8a89c2000-10-06 22:36:03 +0000344 _write_data(writer, self._get_attributes()[a_name].value)
Fred Drake55c38192000-06-29 19:39:57 +0000345 writer.write("\"")
346 if self.childNodes:
347 writer.write(">")
348 for node in self.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000349 node.writexml(writer)
350 writer.write("</%s>" % self.tagName)
Fred Drake55c38192000-06-29 19:39:57 +0000351 else:
352 writer.write("/>")
353
Fred Drake1f549022000-09-24 05:21:58 +0000354 def _get_attributes(self):
355 return AttributeList(self._attrs, self._attrsNS)
Fred Drake55c38192000-06-29 19:39:57 +0000356
Fred Drake1f549022000-09-24 05:21:58 +0000357class Comment(Node):
358 nodeType = Node.COMMENT_NODE
Fred Drake55c38192000-06-29 19:39:57 +0000359
Fred Drake1f549022000-09-24 05:21:58 +0000360 def __init__(self, data):
361 Node.__init__(self)
362 self.data = self.nodeValue = data
363 self.nodeName = "#comment"
364 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000365
Fred Drake1f549022000-09-24 05:21:58 +0000366 def writexml(self, writer):
367 writer.write("<!--%s-->" % self.data)
368
369class ProcessingInstruction(Node):
370 nodeType = Node.PROCESSING_INSTRUCTION_NODE
371
372 def __init__(self, target, data):
373 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000374 self.target = self.nodeName = target
375 self.data = self.nodeValue = data
Fred Drake1f549022000-09-24 05:21:58 +0000376 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000377
Fred Drake1f549022000-09-24 05:21:58 +0000378 def writexml(self, writer):
379 writer.write("<?%s %s?>" % (self.target, self.data))
Fred Drake55c38192000-06-29 19:39:57 +0000380
Fred Drake1f549022000-09-24 05:21:58 +0000381class Text(Node):
382 nodeType = Node.TEXT_NODE
383 nodeName = "#text"
384
385 def __init__(self, data):
386 Node.__init__(self)
Fred Drake55c38192000-06-29 19:39:57 +0000387 self.data = self.nodeValue = data
Fred Drake1f549022000-09-24 05:21:58 +0000388 self.attributes = None
Fred Drake55c38192000-06-29 19:39:57 +0000389
390 def __repr__(self):
Fred Drake1f549022000-09-24 05:21:58 +0000391 if len(self.data) > 10:
392 dotdotdot = "..."
Fred Drake55c38192000-06-29 19:39:57 +0000393 else:
Fred Drake1f549022000-09-24 05:21:58 +0000394 dotdotdot = ""
395 return "<DOM Text node \"%s%s\">" % (self.data[0:10], dotdotdot)
Fred Drake55c38192000-06-29 19:39:57 +0000396
Fred Drake1f549022000-09-24 05:21:58 +0000397 def writexml(self, writer):
398 _write_data(writer, self.data)
Fred Drake55c38192000-06-29 19:39:57 +0000399
Fred Drake1f549022000-09-24 05:21:58 +0000400def _nssplit(qualifiedName):
Martin v. Löwis830b37b2000-10-07 19:03:20 +0000401 import string
402 fields = string.split(qualifiedName,':', 1)
Paul Prescod73678da2000-07-01 04:58:47 +0000403 if len(fields) == 2:
404 return fields
405 elif len(fields) == 1:
Fred Drake1f549022000-09-24 05:21:58 +0000406 return ('', fields[0])
Paul Prescod73678da2000-07-01 04:58:47 +0000407
Fred Drake1f549022000-09-24 05:21:58 +0000408class Document(Node):
409 nodeType = Node.DOCUMENT_NODE
410 documentElement = None
Fred Drake55c38192000-06-29 19:39:57 +0000411
Fred Drake1f549022000-09-24 05:21:58 +0000412 def __init__(self):
413 Node.__init__(self)
414 self.attributes = None
415 self.nodeName = "#document"
416 self.nodeValue = None
417
418 def appendChild(self, node):
419 if node.nodeType == Node.ELEMENT_NODE:
Paul Prescodce88db02000-09-15 17:09:19 +0000420 if self.documentElement:
421 raise TypeError, "Two document elements disallowed"
422 else:
Fred Drake1f549022000-09-24 05:21:58 +0000423 self.documentElement = node
424 Node.appendChild(self, node)
Paul Prescod73678da2000-07-01 04:58:47 +0000425 return node
426
Fred Drake1f549022000-09-24 05:21:58 +0000427 createElement = Element
Fred Drake55c38192000-06-29 19:39:57 +0000428
Fred Drake1f549022000-09-24 05:21:58 +0000429 createTextNode = Text
Fred Drake55c38192000-06-29 19:39:57 +0000430
Fred Drake1f549022000-09-24 05:21:58 +0000431 createComment = Comment
Fred Drake55c38192000-06-29 19:39:57 +0000432
Fred Drake1f549022000-09-24 05:21:58 +0000433 createProcessingInstruction = ProcessingInstruction
Fred Drake55c38192000-06-29 19:39:57 +0000434
Fred Drake1f549022000-09-24 05:21:58 +0000435 createAttribute = Attr
Fred Drake55c38192000-06-29 19:39:57 +0000436
437 def createElementNS(self, namespaceURI, qualifiedName):
Fred Drake1f549022000-09-24 05:21:58 +0000438 prefix,localName = _nssplit(qualifiedName)
Paul Prescod73678da2000-07-01 04:58:47 +0000439 return Element(qualifiedName, namespaceURI, prefix, localName)
Fred Drake55c38192000-06-29 19:39:57 +0000440
441 def createAttributeNS(self, namespaceURI, qualifiedName):
Fred Drake1f549022000-09-24 05:21:58 +0000442 prefix,localName = _nssplit(qualifiedName)
Martin v. Löwis2c8a89c2000-10-06 22:36:03 +0000443 return Attr(qualifiedName, namespaceURI, localName, prefix)
Fred Drake55c38192000-06-29 19:39:57 +0000444
Fred Drake1f549022000-09-24 05:21:58 +0000445 def getElementsByTagNameNS(self, namespaceURI, localName):
446 _getElementsByTagNameNSHelper(self, namespaceURI, localName)
Fred Drake55c38192000-06-29 19:39:57 +0000447
Fred Drake1f549022000-09-24 05:21:58 +0000448 def unlink(self):
449 self.documentElement = None
450 Node.unlink(self)
Fred Drake55c38192000-06-29 19:39:57 +0000451
Fred Drake1f549022000-09-24 05:21:58 +0000452 def getElementsByTagName(self, name):
453 rc = []
454 _getElementsByTagNameHelper(self, name, rc)
Fred Drake55c38192000-06-29 19:39:57 +0000455 return rc
456
Fred Drake1f549022000-09-24 05:21:58 +0000457 def writexml(self, writer):
Fred Drake55c38192000-06-29 19:39:57 +0000458 for node in self.childNodes:
Fred Drake1f549022000-09-24 05:21:58 +0000459 node.writexml(writer)
Fred Drake55c38192000-06-29 19:39:57 +0000460
Fred Drake1f549022000-09-24 05:21:58 +0000461def _doparse(func, args, kwargs):
462 events = apply(func, args, kwargs)
463 toktype, rootNode = events.getEvent()
464 events.expandNode(rootNode)
Fred Drake55c38192000-06-29 19:39:57 +0000465 return rootNode
466
Fred Drake1f549022000-09-24 05:21:58 +0000467def parse(*args, **kwargs):
Paul Prescod623511b2000-07-21 22:05:49 +0000468 "Parse a file into a DOM by filename or file object"
Fred Drake1f549022000-09-24 05:21:58 +0000469 return _doparse(pulldom.parse, args, kwargs)
Fred Drake55c38192000-06-29 19:39:57 +0000470
Fred Drake1f549022000-09-24 05:21:58 +0000471def parseString(*args, **kwargs):
Paul Prescod623511b2000-07-21 22:05:49 +0000472 "Parse a file into a DOM from a string"
Fred Drake1f549022000-09-24 05:21:58 +0000473 return _doparse(pulldom.parseString, args, kwargs)
Paul Prescod623511b2000-07-21 22:05:49 +0000474