blob: 6c4dd948ec9bdb182c138e626949e5cda14161dd [file] [log] [blame]
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001# test for xml.dom.minidom
Paul Prescod7993bcc2000-07-01 14:54:16 +00002
Guido van Rossume2ae77b2001-10-24 20:42:55 +00003import os
Fred Drake17647f52000-07-03 16:37:42 +00004import sys
Martin v. Löwisfd6aaa12003-01-25 22:02:52 +00005import pickle
Fred Drake17647f52000-07-03 16:37:42 +00006import traceback
Martin v. Löwisfd6aaa12003-01-25 22:02:52 +00007from StringIO import StringIO
Barry Warsaw04f357c2002-07-23 19:04:11 +00008from test.test_support import verbose
Fred Drake17647f52000-07-03 16:37:42 +00009
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010import xml.dom
11import xml.dom.minidom
12import xml.parsers.expat
Fred Drakec441f7b2002-07-19 22:16:41 +000013
Thomas Wouters0e3f5912006-08-11 14:57:12 +000014from xml.dom.minidom import parse, Node, Document, parseString
15from xml.dom.minidom import getDOMImplementation
Martin v. Löwisfd6aaa12003-01-25 22:02:52 +000016
Fred Drakec441f7b2002-07-19 22:16:41 +000017
Fred Drake17647f52000-07-03 16:37:42 +000018if __name__ == "__main__":
19 base = sys.argv[0]
20else:
21 base = __file__
Guido van Rossume2ae77b2001-10-24 20:42:55 +000022tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml")
Fred Drake17647f52000-07-03 16:37:42 +000023del base
Paul Prescod7993bcc2000-07-01 14:54:16 +000024
Jeremy Hylton3b0c6002000-10-12 17:31:36 +000025def confirm(test, testname = "Test"):
Fred Drakec441f7b2002-07-19 22:16:41 +000026 if not test:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000027 print("Failed " + testname)
Paul Prescod10d27662000-09-18 19:07:26 +000028 raise Exception
29
Paul Prescod10d27662000-09-18 19:07:26 +000030def testParseFromFile():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +000031 dom = parse(StringIO(open(tstfile).read()))
Paul Prescod4c799192000-09-19 19:33:02 +000032 dom.unlink()
Martin v. Löwis89c528b2000-09-19 16:22:10 +000033 confirm(isinstance(dom,Document))
Paul Prescod10d27662000-09-18 19:07:26 +000034
Jeremy Hylton3b0c6002000-10-12 17:31:36 +000035def testGetElementsByTagName():
36 dom = parse(tstfile)
37 confirm(dom.getElementsByTagName("LI") == \
38 dom.documentElement.getElementsByTagName("LI"))
Paul Prescod7993bcc2000-07-01 14:54:16 +000039 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +000040
Jeremy Hylton3b0c6002000-10-12 17:31:36 +000041def testInsertBefore():
Fred Drakea1bde802000-11-21 22:02:43 +000042 dom = parseString("<doc><foo/></doc>")
43 root = dom.documentElement
44 elem = root.childNodes[0]
45 nelem = dom.createElement("element")
46 root.insertBefore(nelem, elem)
47 confirm(len(root.childNodes) == 2
Fred Drake946f7b12001-09-28 20:31:50 +000048 and root.childNodes.length == 2
Fred Drakea1bde802000-11-21 22:02:43 +000049 and root.childNodes[0] is nelem
Fred Drake946f7b12001-09-28 20:31:50 +000050 and root.childNodes.item(0) is nelem
Fred Drakea1bde802000-11-21 22:02:43 +000051 and root.childNodes[1] is elem
Fred Drake946f7b12001-09-28 20:31:50 +000052 and root.childNodes.item(1) is elem
Fred Drakea1bde802000-11-21 22:02:43 +000053 and root.firstChild is nelem
54 and root.lastChild is elem
55 and root.toxml() == "<doc><element/><foo/></doc>"
56 , "testInsertBefore -- node properly placed in tree")
57 nelem = dom.createElement("element")
58 root.insertBefore(nelem, None)
59 confirm(len(root.childNodes) == 3
Fred Drake946f7b12001-09-28 20:31:50 +000060 and root.childNodes.length == 3
Fred Drakea1bde802000-11-21 22:02:43 +000061 and root.childNodes[1] is elem
Fred Drake946f7b12001-09-28 20:31:50 +000062 and root.childNodes.item(1) is elem
Fred Drakea1bde802000-11-21 22:02:43 +000063 and root.childNodes[2] is nelem
Fred Drake946f7b12001-09-28 20:31:50 +000064 and root.childNodes.item(2) is nelem
Fred Drakea1bde802000-11-21 22:02:43 +000065 and root.lastChild is nelem
66 and nelem.previousSibling is elem
67 and root.toxml() == "<doc><element/><foo/><element/></doc>"
68 , "testInsertBefore -- node properly placed in tree")
69 nelem2 = dom.createElement("bar")
70 root.insertBefore(nelem2, nelem)
71 confirm(len(root.childNodes) == 4
Fred Drake946f7b12001-09-28 20:31:50 +000072 and root.childNodes.length == 4
Fred Drakea1bde802000-11-21 22:02:43 +000073 and root.childNodes[2] is nelem2
Fred Drake946f7b12001-09-28 20:31:50 +000074 and root.childNodes.item(2) is nelem2
Fred Drakea1bde802000-11-21 22:02:43 +000075 and root.childNodes[3] is nelem
Fred Drake946f7b12001-09-28 20:31:50 +000076 and root.childNodes.item(3) is nelem
Fred Drakea1bde802000-11-21 22:02:43 +000077 and nelem2.nextSibling is nelem
78 and nelem.previousSibling is nelem2
79 and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
80 , "testInsertBefore -- node properly placed in tree")
Paul Prescod7993bcc2000-07-01 14:54:16 +000081 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +000082
Fred Drakee50959a2001-12-06 04:32:18 +000083def _create_fragment_test_nodes():
84 dom = parseString("<doc/>")
85 orig = dom.createTextNode("original")
86 c1 = dom.createTextNode("foo")
87 c2 = dom.createTextNode("bar")
88 c3 = dom.createTextNode("bat")
89 dom.documentElement.appendChild(orig)
90 frag = dom.createDocumentFragment()
91 frag.appendChild(c1)
92 frag.appendChild(c2)
93 frag.appendChild(c3)
94 return dom, orig, c1, c2, c3, frag
95
96def testInsertBeforeFragment():
97 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
98 dom.documentElement.insertBefore(frag, None)
99 confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
100 "insertBefore(<fragment>, None)")
101 frag.unlink()
102 dom.unlink()
103 #
104 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
105 dom.documentElement.insertBefore(frag, orig)
106 confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig),
107 "insertBefore(<fragment>, orig)")
108 frag.unlink()
109 dom.unlink()
110
Paul Prescod7993bcc2000-07-01 14:54:16 +0000111def testAppendChild():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000112 dom = parse(tstfile)
113 dom.documentElement.appendChild(dom.createComment(u"Hello"))
114 confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
115 confirm(dom.documentElement.childNodes[-1].data == "Hello")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000116 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000117
Fred Drakee50959a2001-12-06 04:32:18 +0000118def testAppendChildFragment():
119 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
120 dom.documentElement.appendChild(frag)
121 confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
122 "appendChild(<fragment>)")
123 frag.unlink()
124 dom.unlink()
125
126def testReplaceChildFragment():
127 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
128 dom.documentElement.replaceChild(frag, orig)
129 orig.unlink()
130 confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
131 "replaceChild(<fragment>)")
132 frag.unlink()
133 dom.unlink()
134
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000135def testLegalChildren():
136 dom = Document()
137 elem = dom.createElement('element')
138 text = dom.createTextNode('text')
Fredrik Lundhf7850422001-01-17 21:51:36 +0000139
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000140 try: dom.appendChild(text)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000141 except xml.dom.HierarchyRequestErr: pass
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000142 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000143 print("dom.appendChild didn't raise HierarchyRequestErr")
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000144
145 dom.appendChild(elem)
146 try: dom.insertBefore(text, elem)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000147 except xml.dom.HierarchyRequestErr: pass
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000148 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000149 print("dom.appendChild didn't raise HierarchyRequestErr")
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000150
151 try: dom.replaceChild(text, elem)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000152 except xml.dom.HierarchyRequestErr: pass
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000153 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000154 print("dom.appendChild didn't raise HierarchyRequestErr")
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000155
Tim Peters0009c4e2001-02-21 07:29:48 +0000156 nodemap = elem.attributes
Andrew M. Kuchlingbc8f72c2001-02-21 01:30:26 +0000157 try: nodemap.setNamedItem(text)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000158 except xml.dom.HierarchyRequestErr: pass
Andrew M. Kuchlingbc8f72c2001-02-21 01:30:26 +0000159 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000160 print("NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr")
Andrew M. Kuchlingbc8f72c2001-02-21 01:30:26 +0000161
162 try: nodemap.setNamedItemNS(text)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000163 except xml.dom.HierarchyRequestErr: pass
Andrew M. Kuchlingbc8f72c2001-02-21 01:30:26 +0000164 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000165 print("NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr")
Andrew M. Kuchlingbc8f72c2001-02-21 01:30:26 +0000166
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000167 elem.appendChild(text)
Fredrik Lundhf7850422001-01-17 21:51:36 +0000168 dom.unlink()
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000169
Fred Drake2998a552001-12-06 18:27:48 +0000170def testNamedNodeMapSetItem():
171 dom = Document()
172 elem = dom.createElement('element')
173 attrs = elem.attributes
174 attrs["foo"] = "bar"
175 a = attrs.item(0)
176 confirm(a.ownerDocument is dom,
177 "NamedNodeMap.__setitem__() sets ownerDocument")
178 confirm(a.ownerElement is elem,
179 "NamedNodeMap.__setitem__() sets ownerElement")
180 confirm(a.value == "bar",
181 "NamedNodeMap.__setitem__() sets value")
182 confirm(a.nodeValue == "bar",
183 "NamedNodeMap.__setitem__() sets nodeValue")
184 elem.unlink()
185 dom.unlink()
186
Paul Prescod7993bcc2000-07-01 14:54:16 +0000187def testNonZero():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000188 dom = parse(tstfile)
189 confirm(dom)# should not be zero
190 dom.appendChild(dom.createComment("foo"))
191 confirm(not dom.childNodes[-1].childNodes)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000192 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000193
194def testUnlink():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000195 dom = parse(tstfile)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000196 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000197
198def testElement():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000199 dom = Document()
200 dom.appendChild(dom.createElement("abc"))
201 confirm(dom.documentElement)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000202 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000203
204def testAAA():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000205 dom = parseString("<abc/>")
206 el = dom.documentElement
207 el.setAttribute("spam", "jam2")
Fred Drakea1bde802000-11-21 22:02:43 +0000208 confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
Fred Drake2998a552001-12-06 18:27:48 +0000209 a = el.getAttributeNode("spam")
210 confirm(a.ownerDocument is dom,
211 "setAttribute() sets ownerDocument")
212 confirm(a.ownerElement is dom.documentElement,
213 "setAttribute() sets ownerElement")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000214 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000215
216def testAAB():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000217 dom = parseString("<abc/>")
218 el = dom.documentElement
219 el.setAttribute("spam", "jam")
220 el.setAttribute("spam", "jam2")
Fred Drakea1bde802000-11-21 22:02:43 +0000221 confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000222 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000223
224def testAddAttr():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000225 dom = Document()
226 child = dom.appendChild(dom.createElement("abc"))
Paul Prescod7993bcc2000-07-01 14:54:16 +0000227
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000228 child.setAttribute("def", "ghi")
229 confirm(child.getAttribute("def") == "ghi")
230 confirm(child.attributes["def"].value == "ghi")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000231
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000232 child.setAttribute("jkl", "mno")
233 confirm(child.getAttribute("jkl") == "mno")
234 confirm(child.attributes["jkl"].value == "mno")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000235
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000236 confirm(len(child.attributes) == 2)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000237
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000238 child.setAttribute("def", "newval")
239 confirm(child.getAttribute("def") == "newval")
240 confirm(child.attributes["def"].value == "newval")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000241
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000242 confirm(len(child.attributes) == 2)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000243 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000244
245def testDeleteAttr():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000246 dom = Document()
247 child = dom.appendChild(dom.createElement("abc"))
Paul Prescod7993bcc2000-07-01 14:54:16 +0000248
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000249 confirm(len(child.attributes) == 0)
250 child.setAttribute("def", "ghi")
251 confirm(len(child.attributes) == 1)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000252 del child.attributes["def"]
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000253 confirm(len(child.attributes) == 0)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000254 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000255
256def testRemoveAttr():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000257 dom = Document()
258 child = dom.appendChild(dom.createElement("abc"))
Paul Prescod7993bcc2000-07-01 14:54:16 +0000259
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000260 child.setAttribute("def", "ghi")
261 confirm(len(child.attributes) == 1)
262 child.removeAttribute("def")
263 confirm(len(child.attributes) == 0)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000264
265 dom.unlink()
266
267def testRemoveAttrNS():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000268 dom = Document()
269 child = dom.appendChild(
270 dom.createElementNS("http://www.python.org", "python:abc"))
Fred Drake004d5e62000-10-23 17:22:08 +0000271 child.setAttributeNS("http://www.w3.org", "xmlns:python",
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000272 "http://www.python.org")
273 child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
274 confirm(len(child.attributes) == 2)
275 child.removeAttributeNS("http://www.python.org", "abcattr")
276 confirm(len(child.attributes) == 1)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000277
278 dom.unlink()
Fred Drake004d5e62000-10-23 17:22:08 +0000279
Paul Prescod7993bcc2000-07-01 14:54:16 +0000280def testRemoveAttributeNode():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000281 dom = Document()
282 child = dom.appendChild(dom.createElement("foo"))
283 child.setAttribute("spam", "jam")
284 confirm(len(child.attributes) == 1)
285 node = child.getAttributeNode("spam")
286 child.removeAttributeNode(node)
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000287 confirm(len(child.attributes) == 0
288 and child.getAttributeNode("spam") is None)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000289
290 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000291
292def testChangeAttr():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000293 dom = parseString("<abc/>")
294 el = dom.documentElement
295 el.setAttribute("spam", "jam")
296 confirm(len(el.attributes) == 1)
297 el.setAttribute("spam", "bam")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000298 # Set this attribute to be an ID and make sure that doesn't change
299 # when changing the value:
300 el.setIdAttribute("spam")
301 confirm(len(el.attributes) == 1
302 and el.attributes["spam"].value == "bam"
303 and el.attributes["spam"].nodeValue == "bam"
304 and el.getAttribute("spam") == "bam"
305 and el.getAttributeNode("spam").isId)
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000306 el.attributes["spam"] = "ham"
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000307 confirm(len(el.attributes) == 1
308 and el.attributes["spam"].value == "ham"
309 and el.attributes["spam"].nodeValue == "ham"
310 and el.getAttribute("spam") == "ham"
311 and el.attributes["spam"].isId)
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000312 el.setAttribute("spam2", "bam")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000313 confirm(len(el.attributes) == 2
314 and el.attributes["spam"].value == "ham"
315 and el.attributes["spam"].nodeValue == "ham"
316 and el.getAttribute("spam") == "ham"
317 and el.attributes["spam2"].value == "bam"
318 and el.attributes["spam2"].nodeValue == "bam"
319 and el.getAttribute("spam2") == "bam")
320 el.attributes["spam2"] = "bam2"
321 confirm(len(el.attributes) == 2
322 and el.attributes["spam"].value == "ham"
323 and el.attributes["spam"].nodeValue == "ham"
324 and el.getAttribute("spam") == "ham"
325 and el.attributes["spam2"].value == "bam2"
326 and el.attributes["spam2"].nodeValue == "bam2"
327 and el.getAttribute("spam2") == "bam2")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000328 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000329
330def testGetAttrList():
331 pass
332
333def testGetAttrValues(): pass
334
335def testGetAttrLength(): pass
336
337def testGetAttribute(): pass
338
339def testGetAttributeNS(): pass
340
341def testGetAttributeNode(): pass
342
Martin v. Löwis351c3d02001-06-03 14:27:02 +0000343def testGetElementsByTagNameNS():
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000344 d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
Martin v. Löwis351c3d02001-06-03 14:27:02 +0000345 <minidom:myelem/>
346 </foo>"""
347 dom = parseString(d)
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000348 elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom", "myelem")
349 confirm(len(elems) == 1
350 and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
351 and elems[0].localName == "myelem"
352 and elems[0].prefix == "minidom"
353 and elems[0].tagName == "minidom:myelem"
354 and elems[0].nodeName == "minidom:myelem")
Martin v. Löwis351c3d02001-06-03 14:27:02 +0000355 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000356
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000357def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc, nsuri, lname):
358 nodelist = doc.getElementsByTagNameNS(nsuri, lname)
359 confirm(len(nodelist) == 0)
360
361def testGetEmptyNodeListFromElementsByTagNameNS():
362 doc = parseString('<doc/>')
363 get_empty_nodelist_from_elements_by_tagName_ns_helper(
364 doc, 'http://xml.python.org/namespaces/a', 'localname')
365 get_empty_nodelist_from_elements_by_tagName_ns_helper(
366 doc, '*', 'splat')
367 get_empty_nodelist_from_elements_by_tagName_ns_helper(
368 doc, 'http://xml.python.org/namespaces/a', '*')
369
370 doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
371 get_empty_nodelist_from_elements_by_tagName_ns_helper(
372 doc, "http://xml.python.org/splat", "not-there")
373 get_empty_nodelist_from_elements_by_tagName_ns_helper(
374 doc, "*", "not-there")
375 get_empty_nodelist_from_elements_by_tagName_ns_helper(
376 doc, "http://somewhere.else.net/not-there", "e")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000377
378def testElementReprAndStr():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000379 dom = Document()
380 el = dom.appendChild(dom.createElement("abc"))
381 string1 = repr(el)
382 string2 = str(el)
383 confirm(string1 == string2)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000384 dom.unlink()
385
386# commented out until Fredrick's fix is checked in
387def _testElementReprAndStrUnicode():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000388 dom = Document()
389 el = dom.appendChild(dom.createElement(u"abc"))
390 string1 = repr(el)
391 string2 = str(el)
392 confirm(string1 == string2)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000393 dom.unlink()
394
395# commented out until Fredrick's fix is checked in
396def _testElementReprAndStrUnicodeNS():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000397 dom = Document()
398 el = dom.appendChild(
399 dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
400 string1 = repr(el)
401 string2 = str(el)
402 confirm(string1 == string2)
403 confirm(string1.find("slash:abc") != -1)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000404 dom.unlink()
405
406def testAttributeRepr():
Jeremy Hylton3b0c6002000-10-12 17:31:36 +0000407 dom = Document()
408 el = dom.appendChild(dom.createElement(u"abc"))
409 node = el.setAttribute("abc", "def")
410 confirm(str(node) == repr(node))
Paul Prescod7993bcc2000-07-01 14:54:16 +0000411 dom.unlink()
412
413def testTextNodeRepr(): pass
414
Martin v. Löwis0a84a332000-10-06 22:42:55 +0000415def testWriteXML():
Georg Brandl905a01a2005-08-25 22:14:15 +0000416 str = '<?xml version="1.0" ?><a b="c"/>'
Martin v. Löwis0a84a332000-10-06 22:42:55 +0000417 dom = parseString(str)
418 domstr = dom.toxml()
419 dom.unlink()
420 confirm(str == domstr)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000421
Georg Brandl905a01a2005-08-25 22:14:15 +0000422def testAltNewline():
423 str = '<?xml version="1.0" ?>\n<a b="c"/>\n'
424 dom = parseString(str)
425 domstr = dom.toprettyxml(newl="\r\n")
426 dom.unlink()
427 confirm(domstr == str.replace("\n", "\r\n"))
428
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000429def testProcessingInstruction():
430 dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
431 pi = dom.documentElement.firstChild
432 confirm(pi.target == "mypi"
433 and pi.data == "data \t\n "
434 and pi.nodeName == "mypi"
435 and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
436 and pi.attributes is None
437 and not pi.hasChildNodes()
438 and len(pi.childNodes) == 0
439 and pi.firstChild is None
440 and pi.lastChild is None
441 and pi.localName is None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000442 and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000443
444def testProcessingInstructionRepr(): pass
445
446def testTextRepr(): pass
447
448def testWriteText(): pass
449
450def testDocumentElement(): pass
451
Fred Drakea1bde802000-11-21 22:02:43 +0000452def testTooManyDocumentElements():
453 doc = parseString("<doc/>")
454 elem = doc.createElement("extra")
455 try:
456 doc.appendChild(elem)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000457 except xml.dom.HierarchyRequestErr:
Fred Drakec441f7b2002-07-19 22:16:41 +0000458 pass
Fred Drakea1bde802000-11-21 22:02:43 +0000459 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000460 print("Failed to catch expected exception when" \
461 " adding extra document element.")
Fred Drakea1bde802000-11-21 22:02:43 +0000462 elem.unlink()
463 doc.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000464
465def testCreateElementNS(): pass
466
Andrew M. Kuchlingad4a5582000-12-31 04:03:27 +0000467def testCreateAttributeNS(): pass
Paul Prescod7993bcc2000-07-01 14:54:16 +0000468
469def testParse(): pass
470
471def testParseString(): pass
472
473def testComment(): pass
474
475def testAttrListItem(): pass
476
477def testAttrListItems(): pass
478
479def testAttrListItemNS(): pass
480
481def testAttrListKeys(): pass
482
483def testAttrListKeysNS(): pass
484
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000485def testRemoveNamedItem():
486 doc = parseString("<doc a=''/>")
487 e = doc.documentElement
488 attrs = e.attributes
489 a1 = e.getAttributeNode("a")
490 a2 = attrs.removeNamedItem("a")
491 confirm(a1.isSameNode(a2))
492 try:
493 attrs.removeNamedItem("a")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000494 except xml.dom.NotFoundErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000495 pass
496
497def testRemoveNamedItemNS():
498 doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
499 e = doc.documentElement
500 attrs = e.attributes
501 a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
502 a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
503 confirm(a1.isSameNode(a2))
504 try:
505 attrs.removeNamedItemNS("http://xml.python.org/", "b")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000506 except xml.dom.NotFoundErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000507 pass
508
Paul Prescod7993bcc2000-07-01 14:54:16 +0000509def testAttrListValues(): pass
510
511def testAttrListLength(): pass
512
513def testAttrList__getitem__(): pass
514
515def testAttrList__setitem__(): pass
516
517def testSetAttrValueandNodeValue(): pass
518
519def testParseElement(): pass
520
521def testParseAttributes(): pass
522
523def testParseElementNamespaces(): pass
524
525def testParseAttributeNamespaces(): pass
526
527def testParseProcessingInstructions(): pass
528
529def testChildNodes(): pass
530
531def testFirstChild(): pass
532
533def testHasChildNodes(): pass
534
Fred Drakea1bde802000-11-21 22:02:43 +0000535def testCloneElementShallow():
536 dom, clone = _setupCloneElement(0)
537 confirm(len(clone.childNodes) == 0
Fred Drake946f7b12001-09-28 20:31:50 +0000538 and clone.childNodes.length == 0
Fred Drakea1bde802000-11-21 22:02:43 +0000539 and clone.parentNode is None
540 and clone.toxml() == '<doc attr="value"/>'
541 , "testCloneElementShallow")
542 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000543
Fred Drakea1bde802000-11-21 22:02:43 +0000544def testCloneElementDeep():
545 dom, clone = _setupCloneElement(1)
546 confirm(len(clone.childNodes) == 1
Fred Drake946f7b12001-09-28 20:31:50 +0000547 and clone.childNodes.length == 1
Fred Drakea1bde802000-11-21 22:02:43 +0000548 and clone.parentNode is None
549 and clone.toxml() == '<doc attr="value"><foo/></doc>'
550 , "testCloneElementDeep")
551 dom.unlink()
Paul Prescod7993bcc2000-07-01 14:54:16 +0000552
Fred Drakea1bde802000-11-21 22:02:43 +0000553def _setupCloneElement(deep):
554 dom = parseString("<doc attr='value'><foo/></doc>")
555 root = dom.documentElement
556 clone = root.cloneNode(deep)
557 _testCloneElementCopiesAttributes(
558 root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
559 # mutilate the original so shared data is detected
560 root.tagName = root.nodeName = "MODIFIED"
561 root.setAttribute("attr", "NEW VALUE")
562 root.setAttribute("added", "VALUE")
563 return dom, clone
564
565def _testCloneElementCopiesAttributes(e1, e2, test):
566 attrs1 = e1.attributes
567 attrs2 = e2.attributes
Brett Cannon861fd6f2007-02-21 22:05:37 +0000568 keys1 = sorted(attrs1.keys())
569 keys2 = sorted(attrs2.keys())
Fred Drakea1bde802000-11-21 22:02:43 +0000570 confirm(keys1 == keys2, "clone of element has same attribute keys")
571 for i in range(len(keys1)):
572 a1 = attrs1.item(i)
573 a2 = attrs2.item(i)
574 confirm(a1 is not a2
575 and a1.value == a2.value
576 and a1.nodeValue == a2.nodeValue
577 and a1.namespaceURI == a2.namespaceURI
578 and a1.localName == a2.localName
579 , "clone of attribute node has proper attribute values")
580 confirm(a2.ownerElement is e2,
581 "clone of attribute node correctly owned")
Fredrik Lundhf7850422001-01-17 21:51:36 +0000582
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000583def testCloneDocumentShallow():
584 doc = parseString("<?xml version='1.0'?>\n"
585 "<!-- comment -->"
586 "<!DOCTYPE doc [\n"
587 "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
588 "]>\n"
589 "<doc attr='value'/>")
590 doc2 = doc.cloneNode(0)
591 confirm(doc2 is None,
592 "testCloneDocumentShallow:"
593 " shallow cloning of documents makes no sense!")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000594
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000595def testCloneDocumentDeep():
596 doc = parseString("<?xml version='1.0'?>\n"
597 "<!-- comment -->"
598 "<!DOCTYPE doc [\n"
599 "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
600 "]>\n"
601 "<doc attr='value'/>")
602 doc2 = doc.cloneNode(1)
603 confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
604 "testCloneDocumentDeep: document objects not distinct")
605 confirm(len(doc.childNodes) == len(doc2.childNodes),
606 "testCloneDocumentDeep: wrong number of Document children")
607 confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
608 "testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
609 confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
610 "testCloneDocumentDeep: documentElement owner is not new document")
611 confirm(not doc.documentElement.isSameNode(doc2.documentElement),
612 "testCloneDocumentDeep: documentElement should not be shared")
613 if doc.doctype is not None:
614 # check the doctype iff the original DOM maintained it
615 confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
616 "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
617 confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
618 confirm(not doc.doctype.isSameNode(doc2.doctype))
Paul Prescod7993bcc2000-07-01 14:54:16 +0000619
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000620def testCloneDocumentTypeDeepOk():
621 doctype = create_nonempty_doctype()
622 clone = doctype.cloneNode(1)
623 confirm(clone is not None
624 and clone.nodeName == doctype.nodeName
625 and clone.name == doctype.name
626 and clone.publicId == doctype.publicId
627 and clone.systemId == doctype.systemId
628 and len(clone.entities) == len(doctype.entities)
629 and clone.entities.item(len(clone.entities)) is None
630 and len(clone.notations) == len(doctype.notations)
631 and clone.notations.item(len(clone.notations)) is None
632 and len(clone.childNodes) == 0)
633 for i in range(len(doctype.entities)):
634 se = doctype.entities.item(i)
635 ce = clone.entities.item(i)
636 confirm((not se.isSameNode(ce))
637 and (not ce.isSameNode(se))
638 and ce.nodeName == se.nodeName
639 and ce.notationName == se.notationName
640 and ce.publicId == se.publicId
641 and ce.systemId == se.systemId
642 and ce.encoding == se.encoding
643 and ce.actualEncoding == se.actualEncoding
644 and ce.version == se.version)
645 for i in range(len(doctype.notations)):
646 sn = doctype.notations.item(i)
647 cn = clone.notations.item(i)
648 confirm((not sn.isSameNode(cn))
649 and (not cn.isSameNode(sn))
650 and cn.nodeName == sn.nodeName
651 and cn.publicId == sn.publicId
652 and cn.systemId == sn.systemId)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000653
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000654def testCloneDocumentTypeDeepNotOk():
655 doc = create_doc_with_doctype()
656 clone = doc.doctype.cloneNode(1)
657 confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000658
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000659def testCloneDocumentTypeShallowOk():
660 doctype = create_nonempty_doctype()
661 clone = doctype.cloneNode(0)
662 confirm(clone is not None
663 and clone.nodeName == doctype.nodeName
664 and clone.name == doctype.name
665 and clone.publicId == doctype.publicId
666 and clone.systemId == doctype.systemId
667 and len(clone.entities) == 0
668 and clone.entities.item(0) is None
669 and len(clone.notations) == 0
670 and clone.notations.item(0) is None
671 and len(clone.childNodes) == 0)
Paul Prescod7993bcc2000-07-01 14:54:16 +0000672
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000673def testCloneDocumentTypeShallowNotOk():
674 doc = create_doc_with_doctype()
675 clone = doc.doctype.cloneNode(0)
676 confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000677
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000678def check_import_document(deep, testName):
679 doc1 = parseString("<doc/>")
680 doc2 = parseString("<doc/>")
681 try:
682 doc1.importNode(doc2, deep)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000683 except xml.dom.NotSupportedErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000684 pass
685 else:
686 raise Exception(testName +
687 ": expected NotSupportedErr when importing a document")
688
689def testImportDocumentShallow():
690 check_import_document(0, "testImportDocumentShallow")
691
692def testImportDocumentDeep():
693 check_import_document(1, "testImportDocumentDeep")
694
695# The tests of DocumentType importing use these helpers to construct
696# the documents to work with, since not all DOM builders actually
697# create the DocumentType nodes.
698
699def create_doc_without_doctype(doctype=None):
700 return getDOMImplementation().createDocument(None, "doc", doctype)
701
702def create_nonempty_doctype():
703 doctype = getDOMImplementation().createDocumentType("doc", None, None)
704 doctype.entities._seq = []
705 doctype.notations._seq = []
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000706 notation = xml.dom.minidom.Notation("my-notation", None,
707 "http://xml.python.org/notations/my")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000708 doctype.notations._seq.append(notation)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000709 entity = xml.dom.minidom.Entity("my-entity", None,
710 "http://xml.python.org/entities/my",
711 "my-notation")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000712 entity.version = "1.0"
713 entity.encoding = "utf-8"
714 entity.actualEncoding = "us-ascii"
715 doctype.entities._seq.append(entity)
716 return doctype
717
718def create_doc_with_doctype():
719 doctype = create_nonempty_doctype()
720 doc = create_doc_without_doctype(doctype)
721 doctype.entities.item(0).ownerDocument = doc
722 doctype.notations.item(0).ownerDocument = doc
723 return doc
724
725def testImportDocumentTypeShallow():
726 src = create_doc_with_doctype()
727 target = create_doc_without_doctype()
728 try:
729 imported = target.importNode(src.doctype, 0)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000730 except xml.dom.NotSupportedErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000731 pass
732 else:
733 raise Exception(
734 "testImportDocumentTypeShallow: expected NotSupportedErr")
735
736def testImportDocumentTypeDeep():
737 src = create_doc_with_doctype()
738 target = create_doc_without_doctype()
739 try:
740 imported = target.importNode(src.doctype, 1)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000741 except xml.dom.NotSupportedErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000742 pass
743 else:
744 raise Exception(
745 "testImportDocumentTypeDeep: expected NotSupportedErr")
746
747# Testing attribute clones uses a helper, and should always be deep,
748# even if the argument to cloneNode is false.
749def check_clone_attribute(deep, testName):
750 doc = parseString("<doc attr='value'/>")
751 attr = doc.documentElement.getAttributeNode("attr")
752 assert attr is not None
753 clone = attr.cloneNode(deep)
754 confirm(not clone.isSameNode(attr))
755 confirm(not attr.isSameNode(clone))
756 confirm(clone.ownerElement is None,
757 testName + ": ownerElement should be None")
758 confirm(clone.ownerDocument.isSameNode(attr.ownerDocument),
759 testName + ": ownerDocument does not match")
760 confirm(clone.specified,
761 testName + ": cloned attribute must have specified == True")
762
763def testCloneAttributeShallow():
764 check_clone_attribute(0, "testCloneAttributeShallow")
765
766def testCloneAttributeDeep():
767 check_clone_attribute(1, "testCloneAttributeDeep")
768
769def check_clone_pi(deep, testName):
770 doc = parseString("<?target data?><doc/>")
771 pi = doc.firstChild
772 assert pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
773 clone = pi.cloneNode(deep)
774 confirm(clone.target == pi.target
775 and clone.data == pi.data)
776
777def testClonePIShallow():
778 check_clone_pi(0, "testClonePIShallow")
779
780def testClonePIDeep():
781 check_clone_pi(1, "testClonePIDeep")
Paul Prescod7993bcc2000-07-01 14:54:16 +0000782
Fred Drakea1bde802000-11-21 22:02:43 +0000783def testNormalize():
784 doc = parseString("<doc/>")
785 root = doc.documentElement
786 root.appendChild(doc.createTextNode("first"))
787 root.appendChild(doc.createTextNode("second"))
Fred Drake946f7b12001-09-28 20:31:50 +0000788 confirm(len(root.childNodes) == 2
789 and root.childNodes.length == 2, "testNormalize -- preparation")
Fred Drakea1bde802000-11-21 22:02:43 +0000790 doc.normalize()
791 confirm(len(root.childNodes) == 1
Fred Drake946f7b12001-09-28 20:31:50 +0000792 and root.childNodes.length == 1
Fred Drakea1bde802000-11-21 22:02:43 +0000793 and root.firstChild is root.lastChild
794 and root.firstChild.data == "firstsecond"
795 , "testNormalize -- result")
796 doc.unlink()
797
Fred Drake3277da02000-12-14 18:20:22 +0000798 doc = parseString("<doc/>")
799 root = doc.documentElement
800 root.appendChild(doc.createTextNode(""))
801 doc.normalize()
Fred Drake946f7b12001-09-28 20:31:50 +0000802 confirm(len(root.childNodes) == 0
803 and root.childNodes.length == 0,
Fred Drake3277da02000-12-14 18:20:22 +0000804 "testNormalize -- single empty node removed")
805 doc.unlink()
806
Lars Gustäbelf27f5ab2000-10-11 22:36:00 +0000807def testSiblings():
808 doc = parseString("<doc><?pi?>text?<elm/></doc>")
809 root = doc.documentElement
810 (pi, text, elm) = root.childNodes
Paul Prescod7993bcc2000-07-01 14:54:16 +0000811
Fred Drake004d5e62000-10-23 17:22:08 +0000812 confirm(pi.nextSibling is text and
813 pi.previousSibling is None and
814 text.nextSibling is elm and
815 text.previousSibling is pi and
816 elm.nextSibling is None and
Lars Gustäbelf27f5ab2000-10-11 22:36:00 +0000817 elm.previousSibling is text, "testSiblings")
818
819 doc.unlink()
820
821def testParents():
822 doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
823 root = doc.documentElement
824 elm1 = root.childNodes[0]
825 (elm2a, elm2b) = elm1.childNodes
826 elm3 = elm2b.childNodes[0]
827
828 confirm(root.parentNode is doc and
829 elm1.parentNode is root and
830 elm2a.parentNode is elm1 and
831 elm2b.parentNode is elm1 and
832 elm3.parentNode is elm2b, "testParents")
833
834 doc.unlink()
835
Fred Drake946f7b12001-09-28 20:31:50 +0000836def testNodeListItem():
837 doc = parseString("<doc><e/><e/></doc>")
838 children = doc.childNodes
839 docelem = children[0]
840 confirm(children[0] is children.item(0)
841 and children.item(1) is None
842 and docelem.childNodes.item(0) is docelem.childNodes[0]
843 and docelem.childNodes.item(1) is docelem.childNodes[1]
844 and docelem.childNodes.item(0).childNodes.item(0) is None,
845 "test NodeList.item()")
846 doc.unlink()
847
Lars Gustäbel5bad5a42000-10-13 20:54:10 +0000848def testSAX2DOM():
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000849 from xml.dom import pulldom
Lars Gustäbelf27f5ab2000-10-11 22:36:00 +0000850
Lars Gustäbel5bad5a42000-10-13 20:54:10 +0000851 sax2dom = pulldom.SAX2DOM()
852 sax2dom.startDocument()
853 sax2dom.startElement("doc", {})
854 sax2dom.characters("text")
855 sax2dom.startElement("subelm", {})
856 sax2dom.characters("text")
857 sax2dom.endElement("subelm")
Fred Drake004d5e62000-10-23 17:22:08 +0000858 sax2dom.characters("text")
Lars Gustäbel5bad5a42000-10-13 20:54:10 +0000859 sax2dom.endElement("doc")
860 sax2dom.endDocument()
Lars Gustäbelf27f5ab2000-10-11 22:36:00 +0000861
Lars Gustäbel5bad5a42000-10-13 20:54:10 +0000862 doc = sax2dom.document
Lars Gustäbelf27f5ab2000-10-11 22:36:00 +0000863 root = doc.documentElement
864 (text1, elm1, text2) = root.childNodes
865 text3 = elm1.childNodes[0]
866
867 confirm(text1.previousSibling is None and
868 text1.nextSibling is elm1 and
869 elm1.previousSibling is text1 and
870 elm1.nextSibling is text2 and
871 text2.previousSibling is elm1 and
872 text2.nextSibling is None and
873 text3.previousSibling is None and
Lars Gustäbel5bad5a42000-10-13 20:54:10 +0000874 text3.nextSibling is None, "testSAX2DOM - siblings")
Lars Gustäbelf27f5ab2000-10-11 22:36:00 +0000875
876 confirm(root.parentNode is doc and
877 text1.parentNode is root and
878 elm1.parentNode is root and
879 text2.parentNode is root and
Lars Gustäbel5bad5a42000-10-13 20:54:10 +0000880 text3.parentNode is elm1, "testSAX2DOM - parents")
Fred Drake004d5e62000-10-23 17:22:08 +0000881
Lars Gustäbelf27f5ab2000-10-11 22:36:00 +0000882 doc.unlink()
883
Martin v. Löwis7d650ca2002-06-30 15:05:00 +0000884def testEncodings():
885 doc = parseString('<foo>&#x20ac;</foo>')
Georg Brandl905a01a2005-08-25 22:14:15 +0000886 confirm(doc.toxml() == u'<?xml version="1.0" ?><foo>\u20ac</foo>'
887 and doc.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?><foo>\xe2\x82\xac</foo>'
888 and doc.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?><foo>\xa4</foo>',
Martin v. Löwis7d650ca2002-06-30 15:05:00 +0000889 "testEncodings - encoding EURO SIGN")
Neal Norwitz484d9a42005-09-30 04:46:49 +0000890
891 # Verify that character decoding errors throw exceptions instead of crashing
892 try:
893 doc = parseString('<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
894 except UnicodeDecodeError:
895 pass
896 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000897 print('parsing with bad encoding should raise a UnicodeDecodeError')
Neal Norwitz484d9a42005-09-30 04:46:49 +0000898
Martin v. Löwis7d650ca2002-06-30 15:05:00 +0000899 doc.unlink()
900
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000901class UserDataHandler:
902 called = 0
903 def handle(self, operation, key, data, src, dst):
904 dst.setUserData(key, data + 1, self)
905 src.setUserData(key, None, None)
906 self.called = 1
907
908def testUserData():
909 dom = Document()
910 n = dom.createElement('e')
911 confirm(n.getUserData("foo") is None)
912 n.setUserData("foo", None, None)
913 confirm(n.getUserData("foo") is None)
914 n.setUserData("foo", 12, 12)
915 n.setUserData("bar", 13, 13)
916 confirm(n.getUserData("foo") == 12)
917 confirm(n.getUserData("bar") == 13)
918 n.setUserData("foo", None, None)
919 confirm(n.getUserData("foo") is None)
920 confirm(n.getUserData("bar") == 13)
921
922 handler = UserDataHandler()
923 n.setUserData("bar", 12, handler)
924 c = n.cloneNode(1)
925 confirm(handler.called
926 and n.getUserData("bar") is None
927 and c.getUserData("bar") == 13)
928 n.unlink()
929 c.unlink()
930 dom.unlink()
931
932def testRenameAttribute():
933 doc = parseString("<doc a='v'/>")
934 elem = doc.documentElement
935 attrmap = elem.attributes
936 attr = elem.attributes['a']
937
938 # Simple renaming
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000939 attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000940 confirm(attr.name == "b"
941 and attr.nodeName == "b"
942 and attr.localName is None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000943 and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000944 and attr.prefix is None
945 and attr.value == "v"
946 and elem.getAttributeNode("a") is None
947 and elem.getAttributeNode("b").isSameNode(attr)
948 and attrmap["b"].isSameNode(attr)
949 and attr.ownerDocument.isSameNode(doc)
950 and attr.ownerElement.isSameNode(elem))
951
952 # Rename to have a namespace, no prefix
953 attr = doc.renameNode(attr, "http://xml.python.org/ns", "c")
954 confirm(attr.name == "c"
955 and attr.nodeName == "c"
956 and attr.localName == "c"
957 and attr.namespaceURI == "http://xml.python.org/ns"
958 and attr.prefix is None
959 and attr.value == "v"
960 and elem.getAttributeNode("a") is None
961 and elem.getAttributeNode("b") is None
962 and elem.getAttributeNode("c").isSameNode(attr)
963 and elem.getAttributeNodeNS(
964 "http://xml.python.org/ns", "c").isSameNode(attr)
965 and attrmap["c"].isSameNode(attr)
966 and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr))
967
968 # Rename to have a namespace, with prefix
969 attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d")
970 confirm(attr.name == "p:d"
971 and attr.nodeName == "p:d"
972 and attr.localName == "d"
973 and attr.namespaceURI == "http://xml.python.org/ns2"
974 and attr.prefix == "p"
975 and attr.value == "v"
976 and elem.getAttributeNode("a") is None
977 and elem.getAttributeNode("b") is None
978 and elem.getAttributeNode("c") is None
979 and elem.getAttributeNodeNS(
980 "http://xml.python.org/ns", "c") is None
981 and elem.getAttributeNode("p:d").isSameNode(attr)
982 and elem.getAttributeNodeNS(
983 "http://xml.python.org/ns2", "d").isSameNode(attr)
984 and attrmap["p:d"].isSameNode(attr)
985 and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr))
986
987 # Rename back to a simple non-NS node
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000988 attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000989 confirm(attr.name == "e"
990 and attr.nodeName == "e"
991 and attr.localName is None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000992 and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +0000993 and attr.prefix is None
994 and attr.value == "v"
995 and elem.getAttributeNode("a") is None
996 and elem.getAttributeNode("b") is None
997 and elem.getAttributeNode("c") is None
998 and elem.getAttributeNode("p:d") is None
999 and elem.getAttributeNodeNS(
1000 "http://xml.python.org/ns", "c") is None
1001 and elem.getAttributeNode("e").isSameNode(attr)
1002 and attrmap["e"].isSameNode(attr))
1003
1004 try:
1005 doc.renameNode(attr, "http://xml.python.org/ns", "xmlns")
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001006 except xml.dom.NamespaceErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001007 pass
1008 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001009 print("expected NamespaceErr")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001010
1011 checkRenameNodeSharedConstraints(doc, attr)
1012 doc.unlink()
1013
1014def testRenameElement():
1015 doc = parseString("<doc/>")
1016 elem = doc.documentElement
1017
1018 # Simple renaming
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001019 elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001020 confirm(elem.tagName == "a"
1021 and elem.nodeName == "a"
1022 and elem.localName is None
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001023 and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001024 and elem.prefix is None
1025 and elem.ownerDocument.isSameNode(doc))
1026
1027 # Rename to have a namespace, no prefix
1028 elem = doc.renameNode(elem, "http://xml.python.org/ns", "b")
1029 confirm(elem.tagName == "b"
1030 and elem.nodeName == "b"
1031 and elem.localName == "b"
1032 and elem.namespaceURI == "http://xml.python.org/ns"
1033 and elem.prefix is None
1034 and elem.ownerDocument.isSameNode(doc))
1035
1036 # Rename to have a namespace, with prefix
1037 elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c")
1038 confirm(elem.tagName == "p:c"
1039 and elem.nodeName == "p:c"
1040 and elem.localName == "c"
1041 and elem.namespaceURI == "http://xml.python.org/ns2"
1042 and elem.prefix == "p"
1043 and elem.ownerDocument.isSameNode(doc))
1044
1045 # Rename back to a simple non-NS node
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001046 elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001047 confirm(elem.tagName == "d"
1048 and elem.nodeName == "d"
1049 and elem.localName is None
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001050 and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001051 and elem.prefix is None
1052 and elem.ownerDocument.isSameNode(doc))
1053
1054 checkRenameNodeSharedConstraints(doc, elem)
1055 doc.unlink()
1056
1057def checkRenameNodeSharedConstraints(doc, node):
1058 # Make sure illegal NS usage is detected:
1059 try:
1060 doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo")
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001061 except xml.dom.NamespaceErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001062 pass
1063 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001064 print("expected NamespaceErr")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001065
1066 doc2 = parseString("<doc/>")
1067 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001068 doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
1069 except xml.dom.WrongDocumentErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001070 pass
1071 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001072 print("expected WrongDocumentErr")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001073
1074def testRenameOther():
1075 # We have to create a comment node explicitly since not all DOM
1076 # builders used with minidom add comments to the DOM.
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001077 doc = xml.dom.minidom.getDOMImplementation().createDocument(
1078 xml.dom.EMPTY_NAMESPACE, "e", None)
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001079 node = doc.createComment("comment")
1080 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001081 doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
1082 except xml.dom.NotSupportedErr:
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001083 pass
1084 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001085 print("expected NotSupportedErr when renaming comment node")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001086 doc.unlink()
1087
1088def checkWholeText(node, s):
1089 t = node.wholeText
1090 confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
1091
1092def testWholeText():
1093 doc = parseString("<doc>a</doc>")
1094 elem = doc.documentElement
1095 text = elem.childNodes[0]
1096 assert text.nodeType == Node.TEXT_NODE
1097
1098 checkWholeText(text, "a")
1099 elem.appendChild(doc.createTextNode("b"))
1100 checkWholeText(text, "ab")
1101 elem.insertBefore(doc.createCDATASection("c"), text)
1102 checkWholeText(text, "cab")
1103
1104 # make sure we don't cross other nodes
1105 splitter = doc.createComment("comment")
1106 elem.appendChild(splitter)
1107 text2 = doc.createTextNode("d")
1108 elem.appendChild(text2)
1109 checkWholeText(text, "cab")
1110 checkWholeText(text2, "d")
1111
1112 x = doc.createElement("x")
1113 elem.replaceChild(x, splitter)
1114 splitter = x
1115 checkWholeText(text, "cab")
1116 checkWholeText(text2, "d")
1117
1118 x = doc.createProcessingInstruction("y", "z")
1119 elem.replaceChild(x, splitter)
1120 splitter = x
1121 checkWholeText(text, "cab")
1122 checkWholeText(text2, "d")
1123
1124 elem.removeChild(splitter)
1125 checkWholeText(text, "cabd")
1126 checkWholeText(text2, "cabd")
1127
Andrew M. Kuchling841d25e2005-11-22 19:03:16 +00001128def testPatch1094164 ():
1129 doc = parseString("<doc><e/></doc>")
1130 elem = doc.documentElement
1131 e = elem.firstChild
1132 confirm(e.parentNode is elem, "Before replaceChild()")
1133 # Check that replacing a child with itself leaves the tree unchanged
1134 elem.replaceChild(e, e)
1135 confirm(e.parentNode is elem, "After replaceChild()")
Tim Peters536cf992005-12-25 23:18:31 +00001136
1137
1138
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001139def testReplaceWholeText():
1140 def setup():
1141 doc = parseString("<doc>a<e/>d</doc>")
1142 elem = doc.documentElement
1143 text1 = elem.firstChild
1144 text2 = elem.lastChild
1145 splitter = text1.nextSibling
1146 elem.insertBefore(doc.createTextNode("b"), splitter)
1147 elem.insertBefore(doc.createCDATASection("c"), text1)
1148 return doc, elem, text1, splitter, text2
1149
1150 doc, elem, text1, splitter, text2 = setup()
1151 text = text1.replaceWholeText("new content")
1152 checkWholeText(text, "new content")
1153 checkWholeText(text2, "d")
1154 confirm(len(elem.childNodes) == 3)
1155
1156 doc, elem, text1, splitter, text2 = setup()
1157 text = text2.replaceWholeText("new content")
1158 checkWholeText(text, "new content")
1159 checkWholeText(text1, "cab")
1160 confirm(len(elem.childNodes) == 5)
1161
1162 doc, elem, text1, splitter, text2 = setup()
1163 text = text1.replaceWholeText("")
1164 checkWholeText(text2, "d")
1165 confirm(text is None
1166 and len(elem.childNodes) == 2)
1167
1168def testSchemaType():
1169 doc = parseString(
1170 "<!DOCTYPE doc [\n"
1171 " <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
1172 " <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
1173 " <!ATTLIST doc id ID #IMPLIED \n"
1174 " ref IDREF #IMPLIED \n"
1175 " refs IDREFS #IMPLIED \n"
1176 " enum (a|b) #IMPLIED \n"
1177 " ent ENTITY #IMPLIED \n"
1178 " ents ENTITIES #IMPLIED \n"
1179 " nm NMTOKEN #IMPLIED \n"
1180 " nms NMTOKENS #IMPLIED \n"
1181 " text CDATA #IMPLIED \n"
1182 " >\n"
1183 "]><doc id='name' notid='name' text='splat!' enum='b'"
1184 " ref='name' refs='name name' ent='e1' ents='e1 e2'"
1185 " nm='123' nms='123 abc' />")
1186 elem = doc.documentElement
1187 # We don't want to rely on any specific loader at this point, so
1188 # just make sure we can get to all the names, and that the
1189 # DTD-based namespace is right. The names can vary by loader
1190 # since each supports a different level of DTD information.
1191 t = elem.schemaType
1192 confirm(t.name is None
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001193 and t.namespace == xml.dom.EMPTY_NAMESPACE)
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001194 names = "id notid text enum ref refs ent ents nm nms".split()
1195 for name in names:
1196 a = elem.getAttributeNode(name)
1197 t = a.schemaType
1198 confirm(hasattr(t, "name")
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001199 and t.namespace == xml.dom.EMPTY_NAMESPACE)
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001200
1201def testSetIdAttribute():
1202 doc = parseString("<doc a1='v' a2='w'/>")
1203 e = doc.documentElement
1204 a1 = e.getAttributeNode("a1")
1205 a2 = e.getAttributeNode("a2")
1206 confirm(doc.getElementById("v") is None
1207 and not a1.isId
1208 and not a2.isId)
1209 e.setIdAttribute("a1")
1210 confirm(e.isSameNode(doc.getElementById("v"))
1211 and a1.isId
1212 and not a2.isId)
1213 e.setIdAttribute("a2")
1214 confirm(e.isSameNode(doc.getElementById("v"))
1215 and e.isSameNode(doc.getElementById("w"))
1216 and a1.isId
1217 and a2.isId)
1218 # replace the a1 node; the new node should *not* be an ID
1219 a3 = doc.createAttribute("a1")
1220 a3.value = "v"
1221 e.setAttributeNode(a3)
1222 confirm(doc.getElementById("v") is None
1223 and e.isSameNode(doc.getElementById("w"))
1224 and not a1.isId
1225 and a2.isId
1226 and not a3.isId)
Georg Brandl7eb4b7d2005-07-22 21:49:32 +00001227 # renaming an attribute should not affect its ID-ness:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001228 doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001229 confirm(e.isSameNode(doc.getElementById("w"))
1230 and a2.isId)
1231
1232def testSetIdAttributeNS():
1233 NS1 = "http://xml.python.org/ns1"
1234 NS2 = "http://xml.python.org/ns2"
1235 doc = parseString("<doc"
1236 " xmlns:ns1='" + NS1 + "'"
1237 " xmlns:ns2='" + NS2 + "'"
1238 " ns1:a1='v' ns2:a2='w'/>")
1239 e = doc.documentElement
1240 a1 = e.getAttributeNodeNS(NS1, "a1")
1241 a2 = e.getAttributeNodeNS(NS2, "a2")
1242 confirm(doc.getElementById("v") is None
1243 and not a1.isId
1244 and not a2.isId)
1245 e.setIdAttributeNS(NS1, "a1")
1246 confirm(e.isSameNode(doc.getElementById("v"))
1247 and a1.isId
1248 and not a2.isId)
1249 e.setIdAttributeNS(NS2, "a2")
1250 confirm(e.isSameNode(doc.getElementById("v"))
1251 and e.isSameNode(doc.getElementById("w"))
1252 and a1.isId
1253 and a2.isId)
1254 # replace the a1 node; the new node should *not* be an ID
1255 a3 = doc.createAttributeNS(NS1, "a1")
1256 a3.value = "v"
1257 e.setAttributeNode(a3)
1258 confirm(e.isSameNode(doc.getElementById("w")))
1259 confirm(not a1.isId)
1260 confirm(a2.isId)
1261 confirm(not a3.isId)
1262 confirm(doc.getElementById("v") is None)
Georg Brandl7eb4b7d2005-07-22 21:49:32 +00001263 # renaming an attribute should not affect its ID-ness:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001264 doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001265 confirm(e.isSameNode(doc.getElementById("w"))
1266 and a2.isId)
1267
1268def testSetIdAttributeNode():
1269 NS1 = "http://xml.python.org/ns1"
1270 NS2 = "http://xml.python.org/ns2"
1271 doc = parseString("<doc"
1272 " xmlns:ns1='" + NS1 + "'"
1273 " xmlns:ns2='" + NS2 + "'"
1274 " ns1:a1='v' ns2:a2='w'/>")
1275 e = doc.documentElement
1276 a1 = e.getAttributeNodeNS(NS1, "a1")
1277 a2 = e.getAttributeNodeNS(NS2, "a2")
1278 confirm(doc.getElementById("v") is None
1279 and not a1.isId
1280 and not a2.isId)
1281 e.setIdAttributeNode(a1)
1282 confirm(e.isSameNode(doc.getElementById("v"))
1283 and a1.isId
1284 and not a2.isId)
1285 e.setIdAttributeNode(a2)
1286 confirm(e.isSameNode(doc.getElementById("v"))
1287 and e.isSameNode(doc.getElementById("w"))
1288 and a1.isId
1289 and a2.isId)
1290 # replace the a1 node; the new node should *not* be an ID
1291 a3 = doc.createAttributeNS(NS1, "a1")
1292 a3.value = "v"
1293 e.setAttributeNode(a3)
1294 confirm(e.isSameNode(doc.getElementById("w")))
1295 confirm(not a1.isId)
1296 confirm(a2.isId)
1297 confirm(not a3.isId)
1298 confirm(doc.getElementById("v") is None)
Georg Brandl7eb4b7d2005-07-22 21:49:32 +00001299 # renaming an attribute should not affect its ID-ness:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001300 doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
Martin v. Löwisaa5af8d2003-01-25 21:39:09 +00001301 confirm(e.isSameNode(doc.getElementById("w"))
1302 and a2.isId)
1303
1304def testPickledDocument():
1305 doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
1306 "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
1307 " 'http://xml.python.org/system' [\n"
1308 " <!ELEMENT e EMPTY>\n"
1309 " <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
1310 "]><doc attr='value'> text\n"
1311 "<?pi sample?> <!-- comment --> <e/> </doc>")
1312 s = pickle.dumps(doc)
1313 doc2 = pickle.loads(s)
1314 stack = [(doc, doc2)]
1315 while stack:
1316 n1, n2 = stack.pop()
1317 confirm(n1.nodeType == n2.nodeType
1318 and len(n1.childNodes) == len(n2.childNodes)
1319 and n1.nodeName == n2.nodeName
1320 and not n1.isSameNode(n2)
1321 and not n2.isSameNode(n1))
1322 if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
1323 len(n1.entities)
1324 len(n2.entities)
1325 len(n1.notations)
1326 len(n2.notations)
1327 confirm(len(n1.entities) == len(n2.entities)
1328 and len(n1.notations) == len(n2.notations))
1329 for i in range(len(n1.notations)):
1330 no1 = n1.notations.item(i)
1331 no2 = n1.notations.item(i)
1332 confirm(no1.name == no2.name
1333 and no1.publicId == no2.publicId
1334 and no1.systemId == no2.systemId)
1335 statck.append((no1, no2))
1336 for i in range(len(n1.entities)):
1337 e1 = n1.entities.item(i)
1338 e2 = n2.entities.item(i)
1339 confirm(e1.notationName == e2.notationName
1340 and e1.publicId == e2.publicId
1341 and e1.systemId == e2.systemId)
1342 stack.append((e1, e2))
1343 if n1.nodeType != Node.DOCUMENT_NODE:
1344 confirm(n1.ownerDocument.isSameNode(doc)
1345 and n2.ownerDocument.isSameNode(doc2))
1346 for i in range(len(n1.childNodes)):
1347 stack.append((n1.childNodes[i], n2.childNodes[i]))
1348
1349
Lars Gustäbelf27f5ab2000-10-11 22:36:00 +00001350# --- MAIN PROGRAM
Fred Drake004d5e62000-10-23 17:22:08 +00001351
Brett Cannon861fd6f2007-02-21 22:05:37 +00001352names = sorted(globals().keys())
Paul Prescod10d27662000-09-18 19:07:26 +00001353
Fred Drakeacfb3f62001-02-01 18:11:29 +00001354failed = []
Paul Prescod10d27662000-09-18 19:07:26 +00001355
Fred Drake6dd7d072002-09-12 17:03:02 +00001356try:
1357 Node.allnodes
1358except AttributeError:
Martin v. Löwisfd6aaa12003-01-25 22:02:52 +00001359 # We don't actually have the minidom from the standard library,
Fred Drake6dd7d072002-09-12 17:03:02 +00001360 # but are picking up the PyXML version from site-packages.
1361 def check_allnodes():
1362 pass
1363else:
1364 def check_allnodes():
1365 confirm(len(Node.allnodes) == 0,
1366 "assertion: len(Node.allnodes) == 0")
1367 if len(Node.allnodes):
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001368 print("Garbage left over:")
Fred Drake6dd7d072002-09-12 17:03:02 +00001369 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001370 print(Node.allnodes.items()[0:10])
Fred Drake6dd7d072002-09-12 17:03:02 +00001371 else:
1372 # Don't print specific nodes if repeatable results
1373 # are needed
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001374 print(len(Node.allnodes))
Fred Drake6dd7d072002-09-12 17:03:02 +00001375 Node.allnodes = {}
1376
Paul Prescod7993bcc2000-07-01 14:54:16 +00001377for name in names:
Jeremy Hylton3b0c6002000-10-12 17:31:36 +00001378 if name.startswith("test"):
1379 func = globals()[name]
Paul Prescod7993bcc2000-07-01 14:54:16 +00001380 try:
1381 func()
Fred Drake6dd7d072002-09-12 17:03:02 +00001382 check_allnodes()
Fred Drakeacfb3f62001-02-01 18:11:29 +00001383 except:
1384 failed.append(name)
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001385 print("Test Failed: ", name)
Fred Drake1703cf62000-12-15 21:31:59 +00001386 sys.stdout.flush()
Jeremy Hylton3b0c6002000-10-12 17:31:36 +00001387 traceback.print_exception(*sys.exc_info())
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001388 print(repr(sys.exc_info()[1]))
Jeremy Hylton3b0c6002000-10-12 17:31:36 +00001389 Node.allnodes = {}
Paul Prescod10d27662000-09-18 19:07:26 +00001390
Fred Drakeacfb3f62001-02-01 18:11:29 +00001391if failed:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001392 print("\n\n\n**** Check for failures in these tests:")
Fred Drakeacfb3f62001-02-01 18:11:29 +00001393 for name in failed:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001394 print(" " + name)