1 # test for xml.dom.minidom
3 from xml
.dom
.minidom
import parse
, Node
, Document
, parseString
4 from xml
.dom
import HierarchyRequestErr
5 import xml
.parsers
.expat
10 from test_support
import verbose
12 if __name__
== "__main__":
16 tstfile
= os
.path
.join(os
.path
.dirname(base
), "test.xml")
19 def confirm(test
, testname
= "Test"):
21 print "Passed " + testname
23 print "Failed " + testname
28 def testParseFromFile():
29 from StringIO
import StringIO
30 dom
= parse(StringIO(open(tstfile
).read()))
32 confirm(isinstance(dom
,Document
))
34 def testGetElementsByTagName():
36 confirm(dom
.getElementsByTagName("LI") == \
37 dom
.documentElement
.getElementsByTagName("LI"))
40 def testInsertBefore():
41 dom
= parseString("<doc><foo/></doc>")
42 root
= dom
.documentElement
43 elem
= root
.childNodes
[0]
44 nelem
= dom
.createElement("element")
45 root
.insertBefore(nelem
, elem
)
46 confirm(len(root
.childNodes
) == 2
47 and root
.childNodes
[0] is nelem
48 and root
.childNodes
[1] is elem
49 and root
.firstChild
is nelem
50 and root
.lastChild
is elem
51 and root
.toxml() == "<doc><element/><foo/></doc>"
52 , "testInsertBefore -- node properly placed in tree")
53 nelem
= dom
.createElement("element")
54 root
.insertBefore(nelem
, None)
55 confirm(len(root
.childNodes
) == 3
56 and root
.childNodes
[1] is elem
57 and root
.childNodes
[2] is nelem
58 and root
.lastChild
is nelem
59 and nelem
.previousSibling
is elem
60 and root
.toxml() == "<doc><element/><foo/><element/></doc>"
61 , "testInsertBefore -- node properly placed in tree")
62 nelem2
= dom
.createElement("bar")
63 root
.insertBefore(nelem2
, nelem
)
64 confirm(len(root
.childNodes
) == 4
65 and root
.childNodes
[2] is nelem2
66 and root
.childNodes
[3] is nelem
67 and nelem2
.nextSibling
is nelem
68 and nelem
.previousSibling
is nelem2
69 and root
.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
70 , "testInsertBefore -- node properly placed in tree")
73 def testAppendChild():
75 dom
.documentElement
.appendChild(dom
.createComment(u
"Hello"))
76 confirm(dom
.documentElement
.childNodes
[-1].nodeName
== "#comment")
77 confirm(dom
.documentElement
.childNodes
[-1].data
== "Hello")
80 def testLegalChildren():
82 elem
= dom
.createElement('element')
83 text
= dom
.createTextNode('text')
85 try: dom
.appendChild(text
)
86 except HierarchyRequestErr
: pass
88 print "dom.appendChild didn't raise HierarchyRequestErr"
91 try: dom
.insertBefore(text
, elem
)
92 except HierarchyRequestErr
: pass
94 print "dom.appendChild didn't raise HierarchyRequestErr"
96 try: dom
.replaceChild(text
, elem
)
97 except HierarchyRequestErr
: pass
99 print "dom.appendChild didn't raise HierarchyRequestErr"
101 nodemap
= elem
.attributes
102 try: nodemap
.setNamedItem(text
)
103 except HierarchyRequestErr
: pass
105 print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
107 try: nodemap
.setNamedItemNS(text
)
108 except HierarchyRequestErr
: pass
110 print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
112 elem
.appendChild(text
)
117 confirm(dom
)# should not be zero
118 dom
.appendChild(dom
.createComment("foo"))
119 confirm(not dom
.childNodes
[-1].childNodes
)
128 dom
.appendChild(dom
.createElement("abc"))
129 confirm(dom
.documentElement
)
133 dom
= parseString("<abc/>")
134 el
= dom
.documentElement
135 el
.setAttribute("spam", "jam2")
136 confirm(el
.toxml() == '<abc spam="jam2"/>', "testAAA")
140 dom
= parseString("<abc/>")
141 el
= dom
.documentElement
142 el
.setAttribute("spam", "jam")
143 el
.setAttribute("spam", "jam2")
144 confirm(el
.toxml() == '<abc spam="jam2"/>', "testAAB")
149 child
= dom
.appendChild(dom
.createElement("abc"))
151 child
.setAttribute("def", "ghi")
152 confirm(child
.getAttribute("def") == "ghi")
153 confirm(child
.attributes
["def"].value
== "ghi")
155 child
.setAttribute("jkl", "mno")
156 confirm(child
.getAttribute("jkl") == "mno")
157 confirm(child
.attributes
["jkl"].value
== "mno")
159 confirm(len(child
.attributes
) == 2)
161 child
.setAttribute("def", "newval")
162 confirm(child
.getAttribute("def") == "newval")
163 confirm(child
.attributes
["def"].value
== "newval")
165 confirm(len(child
.attributes
) == 2)
168 def testDeleteAttr():
170 child
= dom
.appendChild(dom
.createElement("abc"))
172 confirm(len(child
.attributes
) == 0)
173 child
.setAttribute("def", "ghi")
174 confirm(len(child
.attributes
) == 1)
175 del child
.attributes
["def"]
176 confirm(len(child
.attributes
) == 0)
179 def testRemoveAttr():
181 child
= dom
.appendChild(dom
.createElement("abc"))
183 child
.setAttribute("def", "ghi")
184 confirm(len(child
.attributes
) == 1)
185 child
.removeAttribute("def")
186 confirm(len(child
.attributes
) == 0)
190 def testRemoveAttrNS():
192 child
= dom
.appendChild(
193 dom
.createElementNS("http://www.python.org", "python:abc"))
194 child
.setAttributeNS("http://www.w3.org", "xmlns:python",
195 "http://www.python.org")
196 child
.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
197 confirm(len(child
.attributes
) == 2)
198 child
.removeAttributeNS("http://www.python.org", "abcattr")
199 confirm(len(child
.attributes
) == 1)
203 def testRemoveAttributeNode():
205 child
= dom
.appendChild(dom
.createElement("foo"))
206 child
.setAttribute("spam", "jam")
207 confirm(len(child
.attributes
) == 1)
208 node
= child
.getAttributeNode("spam")
209 child
.removeAttributeNode(node
)
210 confirm(len(child
.attributes
) == 0)
214 def testChangeAttr():
215 dom
= parseString("<abc/>")
216 el
= dom
.documentElement
217 el
.setAttribute("spam", "jam")
218 confirm(len(el
.attributes
) == 1)
219 el
.setAttribute("spam", "bam")
220 confirm(len(el
.attributes
) == 1)
221 el
.attributes
["spam"] = "ham"
222 confirm(len(el
.attributes
) == 1)
223 el
.setAttribute("spam2", "bam")
224 confirm(len(el
.attributes
) == 2)
225 el
.attributes
[ "spam2"] = "bam2"
226 confirm(len(el
.attributes
) == 2)
229 def testGetAttrList():
232 def testGetAttrValues(): pass
234 def testGetAttrLength(): pass
236 def testGetAttribute(): pass
238 def testGetAttributeNS(): pass
240 def testGetAttributeNode(): pass
242 def testGetElementsByTagNameNS(): pass
244 def testGetEmptyNodeListFromElementsByTagNameNS(): pass
246 def testElementReprAndStr():
248 el
= dom
.appendChild(dom
.createElement("abc"))
251 confirm(string1
== string2
)
254 # commented out until Fredrick's fix is checked in
255 def _testElementReprAndStrUnicode():
257 el
= dom
.appendChild(dom
.createElement(u
"abc"))
260 confirm(string1
== string2
)
263 # commented out until Fredrick's fix is checked in
264 def _testElementReprAndStrUnicodeNS():
266 el
= dom
.appendChild(
267 dom
.createElementNS(u
"http://www.slashdot.org", u
"slash:abc"))
270 confirm(string1
== string2
)
271 confirm(string1
.find("slash:abc") != -1)
273 confirm(len(Node
.allnodes
) == 0)
275 def testAttributeRepr():
277 el
= dom
.appendChild(dom
.createElement(u
"abc"))
278 node
= el
.setAttribute("abc", "def")
279 confirm(str(node
) == repr(node
))
281 confirm(len(Node
.allnodes
) == 0)
283 def testTextNodeRepr(): pass
286 str = '<?xml version="1.0" ?>\n<a b="c"/>'
287 dom
= parseString(str)
290 confirm(str == domstr
)
291 confirm(len(Node
.allnodes
) == 0)
293 def testProcessingInstruction(): pass
295 def testProcessingInstructionRepr(): pass
297 def testTextRepr(): pass
299 def testWriteText(): pass
301 def testDocumentElement(): pass
303 def testTooManyDocumentElements():
304 doc
= parseString("<doc/>")
305 elem
= doc
.createElement("extra")
307 doc
.appendChild(elem
)
308 except HierarchyRequestErr
:
309 print "Caught expected exception when adding extra document element."
311 print "Failed to catch expected exception when" \
312 " adding extra document element."
316 def testCreateElementNS(): pass
318 def testCreateAttributeNS(): pass
320 def testParse(): pass
322 def testParseString(): pass
324 def testComment(): pass
326 def testAttrListItem(): pass
328 def testAttrListItems(): pass
330 def testAttrListItemNS(): pass
332 def testAttrListKeys(): pass
334 def testAttrListKeysNS(): pass
336 def testAttrListValues(): pass
338 def testAttrListLength(): pass
340 def testAttrList__getitem__(): pass
342 def testAttrList__setitem__(): pass
344 def testSetAttrValueandNodeValue(): pass
346 def testParseElement(): pass
348 def testParseAttributes(): pass
350 def testParseElementNamespaces(): pass
352 def testParseAttributeNamespaces(): pass
354 def testParseProcessingInstructions(): pass
356 def testChildNodes(): pass
358 def testFirstChild(): pass
360 def testHasChildNodes(): pass
362 def testCloneElementShallow():
363 dom
, clone
= _setupCloneElement(0)
364 confirm(len(clone
.childNodes
) == 0
365 and clone
.parentNode
is None
366 and clone
.toxml() == '<doc attr="value"/>'
367 , "testCloneElementShallow")
370 def testCloneElementDeep():
371 dom
, clone
= _setupCloneElement(1)
372 confirm(len(clone
.childNodes
) == 1
373 and clone
.parentNode
is None
374 and clone
.toxml() == '<doc attr="value"><foo/></doc>'
375 , "testCloneElementDeep")
378 def _setupCloneElement(deep
):
379 dom
= parseString("<doc attr='value'><foo/></doc>")
380 root
= dom
.documentElement
381 clone
= root
.cloneNode(deep
)
382 _testCloneElementCopiesAttributes(
383 root
, clone
, "testCloneElement" + (deep
and "Deep" or "Shallow"))
384 # mutilate the original so shared data is detected
385 root
.tagName
= root
.nodeName
= "MODIFIED"
386 root
.setAttribute("attr", "NEW VALUE")
387 root
.setAttribute("added", "VALUE")
390 def _testCloneElementCopiesAttributes(e1
, e2
, test
):
391 attrs1
= e1
.attributes
392 attrs2
= e2
.attributes
393 keys1
= attrs1
.keys()
394 keys2
= attrs2
.keys()
397 confirm(keys1
== keys2
, "clone of element has same attribute keys")
398 for i
in range(len(keys1
)):
402 and a1
.value
== a2
.value
403 and a1
.nodeValue
== a2
.nodeValue
404 and a1
.namespaceURI
== a2
.namespaceURI
405 and a1
.localName
== a2
.localName
406 , "clone of attribute node has proper attribute values")
407 confirm(a2
.ownerElement
is e2
,
408 "clone of attribute node correctly owned")
411 def testCloneDocumentShallow(): pass
413 def testCloneDocumentDeep(): pass
415 def testCloneAttributeShallow(): pass
417 def testCloneAttributeDeep(): pass
419 def testClonePIShallow(): pass
421 def testClonePIDeep(): pass
424 doc
= parseString("<doc/>")
425 root
= doc
.documentElement
426 root
.appendChild(doc
.createTextNode("first"))
427 root
.appendChild(doc
.createTextNode("second"))
428 confirm(len(root
.childNodes
) == 2, "testNormalize -- preparation")
430 confirm(len(root
.childNodes
) == 1
431 and root
.firstChild
is root
.lastChild
432 and root
.firstChild
.data
== "firstsecond"
433 , "testNormalize -- result")
436 doc
= parseString("<doc/>")
437 root
= doc
.documentElement
438 root
.appendChild(doc
.createTextNode(""))
440 confirm(len(root
.childNodes
) == 0,
441 "testNormalize -- single empty node removed")
445 doc
= parseString("<doc><?pi?>text?<elm/></doc>")
446 root
= doc
.documentElement
447 (pi
, text
, elm
) = root
.childNodes
449 confirm(pi
.nextSibling
is text
and
450 pi
.previousSibling
is None and
451 text
.nextSibling
is elm
and
452 text
.previousSibling
is pi
and
453 elm
.nextSibling
is None and
454 elm
.previousSibling
is text
, "testSiblings")
459 doc
= parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
460 root
= doc
.documentElement
461 elm1
= root
.childNodes
[0]
462 (elm2a
, elm2b
) = elm1
.childNodes
463 elm3
= elm2b
.childNodes
[0]
465 confirm(root
.parentNode
is doc
and
466 elm1
.parentNode
is root
and
467 elm2a
.parentNode
is elm1
and
468 elm2b
.parentNode
is elm1
and
469 elm3
.parentNode
is elm2b
, "testParents")
474 from xml
.dom
import pulldom
476 sax2dom
= pulldom
.SAX2DOM()
477 sax2dom
.startDocument()
478 sax2dom
.startElement("doc", {})
479 sax2dom
.characters("text")
480 sax2dom
.startElement("subelm", {})
481 sax2dom
.characters("text")
482 sax2dom
.endElement("subelm")
483 sax2dom
.characters("text")
484 sax2dom
.endElement("doc")
485 sax2dom
.endDocument()
487 doc
= sax2dom
.document
488 root
= doc
.documentElement
489 (text1
, elm1
, text2
) = root
.childNodes
490 text3
= elm1
.childNodes
[0]
492 confirm(text1
.previousSibling
is None and
493 text1
.nextSibling
is elm1
and
494 elm1
.previousSibling
is text1
and
495 elm1
.nextSibling
is text2
and
496 text2
.previousSibling
is elm1
and
497 text2
.nextSibling
is None and
498 text3
.previousSibling
is None and
499 text3
.nextSibling
is None, "testSAX2DOM - siblings")
501 confirm(root
.parentNode
is doc
and
502 text1
.parentNode
is root
and
503 elm1
.parentNode
is root
and
504 text2
.parentNode
is root
and
505 text3
.parentNode
is elm1
, "testSAX2DOM - parents")
511 names
= globals().keys()
517 if name
.startswith("test"):
518 func
= globals()[name
]
521 print "Test Succeeded", name
522 confirm(len(Node
.allnodes
) == 0,
523 "assertion: len(Node.allnodes) == 0")
524 if len(Node
.allnodes
):
525 print "Garbage left over:"
527 print Node
.allnodes
.items()[0:10]
529 # Don't print specific nodes if repeatable results
531 print len(Node
.allnodes
)
535 print "Test Failed: ", name
537 traceback
.print_exception(*sys
.exc_info())
538 print `sys
.exc_info()[1]`
542 print "\n\n\n**** Check for failures in these tests:"
547 print "All tests succeeded"
549 Node
.debug
= None # Delete debug output collected in a StringIO object
550 Node
._debug
= 0 # And reset debug mode