1 # test for xml.dom.minidom
7 from test
.test_support
import verbose
10 import xml
.parsers
.expat
12 from xml
.dom
.minidom
import parse
, Node
, Document
, parseString
14 if __name__
== "__main__":
18 tstfile
= os
.path
.join(os
.path
.dirname(base
), "test"+os
.extsep
+"xml")
21 def confirm(test
, testname
= "Test"):
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 xml
.dom
.HierarchyRequestErr
: pass
142 print "dom.appendChild didn't raise HierarchyRequestErr"
144 dom
.appendChild(elem
)
145 try: dom
.insertBefore(text
, elem
)
146 except xml
.dom
.HierarchyRequestErr
: pass
148 print "dom.appendChild didn't raise HierarchyRequestErr"
150 try: dom
.replaceChild(text
, elem
)
151 except xml
.dom
.HierarchyRequestErr
: pass
153 print "dom.appendChild didn't raise HierarchyRequestErr"
155 nodemap
= elem
.attributes
156 try: nodemap
.setNamedItem(text
)
157 except xml
.dom
.HierarchyRequestErr
: pass
159 print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
161 try: nodemap
.setNamedItemNS(text
)
162 except xml
.dom
.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)
357 def testAttributeRepr():
359 el
= dom
.appendChild(dom
.createElement(u
"abc"))
360 node
= el
.setAttribute("abc", "def")
361 confirm(str(node
) == repr(node
))
364 def testTextNodeRepr(): pass
367 str = '<?xml version="1.0" ?>\n<a b="c"/>'
368 dom
= parseString(str)
371 confirm(str == domstr
)
373 def testProcessingInstruction(): pass
375 def testProcessingInstructionRepr(): pass
377 def testTextRepr(): pass
379 def testWriteText(): pass
381 def testDocumentElement(): pass
383 def testTooManyDocumentElements():
384 doc
= parseString("<doc/>")
385 elem
= doc
.createElement("extra")
387 doc
.appendChild(elem
)
388 except xml
.dom
.HierarchyRequestErr
:
391 print "Failed to catch expected exception when" \
392 " adding extra document element."
396 def testCreateElementNS(): pass
398 def testCreateAttributeNS(): pass
400 def testParse(): pass
402 def testParseString(): pass
404 def testComment(): pass
406 def testAttrListItem(): pass
408 def testAttrListItems(): pass
410 def testAttrListItemNS(): pass
412 def testAttrListKeys(): pass
414 def testAttrListKeysNS(): pass
416 def testAttrListValues(): pass
418 def testAttrListLength(): pass
420 def testAttrList__getitem__(): pass
422 def testAttrList__setitem__(): pass
424 def testSetAttrValueandNodeValue(): pass
426 def testParseElement(): pass
428 def testParseAttributes(): pass
430 def testParseElementNamespaces(): pass
432 def testParseAttributeNamespaces(): pass
434 def testParseProcessingInstructions(): pass
436 def testChildNodes(): pass
438 def testFirstChild(): pass
440 def testHasChildNodes(): pass
442 def testCloneElementShallow():
443 dom
, clone
= _setupCloneElement(0)
444 confirm(len(clone
.childNodes
) == 0
445 and clone
.childNodes
.length
== 0
446 and clone
.parentNode
is None
447 and clone
.toxml() == '<doc attr="value"/>'
448 , "testCloneElementShallow")
451 def testCloneElementDeep():
452 dom
, clone
= _setupCloneElement(1)
453 confirm(len(clone
.childNodes
) == 1
454 and clone
.childNodes
.length
== 1
455 and clone
.parentNode
is None
456 and clone
.toxml() == '<doc attr="value"><foo/></doc>'
457 , "testCloneElementDeep")
460 def _setupCloneElement(deep
):
461 dom
= parseString("<doc attr='value'><foo/></doc>")
462 root
= dom
.documentElement
463 clone
= root
.cloneNode(deep
)
464 _testCloneElementCopiesAttributes(
465 root
, clone
, "testCloneElement" + (deep
and "Deep" or "Shallow"))
466 # mutilate the original so shared data is detected
467 root
.tagName
= root
.nodeName
= "MODIFIED"
468 root
.setAttribute("attr", "NEW VALUE")
469 root
.setAttribute("added", "VALUE")
472 def _testCloneElementCopiesAttributes(e1
, e2
, test
):
473 attrs1
= e1
.attributes
474 attrs2
= e2
.attributes
475 keys1
= attrs1
.keys()
476 keys2
= attrs2
.keys()
479 confirm(keys1
== keys2
, "clone of element has same attribute keys")
480 for i
in range(len(keys1
)):
484 and a1
.value
== a2
.value
485 and a1
.nodeValue
== a2
.nodeValue
486 and a1
.namespaceURI
== a2
.namespaceURI
487 and a1
.localName
== a2
.localName
488 , "clone of attribute node has proper attribute values")
489 confirm(a2
.ownerElement
is e2
,
490 "clone of attribute node correctly owned")
493 def testCloneDocumentShallow(): pass
495 def testCloneDocumentDeep(): pass
497 def testCloneAttributeShallow(): pass
499 def testCloneAttributeDeep(): pass
501 def testClonePIShallow(): pass
503 def testClonePIDeep(): pass
506 doc
= parseString("<doc/>")
507 root
= doc
.documentElement
508 root
.appendChild(doc
.createTextNode("first"))
509 root
.appendChild(doc
.createTextNode("second"))
510 confirm(len(root
.childNodes
) == 2
511 and root
.childNodes
.length
== 2, "testNormalize -- preparation")
513 confirm(len(root
.childNodes
) == 1
514 and root
.childNodes
.length
== 1
515 and root
.firstChild
is root
.lastChild
516 and root
.firstChild
.data
== "firstsecond"
517 , "testNormalize -- result")
520 doc
= parseString("<doc/>")
521 root
= doc
.documentElement
522 root
.appendChild(doc
.createTextNode(""))
524 confirm(len(root
.childNodes
) == 0
525 and root
.childNodes
.length
== 0,
526 "testNormalize -- single empty node removed")
530 doc
= parseString("<doc><?pi?>text?<elm/></doc>")
531 root
= doc
.documentElement
532 (pi
, text
, elm
) = root
.childNodes
534 confirm(pi
.nextSibling
is text
and
535 pi
.previousSibling
is None and
536 text
.nextSibling
is elm
and
537 text
.previousSibling
is pi
and
538 elm
.nextSibling
is None and
539 elm
.previousSibling
is text
, "testSiblings")
544 doc
= parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
545 root
= doc
.documentElement
546 elm1
= root
.childNodes
[0]
547 (elm2a
, elm2b
) = elm1
.childNodes
548 elm3
= elm2b
.childNodes
[0]
550 confirm(root
.parentNode
is doc
and
551 elm1
.parentNode
is root
and
552 elm2a
.parentNode
is elm1
and
553 elm2b
.parentNode
is elm1
and
554 elm3
.parentNode
is elm2b
, "testParents")
558 def testNodeListItem():
559 doc
= parseString("<doc><e/><e/></doc>")
560 children
= doc
.childNodes
561 docelem
= children
[0]
562 confirm(children
[0] is children
.item(0)
563 and children
.item(1) is None
564 and docelem
.childNodes
.item(0) is docelem
.childNodes
[0]
565 and docelem
.childNodes
.item(1) is docelem
.childNodes
[1]
566 and docelem
.childNodes
.item(0).childNodes
.item(0) is None,
567 "test NodeList.item()")
571 from xml
.dom
import pulldom
573 sax2dom
= pulldom
.SAX2DOM()
574 sax2dom
.startDocument()
575 sax2dom
.startElement("doc", {})
576 sax2dom
.characters("text")
577 sax2dom
.startElement("subelm", {})
578 sax2dom
.characters("text")
579 sax2dom
.endElement("subelm")
580 sax2dom
.characters("text")
581 sax2dom
.endElement("doc")
582 sax2dom
.endDocument()
584 doc
= sax2dom
.document
585 root
= doc
.documentElement
586 (text1
, elm1
, text2
) = root
.childNodes
587 text3
= elm1
.childNodes
[0]
589 confirm(text1
.previousSibling
is None and
590 text1
.nextSibling
is elm1
and
591 elm1
.previousSibling
is text1
and
592 elm1
.nextSibling
is text2
and
593 text2
.previousSibling
is elm1
and
594 text2
.nextSibling
is None and
595 text3
.previousSibling
is None and
596 text3
.nextSibling
is None, "testSAX2DOM - siblings")
598 confirm(root
.parentNode
is doc
and
599 text1
.parentNode
is root
and
600 elm1
.parentNode
is root
and
601 text2
.parentNode
is root
and
602 text3
.parentNode
is elm1
, "testSAX2DOM - parents")
607 doc
= parseString('<foo>€</foo>')
608 confirm(doc
.toxml() == u
'<?xml version="1.0" ?>\n<foo>\u20ac</foo>'
609 and doc
.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?>\n<foo>\xe2\x82\xac</foo>'
610 and doc
.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?>\n<foo>\xa4</foo>',
611 "testEncodings - encoding EURO SIGN")
616 names
= globals().keys()
623 except AttributeError:
624 # We don't actually have the minidom from teh standard library,
625 # but are picking up the PyXML version from site-packages.
626 def check_allnodes():
629 def check_allnodes():
630 confirm(len(Node
.allnodes
) == 0,
631 "assertion: len(Node.allnodes) == 0")
632 if len(Node
.allnodes
):
633 print "Garbage left over:"
635 print Node
.allnodes
.items()[0:10]
637 # Don't print specific nodes if repeatable results
639 print len(Node
.allnodes
)
643 if name
.startswith("test"):
644 func
= globals()[name
]
650 print "Test Failed: ", name
652 traceback
.print_exception(*sys
.exc_info())
653 print `sys
.exc_info()[1]`
657 print "\n\n\n**** Check for failures in these tests:"