1 # test for xml.dom.minidom
7 from StringIO
import StringIO
8 from test
.test_support
import verbose
11 import xml
.dom
.minidom
12 import xml
.parsers
.expat
14 from xml
.dom
.minidom
import parse
, Node
, Document
, parseString
15 from xml
.dom
.minidom
import getDOMImplementation
18 if __name__
== "__main__":
22 tstfile
= os
.path
.join(os
.path
.dirname(base
), "test"+os
.extsep
+"xml")
25 def confirm(test
, testname
= "Test"):
27 print "Failed " + testname
30 def testParseFromFile():
31 dom
= parse(StringIO(open(tstfile
).read()))
33 confirm(isinstance(dom
,Document
))
35 def testGetElementsByTagName():
37 confirm(dom
.getElementsByTagName("LI") == \
38 dom
.documentElement
.getElementsByTagName("LI"))
41 def testInsertBefore():
42 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
48 and root
.childNodes
.length
== 2
49 and root
.childNodes
[0] is nelem
50 and root
.childNodes
.item(0) is nelem
51 and root
.childNodes
[1] is elem
52 and root
.childNodes
.item(1) is elem
53 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
60 and root
.childNodes
.length
== 3
61 and root
.childNodes
[1] is elem
62 and root
.childNodes
.item(1) is elem
63 and root
.childNodes
[2] is nelem
64 and root
.childNodes
.item(2) is nelem
65 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
72 and root
.childNodes
.length
== 4
73 and root
.childNodes
[2] is nelem2
74 and root
.childNodes
.item(2) is nelem2
75 and root
.childNodes
[3] is nelem
76 and root
.childNodes
.item(3) is nelem
77 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")
83 def _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()
94 return dom
, orig
, c1
, c2
, c3
, frag
96 def 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)")
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)")
111 def testAppendChild():
113 dom
.documentElement
.appendChild(dom
.createComment(u
"Hello"))
114 confirm(dom
.documentElement
.childNodes
[-1].nodeName
== "#comment")
115 confirm(dom
.documentElement
.childNodes
[-1].data
== "Hello")
118 def 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>)")
126 def testReplaceChildFragment():
127 dom
, orig
, c1
, c2
, c3
, frag
= _create_fragment_test_nodes()
128 dom
.documentElement
.replaceChild(frag
, orig
)
130 confirm(tuple(dom
.documentElement
.childNodes
) == (c1
, c2
, c3
),
131 "replaceChild(<fragment>)")
135 def testLegalChildren():
137 elem
= dom
.createElement('element')
138 text
= dom
.createTextNode('text')
140 try: dom
.appendChild(text
)
141 except xml
.dom
.HierarchyRequestErr
: pass
143 print "dom.appendChild didn't raise HierarchyRequestErr"
145 dom
.appendChild(elem
)
146 try: dom
.insertBefore(text
, elem
)
147 except xml
.dom
.HierarchyRequestErr
: pass
149 print "dom.appendChild didn't raise HierarchyRequestErr"
151 try: dom
.replaceChild(text
, elem
)
152 except xml
.dom
.HierarchyRequestErr
: pass
154 print "dom.appendChild didn't raise HierarchyRequestErr"
156 nodemap
= elem
.attributes
157 try: nodemap
.setNamedItem(text
)
158 except xml
.dom
.HierarchyRequestErr
: pass
160 print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
162 try: nodemap
.setNamedItemNS(text
)
163 except xml
.dom
.HierarchyRequestErr
: pass
165 print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
167 elem
.appendChild(text
)
170 def testNamedNodeMapSetItem():
172 elem
= dom
.createElement('element')
173 attrs
= elem
.attributes
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")
189 confirm(dom
)# should not be zero
190 dom
.appendChild(dom
.createComment("foo"))
191 confirm(not dom
.childNodes
[-1].childNodes
)
200 dom
.appendChild(dom
.createElement("abc"))
201 confirm(dom
.documentElement
)
205 dom
= parseString("<abc/>")
206 el
= dom
.documentElement
207 el
.setAttribute("spam", "jam2")
208 confirm(el
.toxml() == '<abc spam="jam2"/>', "testAAA")
209 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")
217 dom
= parseString("<abc/>")
218 el
= dom
.documentElement
219 el
.setAttribute("spam", "jam")
220 el
.setAttribute("spam", "jam2")
221 confirm(el
.toxml() == '<abc spam="jam2"/>', "testAAB")
226 child
= dom
.appendChild(dom
.createElement("abc"))
228 child
.setAttribute("def", "ghi")
229 confirm(child
.getAttribute("def") == "ghi")
230 confirm(child
.attributes
["def"].value
== "ghi")
232 child
.setAttribute("jkl", "mno")
233 confirm(child
.getAttribute("jkl") == "mno")
234 confirm(child
.attributes
["jkl"].value
== "mno")
236 confirm(len(child
.attributes
) == 2)
238 child
.setAttribute("def", "newval")
239 confirm(child
.getAttribute("def") == "newval")
240 confirm(child
.attributes
["def"].value
== "newval")
242 confirm(len(child
.attributes
) == 2)
245 def testDeleteAttr():
247 child
= dom
.appendChild(dom
.createElement("abc"))
249 confirm(len(child
.attributes
) == 0)
250 child
.setAttribute("def", "ghi")
251 confirm(len(child
.attributes
) == 1)
252 del child
.attributes
["def"]
253 confirm(len(child
.attributes
) == 0)
256 def testRemoveAttr():
258 child
= dom
.appendChild(dom
.createElement("abc"))
260 child
.setAttribute("def", "ghi")
261 confirm(len(child
.attributes
) == 1)
262 child
.removeAttribute("def")
263 confirm(len(child
.attributes
) == 0)
267 def testRemoveAttrNS():
269 child
= dom
.appendChild(
270 dom
.createElementNS("http://www.python.org", "python:abc"))
271 child
.setAttributeNS("http://www.w3.org", "xmlns:python",
272 "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)
280 def testRemoveAttributeNode():
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
)
287 confirm(len(child
.attributes
) == 0
288 and child
.getAttributeNode("spam") is None)
292 def testChangeAttr():
293 dom
= parseString("<abc/>")
294 el
= dom
.documentElement
295 el
.setAttribute("spam", "jam")
296 confirm(len(el
.attributes
) == 1)
297 el
.setAttribute("spam", "bam")
298 # 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
)
306 el
.attributes
["spam"] = "ham"
307 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
)
312 el
.setAttribute("spam2", "bam")
313 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")
330 def testGetAttrList():
333 def testGetAttrValues(): pass
335 def testGetAttrLength(): pass
337 def testGetAttribute(): pass
339 def testGetAttributeNS(): pass
341 def testGetAttributeNode(): pass
343 def testGetElementsByTagNameNS():
344 d
="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
348 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")
357 def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc
, nsuri
, lname
):
358 nodelist
= doc
.getElementsByTagNameNS(nsuri
, lname
)
359 confirm(len(nodelist
) == 0)
361 def 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(
367 get_empty_nodelist_from_elements_by_tagName_ns_helper(
368 doc
, 'http://xml.python.org/namespaces/a', '*')
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")
378 def testElementReprAndStr():
380 el
= dom
.appendChild(dom
.createElement("abc"))
383 confirm(string1
== string2
)
386 # commented out until Fredrick's fix is checked in
387 def _testElementReprAndStrUnicode():
389 el
= dom
.appendChild(dom
.createElement(u
"abc"))
392 confirm(string1
== string2
)
395 # commented out until Fredrick's fix is checked in
396 def _testElementReprAndStrUnicodeNS():
398 el
= dom
.appendChild(
399 dom
.createElementNS(u
"http://www.slashdot.org", u
"slash:abc"))
402 confirm(string1
== string2
)
403 confirm(string1
.find("slash:abc") != -1)
406 def testAttributeRepr():
408 el
= dom
.appendChild(dom
.createElement(u
"abc"))
409 node
= el
.setAttribute("abc", "def")
410 confirm(str(node
) == repr(node
))
413 def testTextNodeRepr(): pass
416 str = '<?xml version="1.0" ?>\n<a b="c"/>'
417 dom
= parseString(str)
420 confirm(str == domstr
)
422 def testProcessingInstruction():
423 dom
= parseString('<e><?mypi \t\n data \t\n ?></e>')
424 pi
= dom
.documentElement
.firstChild
425 confirm(pi
.target
== "mypi"
426 and pi
.data
== "data \t\n "
427 and pi
.nodeName
== "mypi"
428 and pi
.nodeType
== Node
.PROCESSING_INSTRUCTION_NODE
429 and pi
.attributes
is None
430 and not pi
.hasChildNodes()
431 and len(pi
.childNodes
) == 0
432 and pi
.firstChild
is None
433 and pi
.lastChild
is None
434 and pi
.localName
is None
435 and pi
.namespaceURI
== xml
.dom
.EMPTY_NAMESPACE
)
437 def testProcessingInstructionRepr(): pass
439 def testTextRepr(): pass
441 def testWriteText(): pass
443 def testDocumentElement(): pass
445 def testTooManyDocumentElements():
446 doc
= parseString("<doc/>")
447 elem
= doc
.createElement("extra")
449 doc
.appendChild(elem
)
450 except xml
.dom
.HierarchyRequestErr
:
453 print "Failed to catch expected exception when" \
454 " adding extra document element."
458 def testCreateElementNS(): pass
460 def testCreateAttributeNS(): pass
462 def testParse(): pass
464 def testParseString(): pass
466 def testComment(): pass
468 def testAttrListItem(): pass
470 def testAttrListItems(): pass
472 def testAttrListItemNS(): pass
474 def testAttrListKeys(): pass
476 def testAttrListKeysNS(): pass
478 def testRemoveNamedItem():
479 doc
= parseString("<doc a=''/>")
480 e
= doc
.documentElement
482 a1
= e
.getAttributeNode("a")
483 a2
= attrs
.removeNamedItem("a")
484 confirm(a1
.isSameNode(a2
))
486 attrs
.removeNamedItem("a")
487 except xml
.dom
.NotFoundErr
:
490 def testRemoveNamedItemNS():
491 doc
= parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
492 e
= doc
.documentElement
494 a1
= e
.getAttributeNodeNS("http://xml.python.org/", "b")
495 a2
= attrs
.removeNamedItemNS("http://xml.python.org/", "b")
496 confirm(a1
.isSameNode(a2
))
498 attrs
.removeNamedItemNS("http://xml.python.org/", "b")
499 except xml
.dom
.NotFoundErr
:
502 def testAttrListValues(): pass
504 def testAttrListLength(): pass
506 def testAttrList__getitem__(): pass
508 def testAttrList__setitem__(): pass
510 def testSetAttrValueandNodeValue(): pass
512 def testParseElement(): pass
514 def testParseAttributes(): pass
516 def testParseElementNamespaces(): pass
518 def testParseAttributeNamespaces(): pass
520 def testParseProcessingInstructions(): pass
522 def testChildNodes(): pass
524 def testFirstChild(): pass
526 def testHasChildNodes(): pass
528 def testCloneElementShallow():
529 dom
, clone
= _setupCloneElement(0)
530 confirm(len(clone
.childNodes
) == 0
531 and clone
.childNodes
.length
== 0
532 and clone
.parentNode
is None
533 and clone
.toxml() == '<doc attr="value"/>'
534 , "testCloneElementShallow")
537 def testCloneElementDeep():
538 dom
, clone
= _setupCloneElement(1)
539 confirm(len(clone
.childNodes
) == 1
540 and clone
.childNodes
.length
== 1
541 and clone
.parentNode
is None
542 and clone
.toxml() == '<doc attr="value"><foo/></doc>'
543 , "testCloneElementDeep")
546 def _setupCloneElement(deep
):
547 dom
= parseString("<doc attr='value'><foo/></doc>")
548 root
= dom
.documentElement
549 clone
= root
.cloneNode(deep
)
550 _testCloneElementCopiesAttributes(
551 root
, clone
, "testCloneElement" + (deep
and "Deep" or "Shallow"))
552 # mutilate the original so shared data is detected
553 root
.tagName
= root
.nodeName
= "MODIFIED"
554 root
.setAttribute("attr", "NEW VALUE")
555 root
.setAttribute("added", "VALUE")
558 def _testCloneElementCopiesAttributes(e1
, e2
, test
):
559 attrs1
= e1
.attributes
560 attrs2
= e2
.attributes
561 keys1
= attrs1
.keys()
562 keys2
= attrs2
.keys()
565 confirm(keys1
== keys2
, "clone of element has same attribute keys")
566 for i
in range(len(keys1
)):
570 and a1
.value
== a2
.value
571 and a1
.nodeValue
== a2
.nodeValue
572 and a1
.namespaceURI
== a2
.namespaceURI
573 and a1
.localName
== a2
.localName
574 , "clone of attribute node has proper attribute values")
575 confirm(a2
.ownerElement
is e2
,
576 "clone of attribute node correctly owned")
578 def testCloneDocumentShallow():
579 doc
= parseString("<?xml version='1.0'?>\n"
582 "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
584 "<doc attr='value'/>")
585 doc2
= doc
.cloneNode(0)
586 confirm(doc2
is None,
587 "testCloneDocumentShallow:"
588 " shallow cloning of documents makes no sense!")
590 def testCloneDocumentDeep():
591 doc
= parseString("<?xml version='1.0'?>\n"
594 "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
596 "<doc attr='value'/>")
597 doc2
= doc
.cloneNode(1)
598 confirm(not (doc
.isSameNode(doc2
) or doc2
.isSameNode(doc
)),
599 "testCloneDocumentDeep: document objects not distinct")
600 confirm(len(doc
.childNodes
) == len(doc2
.childNodes
),
601 "testCloneDocumentDeep: wrong number of Document children")
602 confirm(doc2
.documentElement
.nodeType
== Node
.ELEMENT_NODE
,
603 "testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
604 confirm(doc2
.documentElement
.ownerDocument
.isSameNode(doc2
),
605 "testCloneDocumentDeep: documentElement owner is not new document")
606 confirm(not doc
.documentElement
.isSameNode(doc2
.documentElement
),
607 "testCloneDocumentDeep: documentElement should not be shared")
608 if doc
.doctype
is not None:
609 # check the doctype iff the original DOM maintained it
610 confirm(doc2
.doctype
.nodeType
== Node
.DOCUMENT_TYPE_NODE
,
611 "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
612 confirm(doc2
.doctype
.ownerDocument
.isSameNode(doc2
))
613 confirm(not doc
.doctype
.isSameNode(doc2
.doctype
))
615 def testCloneDocumentTypeDeepOk():
616 doctype
= create_nonempty_doctype()
617 clone
= doctype
.cloneNode(1)
618 confirm(clone
is not None
619 and clone
.nodeName
== doctype
.nodeName
620 and clone
.name
== doctype
.name
621 and clone
.publicId
== doctype
.publicId
622 and clone
.systemId
== doctype
.systemId
623 and len(clone
.entities
) == len(doctype
.entities
)
624 and clone
.entities
.item(len(clone
.entities
)) is None
625 and len(clone
.notations
) == len(doctype
.notations
)
626 and clone
.notations
.item(len(clone
.notations
)) is None
627 and len(clone
.childNodes
) == 0)
628 for i
in range(len(doctype
.entities
)):
629 se
= doctype
.entities
.item(i
)
630 ce
= clone
.entities
.item(i
)
631 confirm((not se
.isSameNode(ce
))
632 and (not ce
.isSameNode(se
))
633 and ce
.nodeName
== se
.nodeName
634 and ce
.notationName
== se
.notationName
635 and ce
.publicId
== se
.publicId
636 and ce
.systemId
== se
.systemId
637 and ce
.encoding
== se
.encoding
638 and ce
.actualEncoding
== se
.actualEncoding
639 and ce
.version
== se
.version
)
640 for i
in range(len(doctype
.notations
)):
641 sn
= doctype
.notations
.item(i
)
642 cn
= clone
.notations
.item(i
)
643 confirm((not sn
.isSameNode(cn
))
644 and (not cn
.isSameNode(sn
))
645 and cn
.nodeName
== sn
.nodeName
646 and cn
.publicId
== sn
.publicId
647 and cn
.systemId
== sn
.systemId
)
649 def testCloneDocumentTypeDeepNotOk():
650 doc
= create_doc_with_doctype()
651 clone
= doc
.doctype
.cloneNode(1)
652 confirm(clone
is None, "testCloneDocumentTypeDeepNotOk")
654 def testCloneDocumentTypeShallowOk():
655 doctype
= create_nonempty_doctype()
656 clone
= doctype
.cloneNode(0)
657 confirm(clone
is not None
658 and clone
.nodeName
== doctype
.nodeName
659 and clone
.name
== doctype
.name
660 and clone
.publicId
== doctype
.publicId
661 and clone
.systemId
== doctype
.systemId
662 and len(clone
.entities
) == 0
663 and clone
.entities
.item(0) is None
664 and len(clone
.notations
) == 0
665 and clone
.notations
.item(0) is None
666 and len(clone
.childNodes
) == 0)
668 def testCloneDocumentTypeShallowNotOk():
669 doc
= create_doc_with_doctype()
670 clone
= doc
.doctype
.cloneNode(0)
671 confirm(clone
is None, "testCloneDocumentTypeShallowNotOk")
673 def check_import_document(deep
, testName
):
674 doc1
= parseString("<doc/>")
675 doc2
= parseString("<doc/>")
677 doc1
.importNode(doc2
, deep
)
678 except xml
.dom
.NotSupportedErr
:
681 raise Exception(testName
+
682 ": expected NotSupportedErr when importing a document")
684 def testImportDocumentShallow():
685 check_import_document(0, "testImportDocumentShallow")
687 def testImportDocumentDeep():
688 check_import_document(1, "testImportDocumentDeep")
690 # The tests of DocumentType importing use these helpers to construct
691 # the documents to work with, since not all DOM builders actually
692 # create the DocumentType nodes.
694 def create_doc_without_doctype(doctype
=None):
695 return getDOMImplementation().createDocument(None, "doc", doctype
)
697 def create_nonempty_doctype():
698 doctype
= getDOMImplementation().createDocumentType("doc", None, None)
699 doctype
.entities
._seq
= []
700 doctype
.notations
._seq
= []
701 notation
= xml
.dom
.minidom
.Notation("my-notation", None,
702 "http://xml.python.org/notations/my")
703 doctype
.notations
._seq
.append(notation
)
704 entity
= xml
.dom
.minidom
.Entity("my-entity", None,
705 "http://xml.python.org/entities/my",
707 entity
.version
= "1.0"
708 entity
.encoding
= "utf-8"
709 entity
.actualEncoding
= "us-ascii"
710 doctype
.entities
._seq
.append(entity
)
713 def create_doc_with_doctype():
714 doctype
= create_nonempty_doctype()
715 doc
= create_doc_without_doctype(doctype
)
716 doctype
.entities
.item(0).ownerDocument
= doc
717 doctype
.notations
.item(0).ownerDocument
= doc
720 def testImportDocumentTypeShallow():
721 src
= create_doc_with_doctype()
722 target
= create_doc_without_doctype()
724 imported
= target
.importNode(src
.doctype
, 0)
725 except xml
.dom
.NotSupportedErr
:
729 "testImportDocumentTypeShallow: expected NotSupportedErr")
731 def testImportDocumentTypeDeep():
732 src
= create_doc_with_doctype()
733 target
= create_doc_without_doctype()
735 imported
= target
.importNode(src
.doctype
, 1)
736 except xml
.dom
.NotSupportedErr
:
740 "testImportDocumentTypeDeep: expected NotSupportedErr")
742 # Testing attribute clones uses a helper, and should always be deep,
743 # even if the argument to cloneNode is false.
744 def check_clone_attribute(deep
, testName
):
745 doc
= parseString("<doc attr='value'/>")
746 attr
= doc
.documentElement
.getAttributeNode("attr")
747 assert attr
is not None
748 clone
= attr
.cloneNode(deep
)
749 confirm(not clone
.isSameNode(attr
))
750 confirm(not attr
.isSameNode(clone
))
751 confirm(clone
.ownerElement
is None,
752 testName
+ ": ownerElement should be None")
753 confirm(clone
.ownerDocument
.isSameNode(attr
.ownerDocument
),
754 testName
+ ": ownerDocument does not match")
755 confirm(clone
.specified
,
756 testName
+ ": cloned attribute must have specified == True")
758 def testCloneAttributeShallow():
759 check_clone_attribute(0, "testCloneAttributeShallow")
761 def testCloneAttributeDeep():
762 check_clone_attribute(1, "testCloneAttributeDeep")
764 def check_clone_pi(deep
, testName
):
765 doc
= parseString("<?target data?><doc/>")
767 assert pi
.nodeType
== Node
.PROCESSING_INSTRUCTION_NODE
768 clone
= pi
.cloneNode(deep
)
769 confirm(clone
.target
== pi
.target
770 and clone
.data
== pi
.data
)
772 def testClonePIShallow():
773 check_clone_pi(0, "testClonePIShallow")
775 def testClonePIDeep():
776 check_clone_pi(1, "testClonePIDeep")
779 doc
= parseString("<doc/>")
780 root
= doc
.documentElement
781 root
.appendChild(doc
.createTextNode("first"))
782 root
.appendChild(doc
.createTextNode("second"))
783 confirm(len(root
.childNodes
) == 2
784 and root
.childNodes
.length
== 2, "testNormalize -- preparation")
786 confirm(len(root
.childNodes
) == 1
787 and root
.childNodes
.length
== 1
788 and root
.firstChild
is root
.lastChild
789 and root
.firstChild
.data
== "firstsecond"
790 , "testNormalize -- result")
793 doc
= parseString("<doc/>")
794 root
= doc
.documentElement
795 root
.appendChild(doc
.createTextNode(""))
797 confirm(len(root
.childNodes
) == 0
798 and root
.childNodes
.length
== 0,
799 "testNormalize -- single empty node removed")
803 doc
= parseString("<doc><?pi?>text?<elm/></doc>")
804 root
= doc
.documentElement
805 (pi
, text
, elm
) = root
.childNodes
807 confirm(pi
.nextSibling
is text
and
808 pi
.previousSibling
is None and
809 text
.nextSibling
is elm
and
810 text
.previousSibling
is pi
and
811 elm
.nextSibling
is None and
812 elm
.previousSibling
is text
, "testSiblings")
817 doc
= parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
818 root
= doc
.documentElement
819 elm1
= root
.childNodes
[0]
820 (elm2a
, elm2b
) = elm1
.childNodes
821 elm3
= elm2b
.childNodes
[0]
823 confirm(root
.parentNode
is doc
and
824 elm1
.parentNode
is root
and
825 elm2a
.parentNode
is elm1
and
826 elm2b
.parentNode
is elm1
and
827 elm3
.parentNode
is elm2b
, "testParents")
831 def testNodeListItem():
832 doc
= parseString("<doc><e/><e/></doc>")
833 children
= doc
.childNodes
834 docelem
= children
[0]
835 confirm(children
[0] is children
.item(0)
836 and children
.item(1) is None
837 and docelem
.childNodes
.item(0) is docelem
.childNodes
[0]
838 and docelem
.childNodes
.item(1) is docelem
.childNodes
[1]
839 and docelem
.childNodes
.item(0).childNodes
.item(0) is None,
840 "test NodeList.item()")
844 from xml
.dom
import pulldom
846 sax2dom
= pulldom
.SAX2DOM()
847 sax2dom
.startDocument()
848 sax2dom
.startElement("doc", {})
849 sax2dom
.characters("text")
850 sax2dom
.startElement("subelm", {})
851 sax2dom
.characters("text")
852 sax2dom
.endElement("subelm")
853 sax2dom
.characters("text")
854 sax2dom
.endElement("doc")
855 sax2dom
.endDocument()
857 doc
= sax2dom
.document
858 root
= doc
.documentElement
859 (text1
, elm1
, text2
) = root
.childNodes
860 text3
= elm1
.childNodes
[0]
862 confirm(text1
.previousSibling
is None and
863 text1
.nextSibling
is elm1
and
864 elm1
.previousSibling
is text1
and
865 elm1
.nextSibling
is text2
and
866 text2
.previousSibling
is elm1
and
867 text2
.nextSibling
is None and
868 text3
.previousSibling
is None and
869 text3
.nextSibling
is None, "testSAX2DOM - siblings")
871 confirm(root
.parentNode
is doc
and
872 text1
.parentNode
is root
and
873 elm1
.parentNode
is root
and
874 text2
.parentNode
is root
and
875 text3
.parentNode
is elm1
, "testSAX2DOM - parents")
880 doc
= parseString('<foo>€</foo>')
881 confirm(doc
.toxml() == u
'<?xml version="1.0" ?>\n<foo>\u20ac</foo>'
882 and doc
.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?>\n<foo>\xe2\x82\xac</foo>'
883 and doc
.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?>\n<foo>\xa4</foo>',
884 "testEncodings - encoding EURO SIGN")
887 class UserDataHandler
:
889 def handle(self
, operation
, key
, data
, src
, dst
):
890 dst
.setUserData(key
, data
+ 1, self
)
891 src
.setUserData(key
, None, None)
896 n
= dom
.createElement('e')
897 confirm(n
.getUserData("foo") is None)
898 n
.setUserData("foo", None, None)
899 confirm(n
.getUserData("foo") is None)
900 n
.setUserData("foo", 12, 12)
901 n
.setUserData("bar", 13, 13)
902 confirm(n
.getUserData("foo") == 12)
903 confirm(n
.getUserData("bar") == 13)
904 n
.setUserData("foo", None, None)
905 confirm(n
.getUserData("foo") is None)
906 confirm(n
.getUserData("bar") == 13)
908 handler
= UserDataHandler()
909 n
.setUserData("bar", 12, handler
)
911 confirm(handler
.called
912 and n
.getUserData("bar") is None
913 and c
.getUserData("bar") == 13)
918 def testRenameAttribute():
919 doc
= parseString("<doc a='v'/>")
920 elem
= doc
.documentElement
921 attrmap
= elem
.attributes
922 attr
= elem
.attributes
['a']
925 attr
= doc
.renameNode(attr
, xml
.dom
.EMPTY_NAMESPACE
, "b")
926 confirm(attr
.name
== "b"
927 and attr
.nodeName
== "b"
928 and attr
.localName
is None
929 and attr
.namespaceURI
== xml
.dom
.EMPTY_NAMESPACE
930 and attr
.prefix
is None
931 and attr
.value
== "v"
932 and elem
.getAttributeNode("a") is None
933 and elem
.getAttributeNode("b").isSameNode(attr
)
934 and attrmap
["b"].isSameNode(attr
)
935 and attr
.ownerDocument
.isSameNode(doc
)
936 and attr
.ownerElement
.isSameNode(elem
))
938 # Rename to have a namespace, no prefix
939 attr
= doc
.renameNode(attr
, "http://xml.python.org/ns", "c")
940 confirm(attr
.name
== "c"
941 and attr
.nodeName
== "c"
942 and attr
.localName
== "c"
943 and attr
.namespaceURI
== "http://xml.python.org/ns"
944 and attr
.prefix
is None
945 and attr
.value
== "v"
946 and elem
.getAttributeNode("a") is None
947 and elem
.getAttributeNode("b") is None
948 and elem
.getAttributeNode("c").isSameNode(attr
)
949 and elem
.getAttributeNodeNS(
950 "http://xml.python.org/ns", "c").isSameNode(attr
)
951 and attrmap
["c"].isSameNode(attr
)
952 and attrmap
[("http://xml.python.org/ns", "c")].isSameNode(attr
))
954 # Rename to have a namespace, with prefix
955 attr
= doc
.renameNode(attr
, "http://xml.python.org/ns2", "p:d")
956 confirm(attr
.name
== "p:d"
957 and attr
.nodeName
== "p:d"
958 and attr
.localName
== "d"
959 and attr
.namespaceURI
== "http://xml.python.org/ns2"
960 and attr
.prefix
== "p"
961 and attr
.value
== "v"
962 and elem
.getAttributeNode("a") is None
963 and elem
.getAttributeNode("b") is None
964 and elem
.getAttributeNode("c") is None
965 and elem
.getAttributeNodeNS(
966 "http://xml.python.org/ns", "c") is None
967 and elem
.getAttributeNode("p:d").isSameNode(attr
)
968 and elem
.getAttributeNodeNS(
969 "http://xml.python.org/ns2", "d").isSameNode(attr
)
970 and attrmap
["p:d"].isSameNode(attr
)
971 and attrmap
[("http://xml.python.org/ns2", "d")].isSameNode(attr
))
973 # Rename back to a simple non-NS node
974 attr
= doc
.renameNode(attr
, xml
.dom
.EMPTY_NAMESPACE
, "e")
975 confirm(attr
.name
== "e"
976 and attr
.nodeName
== "e"
977 and attr
.localName
is None
978 and attr
.namespaceURI
== xml
.dom
.EMPTY_NAMESPACE
979 and attr
.prefix
is None
980 and attr
.value
== "v"
981 and elem
.getAttributeNode("a") is None
982 and elem
.getAttributeNode("b") is None
983 and elem
.getAttributeNode("c") is None
984 and elem
.getAttributeNode("p:d") is None
985 and elem
.getAttributeNodeNS(
986 "http://xml.python.org/ns", "c") is None
987 and elem
.getAttributeNode("e").isSameNode(attr
)
988 and attrmap
["e"].isSameNode(attr
))
991 doc
.renameNode(attr
, "http://xml.python.org/ns", "xmlns")
992 except xml
.dom
.NamespaceErr
:
995 print "expected NamespaceErr"
997 checkRenameNodeSharedConstraints(doc
, attr
)
1000 def testRenameElement():
1001 doc
= parseString("<doc/>")
1002 elem
= doc
.documentElement
1005 elem
= doc
.renameNode(elem
, xml
.dom
.EMPTY_NAMESPACE
, "a")
1006 confirm(elem
.tagName
== "a"
1007 and elem
.nodeName
== "a"
1008 and elem
.localName
is None
1009 and elem
.namespaceURI
== xml
.dom
.EMPTY_NAMESPACE
1010 and elem
.prefix
is None
1011 and elem
.ownerDocument
.isSameNode(doc
))
1013 # Rename to have a namespace, no prefix
1014 elem
= doc
.renameNode(elem
, "http://xml.python.org/ns", "b")
1015 confirm(elem
.tagName
== "b"
1016 and elem
.nodeName
== "b"
1017 and elem
.localName
== "b"
1018 and elem
.namespaceURI
== "http://xml.python.org/ns"
1019 and elem
.prefix
is None
1020 and elem
.ownerDocument
.isSameNode(doc
))
1022 # Rename to have a namespace, with prefix
1023 elem
= doc
.renameNode(elem
, "http://xml.python.org/ns2", "p:c")
1024 confirm(elem
.tagName
== "p:c"
1025 and elem
.nodeName
== "p:c"
1026 and elem
.localName
== "c"
1027 and elem
.namespaceURI
== "http://xml.python.org/ns2"
1028 and elem
.prefix
== "p"
1029 and elem
.ownerDocument
.isSameNode(doc
))
1031 # Rename back to a simple non-NS node
1032 elem
= doc
.renameNode(elem
, xml
.dom
.EMPTY_NAMESPACE
, "d")
1033 confirm(elem
.tagName
== "d"
1034 and elem
.nodeName
== "d"
1035 and elem
.localName
is None
1036 and elem
.namespaceURI
== xml
.dom
.EMPTY_NAMESPACE
1037 and elem
.prefix
is None
1038 and elem
.ownerDocument
.isSameNode(doc
))
1040 checkRenameNodeSharedConstraints(doc
, elem
)
1043 def checkRenameNodeSharedConstraints(doc
, node
):
1044 # Make sure illegal NS usage is detected:
1046 doc
.renameNode(node
, "http://xml.python.org/ns", "xmlns:foo")
1047 except xml
.dom
.NamespaceErr
:
1050 print "expected NamespaceErr"
1052 doc2
= parseString("<doc/>")
1054 doc2
.renameNode(node
, xml
.dom
.EMPTY_NAMESPACE
, "foo")
1055 except xml
.dom
.WrongDocumentErr
:
1058 print "expected WrongDocumentErr"
1060 def testRenameOther():
1061 # We have to create a comment node explicitly since not all DOM
1062 # builders used with minidom add comments to the DOM.
1063 doc
= xml
.dom
.minidom
.getDOMImplementation().createDocument(
1064 xml
.dom
.EMPTY_NAMESPACE
, "e", None)
1065 node
= doc
.createComment("comment")
1067 doc
.renameNode(node
, xml
.dom
.EMPTY_NAMESPACE
, "foo")
1068 except xml
.dom
.NotSupportedErr
:
1071 print "expected NotSupportedErr when renaming comment node"
1074 def checkWholeText(node
, s
):
1076 confirm(t
== s
, "looking for %s, found %s" % (repr(s
), repr(t
)))
1078 def testWholeText():
1079 doc
= parseString("<doc>a</doc>")
1080 elem
= doc
.documentElement
1081 text
= elem
.childNodes
[0]
1082 assert text
.nodeType
== Node
.TEXT_NODE
1084 checkWholeText(text
, "a")
1085 elem
.appendChild(doc
.createTextNode("b"))
1086 checkWholeText(text
, "ab")
1087 elem
.insertBefore(doc
.createCDATASection("c"), text
)
1088 checkWholeText(text
, "cab")
1090 # make sure we don't cross other nodes
1091 splitter
= doc
.createComment("comment")
1092 elem
.appendChild(splitter
)
1093 text2
= doc
.createTextNode("d")
1094 elem
.appendChild(text2
)
1095 checkWholeText(text
, "cab")
1096 checkWholeText(text2
, "d")
1098 x
= doc
.createElement("x")
1099 elem
.replaceChild(x
, splitter
)
1101 checkWholeText(text
, "cab")
1102 checkWholeText(text2
, "d")
1104 x
= doc
.createProcessingInstruction("y", "z")
1105 elem
.replaceChild(x
, splitter
)
1107 checkWholeText(text
, "cab")
1108 checkWholeText(text2
, "d")
1110 elem
.removeChild(splitter
)
1111 checkWholeText(text
, "cabd")
1112 checkWholeText(text2
, "cabd")
1114 def testReplaceWholeText():
1116 doc
= parseString("<doc>a<e/>d</doc>")
1117 elem
= doc
.documentElement
1118 text1
= elem
.firstChild
1119 text2
= elem
.lastChild
1120 splitter
= text1
.nextSibling
1121 elem
.insertBefore(doc
.createTextNode("b"), splitter
)
1122 elem
.insertBefore(doc
.createCDATASection("c"), text1
)
1123 return doc
, elem
, text1
, splitter
, text2
1125 doc
, elem
, text1
, splitter
, text2
= setup()
1126 text
= text1
.replaceWholeText("new content")
1127 checkWholeText(text
, "new content")
1128 checkWholeText(text2
, "d")
1129 confirm(len(elem
.childNodes
) == 3)
1131 doc
, elem
, text1
, splitter
, text2
= setup()
1132 text
= text2
.replaceWholeText("new content")
1133 checkWholeText(text
, "new content")
1134 checkWholeText(text1
, "cab")
1135 confirm(len(elem
.childNodes
) == 5)
1137 doc
, elem
, text1
, splitter
, text2
= setup()
1138 text
= text1
.replaceWholeText("")
1139 checkWholeText(text2
, "d")
1140 confirm(text
is None
1141 and len(elem
.childNodes
) == 2)
1143 def testSchemaType():
1146 " <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
1147 " <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
1148 " <!ATTLIST doc id ID #IMPLIED \n"
1149 " ref IDREF #IMPLIED \n"
1150 " refs IDREFS #IMPLIED \n"
1151 " enum (a|b) #IMPLIED \n"
1152 " ent ENTITY #IMPLIED \n"
1153 " ents ENTITIES #IMPLIED \n"
1154 " nm NMTOKEN #IMPLIED \n"
1155 " nms NMTOKENS #IMPLIED \n"
1156 " text CDATA #IMPLIED \n"
1158 "]><doc id='name' notid='name' text='splat!' enum='b'"
1159 " ref='name' refs='name name' ent='e1' ents='e1 e2'"
1160 " nm='123' nms='123 abc' />")
1161 elem
= doc
.documentElement
1162 # We don't want to rely on any specific loader at this point, so
1163 # just make sure we can get to all the names, and that the
1164 # DTD-based namespace is right. The names can vary by loader
1165 # since each supports a different level of DTD information.
1167 confirm(t
.name
is None
1168 and t
.namespace
== xml
.dom
.EMPTY_NAMESPACE
)
1169 names
= "id notid text enum ref refs ent ents nm nms".split()
1171 a
= elem
.getAttributeNode(name
)
1173 confirm(hasattr(t
, "name")
1174 and t
.namespace
== xml
.dom
.EMPTY_NAMESPACE
)
1176 def testSetIdAttribute():
1177 doc
= parseString("<doc a1='v' a2='w'/>")
1178 e
= doc
.documentElement
1179 a1
= e
.getAttributeNode("a1")
1180 a2
= e
.getAttributeNode("a2")
1181 confirm(doc
.getElementById("v") is None
1184 e
.setIdAttribute("a1")
1185 confirm(e
.isSameNode(doc
.getElementById("v"))
1188 e
.setIdAttribute("a2")
1189 confirm(e
.isSameNode(doc
.getElementById("v"))
1190 and e
.isSameNode(doc
.getElementById("w"))
1193 # replace the a1 node; the new node should *not* be an ID
1194 a3
= doc
.createAttribute("a1")
1196 e
.setAttributeNode(a3
)
1197 confirm(doc
.getElementById("v") is None
1198 and e
.isSameNode(doc
.getElementById("w"))
1202 # renaming an attribute should not affect it's ID-ness:
1203 doc
.renameNode(a2
, xml
.dom
.EMPTY_NAMESPACE
, "an")
1204 confirm(e
.isSameNode(doc
.getElementById("w"))
1207 def testSetIdAttributeNS():
1208 NS1
= "http://xml.python.org/ns1"
1209 NS2
= "http://xml.python.org/ns2"
1210 doc
= parseString("<doc"
1211 " xmlns:ns1='" + NS1
+ "'"
1212 " xmlns:ns2='" + NS2
+ "'"
1213 " ns1:a1='v' ns2:a2='w'/>")
1214 e
= doc
.documentElement
1215 a1
= e
.getAttributeNodeNS(NS1
, "a1")
1216 a2
= e
.getAttributeNodeNS(NS2
, "a2")
1217 confirm(doc
.getElementById("v") is None
1220 e
.setIdAttributeNS(NS1
, "a1")
1221 confirm(e
.isSameNode(doc
.getElementById("v"))
1224 e
.setIdAttributeNS(NS2
, "a2")
1225 confirm(e
.isSameNode(doc
.getElementById("v"))
1226 and e
.isSameNode(doc
.getElementById("w"))
1229 # replace the a1 node; the new node should *not* be an ID
1230 a3
= doc
.createAttributeNS(NS1
, "a1")
1232 e
.setAttributeNode(a3
)
1233 confirm(e
.isSameNode(doc
.getElementById("w")))
1234 confirm(not a1
.isId
)
1236 confirm(not a3
.isId
)
1237 confirm(doc
.getElementById("v") is None)
1238 # renaming an attribute should not affect it's ID-ness:
1239 doc
.renameNode(a2
, xml
.dom
.EMPTY_NAMESPACE
, "an")
1240 confirm(e
.isSameNode(doc
.getElementById("w"))
1243 def testSetIdAttributeNode():
1244 NS1
= "http://xml.python.org/ns1"
1245 NS2
= "http://xml.python.org/ns2"
1246 doc
= parseString("<doc"
1247 " xmlns:ns1='" + NS1
+ "'"
1248 " xmlns:ns2='" + NS2
+ "'"
1249 " ns1:a1='v' ns2:a2='w'/>")
1250 e
= doc
.documentElement
1251 a1
= e
.getAttributeNodeNS(NS1
, "a1")
1252 a2
= e
.getAttributeNodeNS(NS2
, "a2")
1253 confirm(doc
.getElementById("v") is None
1256 e
.setIdAttributeNode(a1
)
1257 confirm(e
.isSameNode(doc
.getElementById("v"))
1260 e
.setIdAttributeNode(a2
)
1261 confirm(e
.isSameNode(doc
.getElementById("v"))
1262 and e
.isSameNode(doc
.getElementById("w"))
1265 # replace the a1 node; the new node should *not* be an ID
1266 a3
= doc
.createAttributeNS(NS1
, "a1")
1268 e
.setAttributeNode(a3
)
1269 confirm(e
.isSameNode(doc
.getElementById("w")))
1270 confirm(not a1
.isId
)
1272 confirm(not a3
.isId
)
1273 confirm(doc
.getElementById("v") is None)
1274 # renaming an attribute should not affect it's ID-ness:
1275 doc
.renameNode(a2
, xml
.dom
.EMPTY_NAMESPACE
, "an")
1276 confirm(e
.isSameNode(doc
.getElementById("w"))
1279 def testPickledDocument():
1280 doc
= parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
1281 "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
1282 " 'http://xml.python.org/system' [\n"
1283 " <!ELEMENT e EMPTY>\n"
1284 " <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
1285 "]><doc attr='value'> text\n"
1286 "<?pi sample?> <!-- comment --> <e/> </doc>")
1287 s
= pickle
.dumps(doc
)
1288 doc2
= pickle
.loads(s
)
1289 stack
= [(doc
, doc2
)]
1291 n1
, n2
= stack
.pop()
1292 confirm(n1
.nodeType
== n2
.nodeType
1293 and len(n1
.childNodes
) == len(n2
.childNodes
)
1294 and n1
.nodeName
== n2
.nodeName
1295 and not n1
.isSameNode(n2
)
1296 and not n2
.isSameNode(n1
))
1297 if n1
.nodeType
== Node
.DOCUMENT_TYPE_NODE
:
1302 confirm(len(n1
.entities
) == len(n2
.entities
)
1303 and len(n1
.notations
) == len(n2
.notations
))
1304 for i
in range(len(n1
.notations
)):
1305 no1
= n1
.notations
.item(i
)
1306 no2
= n1
.notations
.item(i
)
1307 confirm(no1
.name
== no2
.name
1308 and no1
.publicId
== no2
.publicId
1309 and no1
.systemId
== no2
.systemId
)
1310 statck
.append((no1
, no2
))
1311 for i
in range(len(n1
.entities
)):
1312 e1
= n1
.entities
.item(i
)
1313 e2
= n2
.entities
.item(i
)
1314 confirm(e1
.notationName
== e2
.notationName
1315 and e1
.publicId
== e2
.publicId
1316 and e1
.systemId
== e2
.systemId
)
1317 stack
.append((e1
, e2
))
1318 if n1
.nodeType
!= Node
.DOCUMENT_NODE
:
1319 confirm(n1
.ownerDocument
.isSameNode(doc
)
1320 and n2
.ownerDocument
.isSameNode(doc2
))
1321 for i
in range(len(n1
.childNodes
)):
1322 stack
.append((n1
.childNodes
[i
], n2
.childNodes
[i
]))
1327 names
= globals().keys()
1334 except AttributeError:
1335 # We don't actually have the minidom from the standard library,
1336 # but are picking up the PyXML version from site-packages.
1337 def check_allnodes():
1340 def check_allnodes():
1341 confirm(len(Node
.allnodes
) == 0,
1342 "assertion: len(Node.allnodes) == 0")
1343 if len(Node
.allnodes
):
1344 print "Garbage left over:"
1346 print Node
.allnodes
.items()[0:10]
1348 # Don't print specific nodes if repeatable results
1350 print len(Node
.allnodes
)
1354 if name
.startswith("test"):
1355 func
= globals()[name
]
1361 print "Test Failed: ", name
1363 traceback
.print_exception(*sys
.exc_info())
1364 print `sys
.exc_info()[1]`
1368 print "\n\n\n**** Check for failures in these tests:"