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():
243 d
="""<foo xmlns:minidom="http://pyxml.sf.net/minidom">
247 elem
= dom
.getElementsByTagNameNS("http://pyxml.sf.net/minidom","myelem")
248 confirm(len(elem
) == 1)
251 def testGetEmptyNodeListFromElementsByTagNameNS(): pass
253 def testElementReprAndStr():
255 el
= dom
.appendChild(dom
.createElement("abc"))
258 confirm(string1
== string2
)
261 # commented out until Fredrick's fix is checked in
262 def _testElementReprAndStrUnicode():
264 el
= dom
.appendChild(dom
.createElement(u
"abc"))
267 confirm(string1
== string2
)
270 # commented out until Fredrick's fix is checked in
271 def _testElementReprAndStrUnicodeNS():
273 el
= dom
.appendChild(
274 dom
.createElementNS(u
"http://www.slashdot.org", u
"slash:abc"))
277 confirm(string1
== string2
)
278 confirm(string1
.find("slash:abc") != -1)
280 confirm(len(Node
.allnodes
) == 0)
282 def testAttributeRepr():
284 el
= dom
.appendChild(dom
.createElement(u
"abc"))
285 node
= el
.setAttribute("abc", "def")
286 confirm(str(node
) == repr(node
))
288 confirm(len(Node
.allnodes
) == 0)
290 def testTextNodeRepr(): pass
293 str = '<?xml version="1.0" ?>\n<a b="c"/>'
294 dom
= parseString(str)
297 confirm(str == domstr
)
298 confirm(len(Node
.allnodes
) == 0)
300 def testProcessingInstruction(): pass
302 def testProcessingInstructionRepr(): pass
304 def testTextRepr(): pass
306 def testWriteText(): pass
308 def testDocumentElement(): pass
310 def testTooManyDocumentElements():
311 doc
= parseString("<doc/>")
312 elem
= doc
.createElement("extra")
314 doc
.appendChild(elem
)
315 except HierarchyRequestErr
:
316 print "Caught expected exception when adding extra document element."
318 print "Failed to catch expected exception when" \
319 " adding extra document element."
323 def testCreateElementNS(): pass
325 def testCreateAttributeNS(): pass
327 def testParse(): pass
329 def testParseString(): pass
331 def testComment(): pass
333 def testAttrListItem(): pass
335 def testAttrListItems(): pass
337 def testAttrListItemNS(): pass
339 def testAttrListKeys(): pass
341 def testAttrListKeysNS(): pass
343 def testAttrListValues(): pass
345 def testAttrListLength(): pass
347 def testAttrList__getitem__(): pass
349 def testAttrList__setitem__(): pass
351 def testSetAttrValueandNodeValue(): pass
353 def testParseElement(): pass
355 def testParseAttributes(): pass
357 def testParseElementNamespaces(): pass
359 def testParseAttributeNamespaces(): pass
361 def testParseProcessingInstructions(): pass
363 def testChildNodes(): pass
365 def testFirstChild(): pass
367 def testHasChildNodes(): pass
369 def testCloneElementShallow():
370 dom
, clone
= _setupCloneElement(0)
371 confirm(len(clone
.childNodes
) == 0
372 and clone
.parentNode
is None
373 and clone
.toxml() == '<doc attr="value"/>'
374 , "testCloneElementShallow")
377 def testCloneElementDeep():
378 dom
, clone
= _setupCloneElement(1)
379 confirm(len(clone
.childNodes
) == 1
380 and clone
.parentNode
is None
381 and clone
.toxml() == '<doc attr="value"><foo/></doc>'
382 , "testCloneElementDeep")
385 def _setupCloneElement(deep
):
386 dom
= parseString("<doc attr='value'><foo/></doc>")
387 root
= dom
.documentElement
388 clone
= root
.cloneNode(deep
)
389 _testCloneElementCopiesAttributes(
390 root
, clone
, "testCloneElement" + (deep
and "Deep" or "Shallow"))
391 # mutilate the original so shared data is detected
392 root
.tagName
= root
.nodeName
= "MODIFIED"
393 root
.setAttribute("attr", "NEW VALUE")
394 root
.setAttribute("added", "VALUE")
397 def _testCloneElementCopiesAttributes(e1
, e2
, test
):
398 attrs1
= e1
.attributes
399 attrs2
= e2
.attributes
400 keys1
= attrs1
.keys()
401 keys2
= attrs2
.keys()
404 confirm(keys1
== keys2
, "clone of element has same attribute keys")
405 for i
in range(len(keys1
)):
409 and a1
.value
== a2
.value
410 and a1
.nodeValue
== a2
.nodeValue
411 and a1
.namespaceURI
== a2
.namespaceURI
412 and a1
.localName
== a2
.localName
413 , "clone of attribute node has proper attribute values")
414 confirm(a2
.ownerElement
is e2
,
415 "clone of attribute node correctly owned")
418 def testCloneDocumentShallow(): pass
420 def testCloneDocumentDeep(): pass
422 def testCloneAttributeShallow(): pass
424 def testCloneAttributeDeep(): pass
426 def testClonePIShallow(): pass
428 def testClonePIDeep(): pass
431 doc
= parseString("<doc/>")
432 root
= doc
.documentElement
433 root
.appendChild(doc
.createTextNode("first"))
434 root
.appendChild(doc
.createTextNode("second"))
435 confirm(len(root
.childNodes
) == 2, "testNormalize -- preparation")
437 confirm(len(root
.childNodes
) == 1
438 and root
.firstChild
is root
.lastChild
439 and root
.firstChild
.data
== "firstsecond"
440 , "testNormalize -- result")
443 doc
= parseString("<doc/>")
444 root
= doc
.documentElement
445 root
.appendChild(doc
.createTextNode(""))
447 confirm(len(root
.childNodes
) == 0,
448 "testNormalize -- single empty node removed")
452 doc
= parseString("<doc><?pi?>text?<elm/></doc>")
453 root
= doc
.documentElement
454 (pi
, text
, elm
) = root
.childNodes
456 confirm(pi
.nextSibling
is text
and
457 pi
.previousSibling
is None and
458 text
.nextSibling
is elm
and
459 text
.previousSibling
is pi
and
460 elm
.nextSibling
is None and
461 elm
.previousSibling
is text
, "testSiblings")
466 doc
= parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
467 root
= doc
.documentElement
468 elm1
= root
.childNodes
[0]
469 (elm2a
, elm2b
) = elm1
.childNodes
470 elm3
= elm2b
.childNodes
[0]
472 confirm(root
.parentNode
is doc
and
473 elm1
.parentNode
is root
and
474 elm2a
.parentNode
is elm1
and
475 elm2b
.parentNode
is elm1
and
476 elm3
.parentNode
is elm2b
, "testParents")
481 from xml
.dom
import pulldom
483 sax2dom
= pulldom
.SAX2DOM()
484 sax2dom
.startDocument()
485 sax2dom
.startElement("doc", {})
486 sax2dom
.characters("text")
487 sax2dom
.startElement("subelm", {})
488 sax2dom
.characters("text")
489 sax2dom
.endElement("subelm")
490 sax2dom
.characters("text")
491 sax2dom
.endElement("doc")
492 sax2dom
.endDocument()
494 doc
= sax2dom
.document
495 root
= doc
.documentElement
496 (text1
, elm1
, text2
) = root
.childNodes
497 text3
= elm1
.childNodes
[0]
499 confirm(text1
.previousSibling
is None and
500 text1
.nextSibling
is elm1
and
501 elm1
.previousSibling
is text1
and
502 elm1
.nextSibling
is text2
and
503 text2
.previousSibling
is elm1
and
504 text2
.nextSibling
is None and
505 text3
.previousSibling
is None and
506 text3
.nextSibling
is None, "testSAX2DOM - siblings")
508 confirm(root
.parentNode
is doc
and
509 text1
.parentNode
is root
and
510 elm1
.parentNode
is root
and
511 text2
.parentNode
is root
and
512 text3
.parentNode
is elm1
, "testSAX2DOM - parents")
518 names
= globals().keys()
524 if name
.startswith("test"):
525 func
= globals()[name
]
528 print "Test Succeeded", name
529 confirm(len(Node
.allnodes
) == 0,
530 "assertion: len(Node.allnodes) == 0")
531 if len(Node
.allnodes
):
532 print "Garbage left over:"
534 print Node
.allnodes
.items()[0:10]
536 # Don't print specific nodes if repeatable results
538 print len(Node
.allnodes
)
542 print "Test Failed: ", name
544 traceback
.print_exception(*sys
.exc_info())
545 print `sys
.exc_info()[1]`
549 print "\n\n\n**** Check for failures in these tests:"
554 print "All tests succeeded"
556 Node
.debug
= None # Delete debug output collected in a StringIO object
557 Node
._debug
= 0 # And reset debug mode