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"+os
.extsep
+"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
.length
== 2
48 and root
.childNodes
[0] is nelem
49 and root
.childNodes
.item(0) is nelem
50 and root
.childNodes
[1] is elem
51 and root
.childNodes
.item(1) is elem
52 and root
.firstChild
is nelem
53 and root
.lastChild
is elem
54 and root
.toxml() == "<doc><element/><foo/></doc>"
55 , "testInsertBefore -- node properly placed in tree")
56 nelem
= dom
.createElement("element")
57 root
.insertBefore(nelem
, None)
58 confirm(len(root
.childNodes
) == 3
59 and root
.childNodes
.length
== 3
60 and root
.childNodes
[1] is elem
61 and root
.childNodes
.item(1) is elem
62 and root
.childNodes
[2] is nelem
63 and root
.childNodes
.item(2) is nelem
64 and root
.lastChild
is nelem
65 and nelem
.previousSibling
is elem
66 and root
.toxml() == "<doc><element/><foo/><element/></doc>"
67 , "testInsertBefore -- node properly placed in tree")
68 nelem2
= dom
.createElement("bar")
69 root
.insertBefore(nelem2
, nelem
)
70 confirm(len(root
.childNodes
) == 4
71 and root
.childNodes
.length
== 4
72 and root
.childNodes
[2] is nelem2
73 and root
.childNodes
.item(2) is nelem2
74 and root
.childNodes
[3] is nelem
75 and root
.childNodes
.item(3) is nelem
76 and nelem2
.nextSibling
is nelem
77 and nelem
.previousSibling
is nelem2
78 and root
.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
79 , "testInsertBefore -- node properly placed in tree")
82 def _create_fragment_test_nodes():
83 dom
= parseString("<doc/>")
84 orig
= dom
.createTextNode("original")
85 c1
= dom
.createTextNode("foo")
86 c2
= dom
.createTextNode("bar")
87 c3
= dom
.createTextNode("bat")
88 dom
.documentElement
.appendChild(orig
)
89 frag
= dom
.createDocumentFragment()
93 return dom
, orig
, c1
, c2
, c3
, frag
95 def testInsertBeforeFragment():
96 dom
, orig
, c1
, c2
, c3
, frag
= _create_fragment_test_nodes()
97 dom
.documentElement
.insertBefore(frag
, None)
98 confirm(tuple(dom
.documentElement
.childNodes
) == (orig
, c1
, c2
, c3
),
99 "insertBefore(<fragment>, None)")
103 dom
, orig
, c1
, c2
, c3
, frag
= _create_fragment_test_nodes()
104 dom
.documentElement
.insertBefore(frag
, orig
)
105 confirm(tuple(dom
.documentElement
.childNodes
) == (c1
, c2
, c3
, orig
),
106 "insertBefore(<fragment>, orig)")
110 def testAppendChild():
112 dom
.documentElement
.appendChild(dom
.createComment(u
"Hello"))
113 confirm(dom
.documentElement
.childNodes
[-1].nodeName
== "#comment")
114 confirm(dom
.documentElement
.childNodes
[-1].data
== "Hello")
117 def testAppendChildFragment():
118 dom
, orig
, c1
, c2
, c3
, frag
= _create_fragment_test_nodes()
119 dom
.documentElement
.appendChild(frag
)
120 confirm(tuple(dom
.documentElement
.childNodes
) == (orig
, c1
, c2
, c3
),
121 "appendChild(<fragment>)")
125 def testReplaceChildFragment():
126 dom
, orig
, c1
, c2
, c3
, frag
= _create_fragment_test_nodes()
127 dom
.documentElement
.replaceChild(frag
, orig
)
129 confirm(tuple(dom
.documentElement
.childNodes
) == (c1
, c2
, c3
),
130 "replaceChild(<fragment>)")
134 def testLegalChildren():
136 elem
= dom
.createElement('element')
137 text
= dom
.createTextNode('text')
139 try: dom
.appendChild(text
)
140 except HierarchyRequestErr
: pass
142 print "dom.appendChild didn't raise HierarchyRequestErr"
144 dom
.appendChild(elem
)
145 try: dom
.insertBefore(text
, elem
)
146 except HierarchyRequestErr
: pass
148 print "dom.appendChild didn't raise HierarchyRequestErr"
150 try: dom
.replaceChild(text
, elem
)
151 except HierarchyRequestErr
: pass
153 print "dom.appendChild didn't raise HierarchyRequestErr"
155 nodemap
= elem
.attributes
156 try: nodemap
.setNamedItem(text
)
157 except HierarchyRequestErr
: pass
159 print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
161 try: nodemap
.setNamedItemNS(text
)
162 except HierarchyRequestErr
: pass
164 print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
166 elem
.appendChild(text
)
169 def testNamedNodeMapSetItem():
171 elem
= dom
.createElement('element')
172 attrs
= elem
.attributes
175 confirm(a
.ownerDocument
is dom
,
176 "NamedNodeMap.__setitem__() sets ownerDocument")
177 confirm(a
.ownerElement
is elem
,
178 "NamedNodeMap.__setitem__() sets ownerElement")
179 confirm(a
.value
== "bar",
180 "NamedNodeMap.__setitem__() sets value")
181 confirm(a
.nodeValue
== "bar",
182 "NamedNodeMap.__setitem__() sets nodeValue")
188 confirm(dom
)# should not be zero
189 dom
.appendChild(dom
.createComment("foo"))
190 confirm(not dom
.childNodes
[-1].childNodes
)
199 dom
.appendChild(dom
.createElement("abc"))
200 confirm(dom
.documentElement
)
204 dom
= parseString("<abc/>")
205 el
= dom
.documentElement
206 el
.setAttribute("spam", "jam2")
207 confirm(el
.toxml() == '<abc spam="jam2"/>', "testAAA")
208 a
= el
.getAttributeNode("spam")
209 confirm(a
.ownerDocument
is dom
,
210 "setAttribute() sets ownerDocument")
211 confirm(a
.ownerElement
is dom
.documentElement
,
212 "setAttribute() sets ownerElement")
216 dom
= parseString("<abc/>")
217 el
= dom
.documentElement
218 el
.setAttribute("spam", "jam")
219 el
.setAttribute("spam", "jam2")
220 confirm(el
.toxml() == '<abc spam="jam2"/>', "testAAB")
225 child
= dom
.appendChild(dom
.createElement("abc"))
227 child
.setAttribute("def", "ghi")
228 confirm(child
.getAttribute("def") == "ghi")
229 confirm(child
.attributes
["def"].value
== "ghi")
231 child
.setAttribute("jkl", "mno")
232 confirm(child
.getAttribute("jkl") == "mno")
233 confirm(child
.attributes
["jkl"].value
== "mno")
235 confirm(len(child
.attributes
) == 2)
237 child
.setAttribute("def", "newval")
238 confirm(child
.getAttribute("def") == "newval")
239 confirm(child
.attributes
["def"].value
== "newval")
241 confirm(len(child
.attributes
) == 2)
244 def testDeleteAttr():
246 child
= dom
.appendChild(dom
.createElement("abc"))
248 confirm(len(child
.attributes
) == 0)
249 child
.setAttribute("def", "ghi")
250 confirm(len(child
.attributes
) == 1)
251 del child
.attributes
["def"]
252 confirm(len(child
.attributes
) == 0)
255 def testRemoveAttr():
257 child
= dom
.appendChild(dom
.createElement("abc"))
259 child
.setAttribute("def", "ghi")
260 confirm(len(child
.attributes
) == 1)
261 child
.removeAttribute("def")
262 confirm(len(child
.attributes
) == 0)
266 def testRemoveAttrNS():
268 child
= dom
.appendChild(
269 dom
.createElementNS("http://www.python.org", "python:abc"))
270 child
.setAttributeNS("http://www.w3.org", "xmlns:python",
271 "http://www.python.org")
272 child
.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
273 confirm(len(child
.attributes
) == 2)
274 child
.removeAttributeNS("http://www.python.org", "abcattr")
275 confirm(len(child
.attributes
) == 1)
279 def testRemoveAttributeNode():
281 child
= dom
.appendChild(dom
.createElement("foo"))
282 child
.setAttribute("spam", "jam")
283 confirm(len(child
.attributes
) == 1)
284 node
= child
.getAttributeNode("spam")
285 child
.removeAttributeNode(node
)
286 confirm(len(child
.attributes
) == 0)
290 def testChangeAttr():
291 dom
= parseString("<abc/>")
292 el
= dom
.documentElement
293 el
.setAttribute("spam", "jam")
294 confirm(len(el
.attributes
) == 1)
295 el
.setAttribute("spam", "bam")
296 confirm(len(el
.attributes
) == 1)
297 el
.attributes
["spam"] = "ham"
298 confirm(len(el
.attributes
) == 1)
299 el
.setAttribute("spam2", "bam")
300 confirm(len(el
.attributes
) == 2)
301 el
.attributes
[ "spam2"] = "bam2"
302 confirm(len(el
.attributes
) == 2)
305 def testGetAttrList():
308 def testGetAttrValues(): pass
310 def testGetAttrLength(): pass
312 def testGetAttribute(): pass
314 def testGetAttributeNS(): pass
316 def testGetAttributeNode(): pass
318 def testGetElementsByTagNameNS():
319 d
="""<foo xmlns:minidom="http://pyxml.sf.net/minidom">
323 elem
= dom
.getElementsByTagNameNS("http://pyxml.sf.net/minidom","myelem")
324 confirm(len(elem
) == 1)
327 def testGetEmptyNodeListFromElementsByTagNameNS(): pass
329 def testElementReprAndStr():
331 el
= dom
.appendChild(dom
.createElement("abc"))
334 confirm(string1
== string2
)
337 # commented out until Fredrick's fix is checked in
338 def _testElementReprAndStrUnicode():
340 el
= dom
.appendChild(dom
.createElement(u
"abc"))
343 confirm(string1
== string2
)
346 # commented out until Fredrick's fix is checked in
347 def _testElementReprAndStrUnicodeNS():
349 el
= dom
.appendChild(
350 dom
.createElementNS(u
"http://www.slashdot.org", u
"slash:abc"))
353 confirm(string1
== string2
)
354 confirm(string1
.find("slash:abc") != -1)
356 confirm(len(Node
.allnodes
) == 0)
358 def testAttributeRepr():
360 el
= dom
.appendChild(dom
.createElement(u
"abc"))
361 node
= el
.setAttribute("abc", "def")
362 confirm(str(node
) == repr(node
))
364 confirm(len(Node
.allnodes
) == 0)
366 def testTextNodeRepr(): pass
369 str = '<?xml version="1.0" ?>\n<a b="c"/>'
370 dom
= parseString(str)
373 confirm(str == domstr
)
374 confirm(len(Node
.allnodes
) == 0)
376 def testProcessingInstruction(): pass
378 def testProcessingInstructionRepr(): pass
380 def testTextRepr(): pass
382 def testWriteText(): pass
384 def testDocumentElement(): pass
386 def testTooManyDocumentElements():
387 doc
= parseString("<doc/>")
388 elem
= doc
.createElement("extra")
390 doc
.appendChild(elem
)
391 except HierarchyRequestErr
:
392 print "Caught expected exception when adding extra document element."
394 print "Failed to catch expected exception when" \
395 " adding extra document element."
399 def testCreateElementNS(): pass
401 def testCreateAttributeNS(): pass
403 def testParse(): pass
405 def testParseString(): pass
407 def testComment(): pass
409 def testAttrListItem(): pass
411 def testAttrListItems(): pass
413 def testAttrListItemNS(): pass
415 def testAttrListKeys(): pass
417 def testAttrListKeysNS(): pass
419 def testAttrListValues(): pass
421 def testAttrListLength(): pass
423 def testAttrList__getitem__(): pass
425 def testAttrList__setitem__(): pass
427 def testSetAttrValueandNodeValue(): pass
429 def testParseElement(): pass
431 def testParseAttributes(): pass
433 def testParseElementNamespaces(): pass
435 def testParseAttributeNamespaces(): pass
437 def testParseProcessingInstructions(): pass
439 def testChildNodes(): pass
441 def testFirstChild(): pass
443 def testHasChildNodes(): pass
445 def testCloneElementShallow():
446 dom
, clone
= _setupCloneElement(0)
447 confirm(len(clone
.childNodes
) == 0
448 and clone
.childNodes
.length
== 0
449 and clone
.parentNode
is None
450 and clone
.toxml() == '<doc attr="value"/>'
451 , "testCloneElementShallow")
454 def testCloneElementDeep():
455 dom
, clone
= _setupCloneElement(1)
456 confirm(len(clone
.childNodes
) == 1
457 and clone
.childNodes
.length
== 1
458 and clone
.parentNode
is None
459 and clone
.toxml() == '<doc attr="value"><foo/></doc>'
460 , "testCloneElementDeep")
463 def _setupCloneElement(deep
):
464 dom
= parseString("<doc attr='value'><foo/></doc>")
465 root
= dom
.documentElement
466 clone
= root
.cloneNode(deep
)
467 _testCloneElementCopiesAttributes(
468 root
, clone
, "testCloneElement" + (deep
and "Deep" or "Shallow"))
469 # mutilate the original so shared data is detected
470 root
.tagName
= root
.nodeName
= "MODIFIED"
471 root
.setAttribute("attr", "NEW VALUE")
472 root
.setAttribute("added", "VALUE")
475 def _testCloneElementCopiesAttributes(e1
, e2
, test
):
476 attrs1
= e1
.attributes
477 attrs2
= e2
.attributes
478 keys1
= attrs1
.keys()
479 keys2
= attrs2
.keys()
482 confirm(keys1
== keys2
, "clone of element has same attribute keys")
483 for i
in range(len(keys1
)):
487 and a1
.value
== a2
.value
488 and a1
.nodeValue
== a2
.nodeValue
489 and a1
.namespaceURI
== a2
.namespaceURI
490 and a1
.localName
== a2
.localName
491 , "clone of attribute node has proper attribute values")
492 confirm(a2
.ownerElement
is e2
,
493 "clone of attribute node correctly owned")
496 def testCloneDocumentShallow(): pass
498 def testCloneDocumentDeep(): pass
500 def testCloneAttributeShallow(): pass
502 def testCloneAttributeDeep(): pass
504 def testClonePIShallow(): pass
506 def testClonePIDeep(): pass
509 doc
= parseString("<doc/>")
510 root
= doc
.documentElement
511 root
.appendChild(doc
.createTextNode("first"))
512 root
.appendChild(doc
.createTextNode("second"))
513 confirm(len(root
.childNodes
) == 2
514 and root
.childNodes
.length
== 2, "testNormalize -- preparation")
516 confirm(len(root
.childNodes
) == 1
517 and root
.childNodes
.length
== 1
518 and root
.firstChild
is root
.lastChild
519 and root
.firstChild
.data
== "firstsecond"
520 , "testNormalize -- result")
523 doc
= parseString("<doc/>")
524 root
= doc
.documentElement
525 root
.appendChild(doc
.createTextNode(""))
527 confirm(len(root
.childNodes
) == 0
528 and root
.childNodes
.length
== 0,
529 "testNormalize -- single empty node removed")
533 doc
= parseString("<doc><?pi?>text?<elm/></doc>")
534 root
= doc
.documentElement
535 (pi
, text
, elm
) = root
.childNodes
537 confirm(pi
.nextSibling
is text
and
538 pi
.previousSibling
is None and
539 text
.nextSibling
is elm
and
540 text
.previousSibling
is pi
and
541 elm
.nextSibling
is None and
542 elm
.previousSibling
is text
, "testSiblings")
547 doc
= parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
548 root
= doc
.documentElement
549 elm1
= root
.childNodes
[0]
550 (elm2a
, elm2b
) = elm1
.childNodes
551 elm3
= elm2b
.childNodes
[0]
553 confirm(root
.parentNode
is doc
and
554 elm1
.parentNode
is root
and
555 elm2a
.parentNode
is elm1
and
556 elm2b
.parentNode
is elm1
and
557 elm3
.parentNode
is elm2b
, "testParents")
561 def testNodeListItem():
562 doc
= parseString("<doc><e/><e/></doc>")
563 children
= doc
.childNodes
564 docelem
= children
[0]
565 confirm(children
[0] is children
.item(0)
566 and children
.item(1) is None
567 and docelem
.childNodes
.item(0) is docelem
.childNodes
[0]
568 and docelem
.childNodes
.item(1) is docelem
.childNodes
[1]
569 and docelem
.childNodes
.item(0).childNodes
.item(0) is None,
570 "test NodeList.item()")
574 from xml
.dom
import pulldom
576 sax2dom
= pulldom
.SAX2DOM()
577 sax2dom
.startDocument()
578 sax2dom
.startElement("doc", {})
579 sax2dom
.characters("text")
580 sax2dom
.startElement("subelm", {})
581 sax2dom
.characters("text")
582 sax2dom
.endElement("subelm")
583 sax2dom
.characters("text")
584 sax2dom
.endElement("doc")
585 sax2dom
.endDocument()
587 doc
= sax2dom
.document
588 root
= doc
.documentElement
589 (text1
, elm1
, text2
) = root
.childNodes
590 text3
= elm1
.childNodes
[0]
592 confirm(text1
.previousSibling
is None and
593 text1
.nextSibling
is elm1
and
594 elm1
.previousSibling
is text1
and
595 elm1
.nextSibling
is text2
and
596 text2
.previousSibling
is elm1
and
597 text2
.nextSibling
is None and
598 text3
.previousSibling
is None and
599 text3
.nextSibling
is None, "testSAX2DOM - siblings")
601 confirm(root
.parentNode
is doc
and
602 text1
.parentNode
is root
and
603 elm1
.parentNode
is root
and
604 text2
.parentNode
is root
and
605 text3
.parentNode
is elm1
, "testSAX2DOM - parents")
611 names
= globals().keys()
617 if name
.startswith("test"):
618 func
= globals()[name
]
621 print "Test Succeeded", name
622 confirm(len(Node
.allnodes
) == 0,
623 "assertion: len(Node.allnodes) == 0")
624 if len(Node
.allnodes
):
625 print "Garbage left over:"
627 print Node
.allnodes
.items()[0:10]
629 # Don't print specific nodes if repeatable results
631 print len(Node
.allnodes
)
635 print "Test Failed: ", name
637 traceback
.print_exception(*sys
.exc_info())
638 print `sys
.exc_info()[1]`
642 print "\n\n\n**** Check for failures in these tests:"
647 print "All tests succeeded"
649 Node
.debug
= None # Delete debug output collected in a StringIO object
650 Node
._debug
= 0 # And reset debug mode