0001 # test for xml.dom.minidom 0002 0003 import os 0004 import sys 0005 import pickle 0006 import traceback 0007 from StringIO import StringIO 0008 from test.test_support import verbose 0009 0010 import xml.dom 0011 import xml.dom.minidom 0012 import xml.parsers.expat 0013 0014 from xml.dom.minidom import parse, Node, Document, parseString 0015 from xml.dom.minidom import getDOMImplementation 0016 0017 0018 if __name__ == "__main__": 0019 base = sys.argv[0] 0020 else: 0021 base = __file__ 0022 tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml") 0023 del base 0024 0025 def confirm(test, testname = "Test"): 0026 if not test: 0027 print "Failed " + testname 0028 raise Exception 0029 0030 def testParseFromFile(): 0031 dom = parse(StringIO(open(tstfile).read())) 0032 dom.unlink() 0033 confirm(isinstance(dom,Document)) 0034 0035 def testGetElementsByTagName(): 0036 dom = parse(tstfile) 0037 confirm(dom.getElementsByTagName("LI") == \ 0038 dom.documentElement.getElementsByTagName("LI")) 0039 dom.unlink() 0040 0041 def testInsertBefore(): 0042 dom = parseString("<doc><foo/></doc>") 0043 root = dom.documentElement 0044 elem = root.childNodes[0] 0045 nelem = dom.createElement("element") 0046 root.insertBefore(nelem, elem) 0047 confirm(len(root.childNodes) == 2 0048 and root.childNodes.length == 2 0049 and root.childNodes[0] is nelem 0050 and root.childNodes.item(0) is nelem 0051 and root.childNodes[1] is elem 0052 and root.childNodes.item(1) is elem 0053 and root.firstChild is nelem 0054 and root.lastChild is elem 0055 and root.toxml() == "<doc><element/><foo/></doc>" 0056 , "testInsertBefore -- node properly placed in tree") 0057 nelem = dom.createElement("element") 0058 root.insertBefore(nelem, None) 0059 confirm(len(root.childNodes) == 3 0060 and root.childNodes.length == 3 0061 and root.childNodes[1] is elem 0062 and root.childNodes.item(1) is elem 0063 and root.childNodes[2] is nelem 0064 and root.childNodes.item(2) is nelem 0065 and root.lastChild is nelem 0066 and nelem.previousSibling is elem 0067 and root.toxml() == "<doc><element/><foo/><element/></doc>" 0068 , "testInsertBefore -- node properly placed in tree") 0069 nelem2 = dom.createElement("bar") 0070 root.insertBefore(nelem2, nelem) 0071 confirm(len(root.childNodes) == 4 0072 and root.childNodes.length == 4 0073 and root.childNodes[2] is nelem2 0074 and root.childNodes.item(2) is nelem2 0075 and root.childNodes[3] is nelem 0076 and root.childNodes.item(3) is nelem 0077 and nelem2.nextSibling is nelem 0078 and nelem.previousSibling is nelem2 0079 and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>" 0080 , "testInsertBefore -- node properly placed in tree") 0081 dom.unlink() 0082 0083 def _create_fragment_test_nodes(): 0084 dom = parseString("<doc/>") 0085 orig = dom.createTextNode("original") 0086 c1 = dom.createTextNode("foo") 0087 c2 = dom.createTextNode("bar") 0088 c3 = dom.createTextNode("bat") 0089 dom.documentElement.appendChild(orig) 0090 frag = dom.createDocumentFragment() 0091 frag.appendChild(c1) 0092 frag.appendChild(c2) 0093 frag.appendChild(c3) 0094 return dom, orig, c1, c2, c3, frag 0095 0096 def testInsertBeforeFragment(): 0097 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes() 0098 dom.documentElement.insertBefore(frag, None) 0099 confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3), 0100 "insertBefore(<fragment>, None)") 0101 frag.unlink() 0102 dom.unlink() 0103 # 0104 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes() 0105 dom.documentElement.insertBefore(frag, orig) 0106 confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig), 0107 "insertBefore(<fragment>, orig)") 0108 frag.unlink() 0109 dom.unlink() 0110 0111 def testAppendChild(): 0112 dom = parse(tstfile) 0113 dom.documentElement.appendChild(dom.createComment(u"Hello")) 0114 confirm(dom.documentElement.childNodes[-1].nodeName == "#comment") 0115 confirm(dom.documentElement.childNodes[-1].data == "Hello") 0116 dom.unlink() 0117 0118 def testAppendChildFragment(): 0119 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes() 0120 dom.documentElement.appendChild(frag) 0121 confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3), 0122 "appendChild(<fragment>)") 0123 frag.unlink() 0124 dom.unlink() 0125 0126 def testReplaceChildFragment(): 0127 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes() 0128 dom.documentElement.replaceChild(frag, orig) 0129 orig.unlink() 0130 confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3), 0131 "replaceChild(<fragment>)") 0132 frag.unlink() 0133 dom.unlink() 0134 0135 def testLegalChildren(): 0136 dom = Document() 0137 elem = dom.createElement('element') 0138 text = dom.createTextNode('text') 0139 0140 try: dom.appendChild(text) 0141 except xml.dom.HierarchyRequestErr: pass 0142 else: 0143 print "dom.appendChild didn't raise HierarchyRequestErr" 0144 0145 dom.appendChild(elem) 0146 try: dom.insertBefore(text, elem) 0147 except xml.dom.HierarchyRequestErr: pass 0148 else: 0149 print "dom.appendChild didn't raise HierarchyRequestErr" 0150 0151 try: dom.replaceChild(text, elem) 0152 except xml.dom.HierarchyRequestErr: pass 0153 else: 0154 print "dom.appendChild didn't raise HierarchyRequestErr" 0155 0156 nodemap = elem.attributes 0157 try: nodemap.setNamedItem(text) 0158 except xml.dom.HierarchyRequestErr: pass 0159 else: 0160 print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr" 0161 0162 try: nodemap.setNamedItemNS(text) 0163 except xml.dom.HierarchyRequestErr: pass 0164 else: 0165 print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr" 0166 0167 elem.appendChild(text) 0168 dom.unlink() 0169 0170 def testNamedNodeMapSetItem(): 0171 dom = Document() 0172 elem = dom.createElement('element') 0173 attrs = elem.attributes 0174 attrs["foo"] = "bar" 0175 a = attrs.item(0) 0176 confirm(a.ownerDocument is dom, 0177 "NamedNodeMap.__setitem__() sets ownerDocument") 0178 confirm(a.ownerElement is elem, 0179 "NamedNodeMap.__setitem__() sets ownerElement") 0180 confirm(a.value == "bar", 0181 "NamedNodeMap.__setitem__() sets value") 0182 confirm(a.nodeValue == "bar", 0183 "NamedNodeMap.__setitem__() sets nodeValue") 0184 elem.unlink() 0185 dom.unlink() 0186 0187 def testNonZero(): 0188 dom = parse(tstfile) 0189 confirm(dom)# should not be zero 0190 dom.appendChild(dom.createComment("foo")) 0191 confirm(not dom.childNodes[-1].childNodes) 0192 dom.unlink() 0193 0194 def testUnlink(): 0195 dom = parse(tstfile) 0196 dom.unlink() 0197 0198 def testElement(): 0199 dom = Document() 0200 dom.appendChild(dom.createElement("abc")) 0201 confirm(dom.documentElement) 0202 dom.unlink() 0203 0204 def testAAA(): 0205 dom = parseString("<abc/>") 0206 el = dom.documentElement 0207 el.setAttribute("spam", "jam2") 0208 confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA") 0209 a = el.getAttributeNode("spam") 0210 confirm(a.ownerDocument is dom, 0211 "setAttribute() sets ownerDocument") 0212 confirm(a.ownerElement is dom.documentElement, 0213 "setAttribute() sets ownerElement") 0214 dom.unlink() 0215 0216 def testAAB(): 0217 dom = parseString("<abc/>") 0218 el = dom.documentElement 0219 el.setAttribute("spam", "jam") 0220 el.setAttribute("spam", "jam2") 0221 confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB") 0222 dom.unlink() 0223 0224 def testAddAttr(): 0225 dom = Document() 0226 child = dom.appendChild(dom.createElement("abc")) 0227 0228 child.setAttribute("def", "ghi") 0229 confirm(child.getAttribute("def") == "ghi") 0230 confirm(child.attributes["def"].value == "ghi") 0231 0232 child.setAttribute("jkl", "mno") 0233 confirm(child.getAttribute("jkl") == "mno") 0234 confirm(child.attributes["jkl"].value == "mno") 0235 0236 confirm(len(child.attributes) == 2) 0237 0238 child.setAttribute("def", "newval") 0239 confirm(child.getAttribute("def") == "newval") 0240 confirm(child.attributes["def"].value == "newval") 0241 0242 confirm(len(child.attributes) == 2) 0243 dom.unlink() 0244 0245 def testDeleteAttr(): 0246 dom = Document() 0247 child = dom.appendChild(dom.createElement("abc")) 0248 0249 confirm(len(child.attributes) == 0) 0250 child.setAttribute("def", "ghi") 0251 confirm(len(child.attributes) == 1) 0252 del child.attributes["def"] 0253 confirm(len(child.attributes) == 0) 0254 dom.unlink() 0255 0256 def testRemoveAttr(): 0257 dom = Document() 0258 child = dom.appendChild(dom.createElement("abc")) 0259 0260 child.setAttribute("def", "ghi") 0261 confirm(len(child.attributes) == 1) 0262 child.removeAttribute("def") 0263 confirm(len(child.attributes) == 0) 0264 0265 dom.unlink() 0266 0267 def testRemoveAttrNS(): 0268 dom = Document() 0269 child = dom.appendChild( 0270 dom.createElementNS("http://www.python.org", "python:abc")) 0271 child.setAttributeNS("http://www.w3.org", "xmlns:python", 0272 "http://www.python.org") 0273 child.setAttributeNS("http://www.python.org", "python:abcattr", "foo") 0274 confirm(len(child.attributes) == 2) 0275 child.removeAttributeNS("http://www.python.org", "abcattr") 0276 confirm(len(child.attributes) == 1) 0277 0278 dom.unlink() 0279 0280 def testRemoveAttributeNode(): 0281 dom = Document() 0282 child = dom.appendChild(dom.createElement("foo")) 0283 child.setAttribute("spam", "jam") 0284 confirm(len(child.attributes) == 1) 0285 node = child.getAttributeNode("spam") 0286 child.removeAttributeNode(node) 0287 confirm(len(child.attributes) == 0 0288 and child.getAttributeNode("spam") is None) 0289 0290 dom.unlink() 0291 0292 def testChangeAttr(): 0293 dom = parseString("<abc/>") 0294 el = dom.documentElement 0295 el.setAttribute("spam", "jam") 0296 confirm(len(el.attributes) == 1) 0297 el.setAttribute("spam", "bam") 0298 # Set this attribute to be an ID and make sure that doesn't change 0299 # when changing the value: 0300 el.setIdAttribute("spam") 0301 confirm(len(el.attributes) == 1 0302 and el.attributes["spam"].value == "bam" 0303 and el.attributes["spam"].nodeValue == "bam" 0304 and el.getAttribute("spam") == "bam" 0305 and el.getAttributeNode("spam").isId) 0306 el.attributes["spam"] = "ham" 0307 confirm(len(el.attributes) == 1 0308 and el.attributes["spam"].value == "ham" 0309 and el.attributes["spam"].nodeValue == "ham" 0310 and el.getAttribute("spam") == "ham" 0311 and el.attributes["spam"].isId) 0312 el.setAttribute("spam2", "bam") 0313 confirm(len(el.attributes) == 2 0314 and el.attributes["spam"].value == "ham" 0315 and el.attributes["spam"].nodeValue == "ham" 0316 and el.getAttribute("spam") == "ham" 0317 and el.attributes["spam2"].value == "bam" 0318 and el.attributes["spam2"].nodeValue == "bam" 0319 and el.getAttribute("spam2") == "bam") 0320 el.attributes["spam2"] = "bam2" 0321 confirm(len(el.attributes) == 2 0322 and el.attributes["spam"].value == "ham" 0323 and el.attributes["spam"].nodeValue == "ham" 0324 and el.getAttribute("spam") == "ham" 0325 and el.attributes["spam2"].value == "bam2" 0326 and el.attributes["spam2"].nodeValue == "bam2" 0327 and el.getAttribute("spam2") == "bam2") 0328 dom.unlink() 0329 0330 def testGetAttrList(): 0331 pass 0332 0333 def testGetAttrValues(): pass 0334 0335 def testGetAttrLength(): pass 0336 0337 def testGetAttribute(): pass 0338 0339 def testGetAttributeNS(): pass 0340 0341 def testGetAttributeNode(): pass 0342 0343 def testGetElementsByTagNameNS(): 0344 d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'> 0345 <minidom:myelem/> 0346 </foo>""" 0347 dom = parseString(d) 0348 elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom", "myelem") 0349 confirm(len(elems) == 1 0350 and elems[0].namespaceURI == "http://pyxml.sf.net/minidom" 0351 and elems[0].localName == "myelem" 0352 and elems[0].prefix == "minidom" 0353 and elems[0].tagName == "minidom:myelem" 0354 and elems[0].nodeName == "minidom:myelem") 0355 dom.unlink() 0356 0357 def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc, nsuri, lname): 0358 nodelist = doc.getElementsByTagNameNS(nsuri, lname) 0359 confirm(len(nodelist) == 0) 0360 0361 def testGetEmptyNodeListFromElementsByTagNameNS(): 0362 doc = parseString('<doc/>') 0363 get_empty_nodelist_from_elements_by_tagName_ns_helper( 0364 doc, 'http://xml.python.org/namespaces/a', 'localname') 0365 get_empty_nodelist_from_elements_by_tagName_ns_helper( 0366 doc, '*', 'splat') 0367 get_empty_nodelist_from_elements_by_tagName_ns_helper( 0368 doc, 'http://xml.python.org/namespaces/a', '*') 0369 0370 doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>') 0371 get_empty_nodelist_from_elements_by_tagName_ns_helper( 0372 doc, "http://xml.python.org/splat", "not-there") 0373 get_empty_nodelist_from_elements_by_tagName_ns_helper( 0374 doc, "*", "not-there") 0375 get_empty_nodelist_from_elements_by_tagName_ns_helper( 0376 doc, "http://somewhere.else.net/not-there", "e") 0377 0378 def testElementReprAndStr(): 0379 dom = Document() 0380 el = dom.appendChild(dom.createElement("abc")) 0381 string1 = repr(el) 0382 string2 = str(el) 0383 confirm(string1 == string2) 0384 dom.unlink() 0385 0386 # commented out until Fredrick's fix is checked in 0387 def _testElementReprAndStrUnicode(): 0388 dom = Document() 0389 el = dom.appendChild(dom.createElement(u"abc")) 0390 string1 = repr(el) 0391 string2 = str(el) 0392 confirm(string1 == string2) 0393 dom.unlink() 0394 0395 # commented out until Fredrick's fix is checked in 0396 def _testElementReprAndStrUnicodeNS(): 0397 dom = Document() 0398 el = dom.appendChild( 0399 dom.createElementNS(u"http://www.slashdot.org", u"slash:abc")) 0400 string1 = repr(el) 0401 string2 = str(el) 0402 confirm(string1 == string2) 0403 confirm(string1.find("slash:abc") != -1) 0404 dom.unlink() 0405 0406 def testAttributeRepr(): 0407 dom = Document() 0408 el = dom.appendChild(dom.createElement(u"abc")) 0409 node = el.setAttribute("abc", "def") 0410 confirm(str(node) == repr(node)) 0411 dom.unlink() 0412 0413 def testTextNodeRepr(): pass 0414 0415 def testWriteXML(): 0416 str = '<?xml version="1.0" ?>\n<a b="c"/>' 0417 dom = parseString(str) 0418 domstr = dom.toxml() 0419 dom.unlink() 0420 confirm(str == domstr) 0421 0422 def testProcessingInstruction(): 0423 dom = parseString('<e><?mypi \t\n data \t\n ?></e>') 0424 pi = dom.documentElement.firstChild 0425 confirm(pi.target == "mypi" 0426 and pi.data == "data \t\n " 0427 and pi.nodeName == "mypi" 0428 and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE 0429 and pi.attributes is None 0430 and not pi.hasChildNodes() 0431 and len(pi.childNodes) == 0 0432 and pi.firstChild is None 0433 and pi.lastChild is None 0434 and pi.localName is None 0435 and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE) 0436 0437 def testProcessingInstructionRepr(): pass 0438 0439 def testTextRepr(): pass 0440 0441 def testWriteText(): pass 0442 0443 def testDocumentElement(): pass 0444 0445 def testTooManyDocumentElements(): 0446 doc = parseString("<doc/>") 0447 elem = doc.createElement("extra") 0448 try: 0449 doc.appendChild(elem) 0450 except xml.dom.HierarchyRequestErr: 0451 pass 0452 else: 0453 print "Failed to catch expected exception when" \ 0454 " adding extra document element." 0455 elem.unlink() 0456 doc.unlink() 0457 0458 def testCreateElementNS(): pass 0459 0460 def testCreateAttributeNS(): pass 0461 0462 def testParse(): pass 0463 0464 def testParseString(): pass 0465 0466 def testComment(): pass 0467 0468 def testAttrListItem(): pass 0469 0470 def testAttrListItems(): pass 0471 0472 def testAttrListItemNS(): pass 0473 0474 def testAttrListKeys(): pass 0475 0476 def testAttrListKeysNS(): pass 0477 0478 def testRemoveNamedItem(): 0479 doc = parseString("<doc a=''/>") 0480 e = doc.documentElement 0481 attrs = e.attributes 0482 a1 = e.getAttributeNode("a") 0483 a2 = attrs.removeNamedItem("a") 0484 confirm(a1.isSameNode(a2)) 0485 try: 0486 attrs.removeNamedItem("a") 0487 except xml.dom.NotFoundErr: 0488 pass 0489 0490 def testRemoveNamedItemNS(): 0491 doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>") 0492 e = doc.documentElement 0493 attrs = e.attributes 0494 a1 = e.getAttributeNodeNS("http://xml.python.org/", "b") 0495 a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b") 0496 confirm(a1.isSameNode(a2)) 0497 try: 0498 attrs.removeNamedItemNS("http://xml.python.org/", "b") 0499 except xml.dom.NotFoundErr: 0500 pass 0501 0502 def testAttrListValues(): pass 0503 0504 def testAttrListLength(): pass 0505 0506 def testAttrList__getitem__(): pass 0507 0508 def testAttrList__setitem__(): pass 0509 0510 def testSetAttrValueandNodeValue(): pass 0511 0512 def testParseElement(): pass 0513 0514 def testParseAttributes(): pass 0515 0516 def testParseElementNamespaces(): pass 0517 0518 def testParseAttributeNamespaces(): pass 0519 0520 def testParseProcessingInstructions(): pass 0521 0522 def testChildNodes(): pass 0523 0524 def testFirstChild(): pass 0525 0526 def testHasChildNodes(): pass 0527 0528 def testCloneElementShallow(): 0529 dom, clone = _setupCloneElement(0) 0530 confirm(len(clone.childNodes) == 0 0531 and clone.childNodes.length == 0 0532 and clone.parentNode is None 0533 and clone.toxml() == '<doc attr="value"/>' 0534 , "testCloneElementShallow") 0535 dom.unlink() 0536 0537 def testCloneElementDeep(): 0538 dom, clone = _setupCloneElement(1) 0539 confirm(len(clone.childNodes) == 1 0540 and clone.childNodes.length == 1 0541 and clone.parentNode is None 0542 and clone.toxml() == '<doc attr="value"><foo/></doc>' 0543 , "testCloneElementDeep") 0544 dom.unlink() 0545 0546 def _setupCloneElement(deep): 0547 dom = parseString("<doc attr='value'><foo/></doc>") 0548 root = dom.documentElement 0549 clone = root.cloneNode(deep) 0550 _testCloneElementCopiesAttributes( 0551 root, clone, "testCloneElement" + (deep and "Deep" or "Shallow")) 0552 # mutilate the original so shared data is detected 0553 root.tagName = root.nodeName = "MODIFIED" 0554 root.setAttribute("attr", "NEW VALUE") 0555 root.setAttribute("added", "VALUE") 0556 return dom, clone 0557 0558 def _testCloneElementCopiesAttributes(e1, e2, test): 0559 attrs1 = e1.attributes 0560 attrs2 = e2.attributes 0561 keys1 = attrs1.keys() 0562 keys2 = attrs2.keys() 0563 keys1.sort() 0564 keys2.sort() 0565 confirm(keys1 == keys2, "clone of element has same attribute keys") 0566 for i in range(len(keys1)): 0567 a1 = attrs1.item(i) 0568 a2 = attrs2.item(i) 0569 confirm(a1 is not a2 0570 and a1.value == a2.value 0571 and a1.nodeValue == a2.nodeValue 0572 and a1.namespaceURI == a2.namespaceURI 0573 and a1.localName == a2.localName 0574 , "clone of attribute node has proper attribute values") 0575 confirm(a2.ownerElement is e2, 0576 "clone of attribute node correctly owned") 0577 0578 def testCloneDocumentShallow(): 0579 doc = parseString("<?xml version='1.0'?>\n" 0580 "<!-- comment -->" 0581 "<!DOCTYPE doc [\n" 0582 "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n" 0583 "]>\n" 0584 "<doc attr='value'/>") 0585 doc2 = doc.cloneNode(0) 0586 confirm(doc2 is None, 0587 "testCloneDocumentShallow:" 0588 " shallow cloning of documents makes no sense!") 0589 0590 def testCloneDocumentDeep(): 0591 doc = parseString("<?xml version='1.0'?>\n" 0592 "<!-- comment -->" 0593 "<!DOCTYPE doc [\n" 0594 "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n" 0595 "]>\n" 0596 "<doc attr='value'/>") 0597 doc2 = doc.cloneNode(1) 0598 confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)), 0599 "testCloneDocumentDeep: document objects not distinct") 0600 confirm(len(doc.childNodes) == len(doc2.childNodes), 0601 "testCloneDocumentDeep: wrong number of Document children") 0602 confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE, 0603 "testCloneDocumentDeep: documentElement not an ELEMENT_NODE") 0604 confirm(doc2.documentElement.ownerDocument.isSameNode(doc2), 0605 "testCloneDocumentDeep: documentElement owner is not new document") 0606 confirm(not doc.documentElement.isSameNode(doc2.documentElement), 0607 "testCloneDocumentDeep: documentElement should not be shared") 0608 if doc.doctype is not None: 0609 # check the doctype iff the original DOM maintained it 0610 confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE, 0611 "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE") 0612 confirm(doc2.doctype.ownerDocument.isSameNode(doc2)) 0613 confirm(not doc.doctype.isSameNode(doc2.doctype)) 0614 0615 def testCloneDocumentTypeDeepOk(): 0616 doctype = create_nonempty_doctype() 0617 clone = doctype.cloneNode(1) 0618 confirm(clone is not None 0619 and clone.nodeName == doctype.nodeName 0620 and clone.name == doctype.name 0621 and clone.publicId == doctype.publicId 0622 and clone.systemId == doctype.systemId 0623 and len(clone.entities) == len(doctype.entities) 0624 and clone.entities.item(len(clone.entities)) is None 0625 and len(clone.notations) == len(doctype.notations) 0626 and clone.notations.item(len(clone.notations)) is None 0627 and len(clone.childNodes) == 0) 0628 for i in range(len(doctype.entities)): 0629 se = doctype.entities.item(i) 0630 ce = clone.entities.item(i) 0631 confirm((not se.isSameNode(ce)) 0632 and (not ce.isSameNode(se)) 0633 and ce.nodeName == se.nodeName 0634 and ce.notationName == se.notationName 0635 and ce.publicId == se.publicId 0636 and ce.systemId == se.systemId 0637 and ce.encoding == se.encoding 0638 and ce.actualEncoding == se.actualEncoding 0639 and ce.version == se.version) 0640 for i in range(len(doctype.notations)): 0641 sn = doctype.notations.item(i) 0642 cn = clone.notations.item(i) 0643 confirm((not sn.isSameNode(cn)) 0644 and (not cn.isSameNode(sn)) 0645 and cn.nodeName == sn.nodeName 0646 and cn.publicId == sn.publicId 0647 and cn.systemId == sn.systemId) 0648 0649 def testCloneDocumentTypeDeepNotOk(): 0650 doc = create_doc_with_doctype() 0651 clone = doc.doctype.cloneNode(1) 0652 confirm(clone is None, "testCloneDocumentTypeDeepNotOk") 0653 0654 def testCloneDocumentTypeShallowOk(): 0655 doctype = create_nonempty_doctype() 0656 clone = doctype.cloneNode(0) 0657 confirm(clone is not None 0658 and clone.nodeName == doctype.nodeName 0659 and clone.name == doctype.name 0660 and clone.publicId == doctype.publicId 0661 and clone.systemId == doctype.systemId 0662 and len(clone.entities) == 0 0663 and clone.entities.item(0) is None 0664 and len(clone.notations) == 0 0665 and clone.notations.item(0) is None 0666 and len(clone.childNodes) == 0) 0667 0668 def testCloneDocumentTypeShallowNotOk(): 0669 doc = create_doc_with_doctype() 0670 clone = doc.doctype.cloneNode(0) 0671 confirm(clone is None, "testCloneDocumentTypeShallowNotOk") 0672 0673 def check_import_document(deep, testName): 0674 doc1 = parseString("<doc/>") 0675 doc2 = parseString("<doc/>") 0676 try: 0677 doc1.importNode(doc2, deep) 0678 except xml.dom.NotSupportedErr: 0679 pass 0680 else: 0681 raise Exception(testName + 0682 ": expected NotSupportedErr when importing a document") 0683 0684 def testImportDocumentShallow(): 0685 check_import_document(0, "testImportDocumentShallow") 0686 0687 def testImportDocumentDeep(): 0688 check_import_document(1, "testImportDocumentDeep") 0689 0690 # The tests of DocumentType importing use these helpers to construct 0691 # the documents to work with, since not all DOM builders actually 0692 # create the DocumentType nodes. 0693 0694 def create_doc_without_doctype(doctype=None): 0695 return getDOMImplementation().createDocument(None, "doc", doctype) 0696 0697 def create_nonempty_doctype(): 0698 doctype = getDOMImplementation().createDocumentType("doc", None, None) 0699 doctype.entities._seq = [] 0700 doctype.notations._seq = [] 0701 notation = xml.dom.minidom.Notation("my-notation", None, 0702 "http://xml.python.org/notations/my") 0703 doctype.notations._seq.append(notation) 0704 entity = xml.dom.minidom.Entity("my-entity", None, 0705 "http://xml.python.org/entities/my", 0706 "my-notation") 0707 entity.version = "1.0" 0708 entity.encoding = "utf-8" 0709 entity.actualEncoding = "us-ascii" 0710 doctype.entities._seq.append(entity) 0711 return doctype 0712 0713 def create_doc_with_doctype(): 0714 doctype = create_nonempty_doctype() 0715 doc = create_doc_without_doctype(doctype) 0716 doctype.entities.item(0).ownerDocument = doc 0717 doctype.notations.item(0).ownerDocument = doc 0718 return doc 0719 0720 def testImportDocumentTypeShallow(): 0721 src = create_doc_with_doctype() 0722 target = create_doc_without_doctype() 0723 try: 0724 imported = target.importNode(src.doctype, 0) 0725 except xml.dom.NotSupportedErr: 0726 pass 0727 else: 0728 raise Exception( 0729 "testImportDocumentTypeShallow: expected NotSupportedErr") 0730 0731 def testImportDocumentTypeDeep(): 0732 src = create_doc_with_doctype() 0733 target = create_doc_without_doctype() 0734 try: 0735 imported = target.importNode(src.doctype, 1) 0736 except xml.dom.NotSupportedErr: 0737 pass 0738 else: 0739 raise Exception( 0740 "testImportDocumentTypeDeep: expected NotSupportedErr") 0741 0742 # Testing attribute clones uses a helper, and should always be deep, 0743 # even if the argument to cloneNode is false. 0744 def check_clone_attribute(deep, testName): 0745 doc = parseString("<doc attr='value'/>") 0746 attr = doc.documentElement.getAttributeNode("attr") 0747 assert attr is not None 0748 clone = attr.cloneNode(deep) 0749 confirm(not clone.isSameNode(attr)) 0750 confirm(not attr.isSameNode(clone)) 0751 confirm(clone.ownerElement is None, 0752 testName + ": ownerElement should be None") 0753 confirm(clone.ownerDocument.isSameNode(attr.ownerDocument), 0754 testName + ": ownerDocument does not match") 0755 confirm(clone.specified, 0756 testName + ": cloned attribute must have specified == True") 0757 0758 def testCloneAttributeShallow(): 0759 check_clone_attribute(0, "testCloneAttributeShallow") 0760 0761 def testCloneAttributeDeep(): 0762 check_clone_attribute(1, "testCloneAttributeDeep") 0763 0764 def check_clone_pi(deep, testName): 0765 doc = parseString("<?target data?><doc/>") 0766 pi = doc.firstChild 0767 assert pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE 0768 clone = pi.cloneNode(deep) 0769 confirm(clone.target == pi.target 0770 and clone.data == pi.data) 0771 0772 def testClonePIShallow(): 0773 check_clone_pi(0, "testClonePIShallow") 0774 0775 def testClonePIDeep(): 0776 check_clone_pi(1, "testClonePIDeep") 0777 0778 def testNormalize(): 0779 doc = parseString("<doc/>") 0780 root = doc.documentElement 0781 root.appendChild(doc.createTextNode("first")) 0782 root.appendChild(doc.createTextNode("second")) 0783 confirm(len(root.childNodes) == 2 0784 and root.childNodes.length == 2, "testNormalize -- preparation") 0785 doc.normalize() 0786 confirm(len(root.childNodes) == 1 0787 and root.childNodes.length == 1 0788 and root.firstChild is root.lastChild 0789 and root.firstChild.data == "firstsecond" 0790 , "testNormalize -- result") 0791 doc.unlink() 0792 0793 doc = parseString("<doc/>") 0794 root = doc.documentElement 0795 root.appendChild(doc.createTextNode("")) 0796 doc.normalize() 0797 confirm(len(root.childNodes) == 0 0798 and root.childNodes.length == 0, 0799 "testNormalize -- single empty node removed") 0800 doc.unlink() 0801 0802 def testSiblings(): 0803 doc = parseString("<doc><?pi?>text?<elm/></doc>") 0804 root = doc.documentElement 0805 (pi, text, elm) = root.childNodes 0806 0807 confirm(pi.nextSibling is text and 0808 pi.previousSibling is None and 0809 text.nextSibling is elm and 0810 text.previousSibling is pi and 0811 elm.nextSibling is None and 0812 elm.previousSibling is text, "testSiblings") 0813 0814 doc.unlink() 0815 0816 def testParents(): 0817 doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>") 0818 root = doc.documentElement 0819 elm1 = root.childNodes[0] 0820 (elm2a, elm2b) = elm1.childNodes 0821 elm3 = elm2b.childNodes[0] 0822 0823 confirm(root.parentNode is doc and 0824 elm1.parentNode is root and 0825 elm2a.parentNode is elm1 and 0826 elm2b.parentNode is elm1 and 0827 elm3.parentNode is elm2b, "testParents") 0828 0829 doc.unlink() 0830 0831 def testNodeListItem(): 0832 doc = parseString("<doc><e/><e/></doc>") 0833 children = doc.childNodes 0834 docelem = children[0] 0835 confirm(children[0] is children.item(0) 0836 and children.item(1) is None 0837 and docelem.childNodes.item(0) is docelem.childNodes[0] 0838 and docelem.childNodes.item(1) is docelem.childNodes[1] 0839 and docelem.childNodes.item(0).childNodes.item(0) is None, 0840 "test NodeList.item()") 0841 doc.unlink() 0842 0843 def testSAX2DOM(): 0844 from xml.dom import pulldom 0845 0846 sax2dom = pulldom.SAX2DOM() 0847 sax2dom.startDocument() 0848 sax2dom.startElement("doc", {}) 0849 sax2dom.characters("text") 0850 sax2dom.startElement("subelm", {}) 0851 sax2dom.characters("text") 0852 sax2dom.endElement("subelm") 0853 sax2dom.characters("text") 0854 sax2dom.endElement("doc") 0855 sax2dom.endDocument() 0856 0857 doc = sax2dom.document 0858 root = doc.documentElement 0859 (text1, elm1, text2) = root.childNodes 0860 text3 = elm1.childNodes[0] 0861 0862 confirm(text1.previousSibling is None and 0863 text1.nextSibling is elm1 and 0864 elm1.previousSibling is text1 and 0865 elm1.nextSibling is text2 and 0866 text2.previousSibling is elm1 and 0867 text2.nextSibling is None and 0868 text3.previousSibling is None and 0869 text3.nextSibling is None, "testSAX2DOM - siblings") 0870 0871 confirm(root.parentNode is doc and 0872 text1.parentNode is root and 0873 elm1.parentNode is root and 0874 text2.parentNode is root and 0875 text3.parentNode is elm1, "testSAX2DOM - parents") 0876 0877 doc.unlink() 0878 0879 def testEncodings(): 0880 doc = parseString('<foo>€</foo>') 0881 confirm(doc.toxml() == u'<?xml version="1.0" ?>\n<foo>\u20ac</foo>' 0882 and doc.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?>\n<foo>\xe2\x82\xac</foo>' 0883 and doc.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?>\n<foo>\xa4</foo>', 0884 "testEncodings - encoding EURO SIGN") 0885 doc.unlink() 0886 0887 class UserDataHandler: 0888 called = 0 0889 def handle(self, operation, key, data, src, dst): 0890 dst.setUserData(key, data + 1, self) 0891 src.setUserData(key, None, None) 0892 self.called = 1 0893 0894 def testUserData(): 0895 dom = Document() 0896 n = dom.createElement('e') 0897 confirm(n.getUserData("foo") is None) 0898 n.setUserData("foo", None, None) 0899 confirm(n.getUserData("foo") is None) 0900 n.setUserData("foo", 12, 12) 0901 n.setUserData("bar", 13, 13) 0902 confirm(n.getUserData("foo") == 12) 0903 confirm(n.getUserData("bar") == 13) 0904 n.setUserData("foo", None, None) 0905 confirm(n.getUserData("foo") is None) 0906 confirm(n.getUserData("bar") == 13) 0907 0908 handler = UserDataHandler() 0909 n.setUserData("bar", 12, handler) 0910 c = n.cloneNode(1) 0911 confirm(handler.called 0912 and n.getUserData("bar") is None 0913 and c.getUserData("bar") == 13) 0914 n.unlink() 0915 c.unlink() 0916 dom.unlink() 0917 0918 def testRenameAttribute(): 0919 doc = parseString("<doc a='v'/>") 0920 elem = doc.documentElement 0921 attrmap = elem.attributes 0922 attr = elem.attributes['a'] 0923 0924 # Simple renaming 0925 attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b") 0926 confirm(attr.name == "b" 0927 and attr.nodeName == "b" 0928 and attr.localName is None 0929 and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE 0930 and attr.prefix is None 0931 and attr.value == "v" 0932 and elem.getAttributeNode("a") is None 0933 and elem.getAttributeNode("b").isSameNode(attr) 0934 and attrmap["b"].isSameNode(attr) 0935 and attr.ownerDocument.isSameNode(doc) 0936 and attr.ownerElement.isSameNode(elem)) 0937 0938 # Rename to have a namespace, no prefix 0939 attr = doc.renameNode(attr, "http://xml.python.org/ns", "c") 0940 confirm(attr.name == "c" 0941 and attr.nodeName == "c" 0942 and attr.localName == "c" 0943 and attr.namespaceURI == "http://xml.python.org/ns" 0944 and attr.prefix is None 0945 and attr.value == "v" 0946 and elem.getAttributeNode("a") is None 0947 and elem.getAttributeNode("b") is None 0948 and elem.getAttributeNode("c").isSameNode(attr) 0949 and elem.getAttributeNodeNS( 0950 "http://xml.python.org/ns", "c").isSameNode(attr) 0951 and attrmap["c"].isSameNode(attr) 0952 and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr)) 0953 0954 # Rename to have a namespace, with prefix 0955 attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d") 0956 confirm(attr.name == "p:d" 0957 and attr.nodeName == "p:d" 0958 and attr.localName == "d" 0959 and attr.namespaceURI == "http://xml.python.org/ns2" 0960 and attr.prefix == "p" 0961 and attr.value == "v" 0962 and elem.getAttributeNode("a") is None 0963 and elem.getAttributeNode("b") is None 0964 and elem.getAttributeNode("c") is None 0965 and elem.getAttributeNodeNS( 0966 "http://xml.python.org/ns", "c") is None 0967 and elem.getAttributeNode("p:d").isSameNode(attr) 0968 and elem.getAttributeNodeNS( 0969 "http://xml.python.org/ns2", "d").isSameNode(attr) 0970 and attrmap["p:d"].isSameNode(attr) 0971 and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr)) 0972 0973 # Rename back to a simple non-NS node 0974 attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e") 0975 confirm(attr.name == "e" 0976 and attr.nodeName == "e" 0977 and attr.localName is None 0978 and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE 0979 and attr.prefix is None 0980 and attr.value == "v" 0981 and elem.getAttributeNode("a") is None 0982 and elem.getAttributeNode("b") is None 0983 and elem.getAttributeNode("c") is None 0984 and elem.getAttributeNode("p:d") is None 0985 and elem.getAttributeNodeNS( 0986 "http://xml.python.org/ns", "c") is None 0987 and elem.getAttributeNode("e").isSameNode(attr) 0988 and attrmap["e"].isSameNode(attr)) 0989 0990 try: 0991 doc.renameNode(attr, "http://xml.python.org/ns", "xmlns") 0992 except xml.dom.NamespaceErr: 0993 pass 0994 else: 0995 print "expected NamespaceErr" 0996 0997 checkRenameNodeSharedConstraints(doc, attr) 0998 doc.unlink() 0999 1000 def testRenameElement(): 1001 doc = parseString("<doc/>") 1002 elem = doc.documentElement 1003 1004 # Simple renaming 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)) 1012 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)) 1021 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)) 1030 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)) 1039 1040 checkRenameNodeSharedConstraints(doc, elem) 1041 doc.unlink() 1042 1043 def checkRenameNodeSharedConstraints(doc, node): 1044 # Make sure illegal NS usage is detected: 1045 try: 1046 doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo") 1047 except xml.dom.NamespaceErr: 1048 pass 1049 else: 1050 print "expected NamespaceErr" 1051 1052 doc2 = parseString("<doc/>") 1053 try: 1054 doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo") 1055 except xml.dom.WrongDocumentErr: 1056 pass 1057 else: 1058 print "expected WrongDocumentErr" 1059 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") 1066 try: 1067 doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo") 1068 except xml.dom.NotSupportedErr: 1069 pass 1070 else: 1071 print "expected NotSupportedErr when renaming comment node" 1072 doc.unlink() 1073 1074 def checkWholeText(node, s): 1075 t = node.wholeText 1076 confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t))) 1077 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 1083 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") 1089 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") 1097 1098 x = doc.createElement("x") 1099 elem.replaceChild(x, splitter) 1100 splitter = x 1101 checkWholeText(text, "cab") 1102 checkWholeText(text2, "d") 1103 1104 x = doc.createProcessingInstruction("y", "z") 1105 elem.replaceChild(x, splitter) 1106 splitter = x 1107 checkWholeText(text, "cab") 1108 checkWholeText(text2, "d") 1109 1110 elem.removeChild(splitter) 1111 checkWholeText(text, "cabd") 1112 checkWholeText(text2, "cabd") 1113 1114 def testReplaceWholeText(): 1115 def setup(): 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 1124 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) 1130 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) 1136 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) 1142 1143 def testSchemaType(): 1144 doc = parseString( 1145 "<!DOCTYPE doc [\n" 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" 1157 " >\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. 1166 t = elem.schemaType 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() 1170 for name in names: 1171 a = elem.getAttributeNode(name) 1172 t = a.schemaType 1173 confirm(hasattr(t, "name") 1174 and t.namespace == xml.dom.EMPTY_NAMESPACE) 1175 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 1182 and not a1.isId 1183 and not a2.isId) 1184 e.setIdAttribute("a1") 1185 confirm(e.isSameNode(doc.getElementById("v")) 1186 and a1.isId 1187 and not a2.isId) 1188 e.setIdAttribute("a2") 1189 confirm(e.isSameNode(doc.getElementById("v")) 1190 and e.isSameNode(doc.getElementById("w")) 1191 and a1.isId 1192 and a2.isId) 1193 # replace the a1 node; the new node should *not* be an ID 1194 a3 = doc.createAttribute("a1") 1195 a3.value = "v" 1196 e.setAttributeNode(a3) 1197 confirm(doc.getElementById("v") is None 1198 and e.isSameNode(doc.getElementById("w")) 1199 and not a1.isId 1200 and a2.isId 1201 and not a3.isId) 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")) 1205 and a2.isId) 1206 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 1218 and not a1.isId 1219 and not a2.isId) 1220 e.setIdAttributeNS(NS1, "a1") 1221 confirm(e.isSameNode(doc.getElementById("v")) 1222 and a1.isId 1223 and not a2.isId) 1224 e.setIdAttributeNS(NS2, "a2") 1225 confirm(e.isSameNode(doc.getElementById("v")) 1226 and e.isSameNode(doc.getElementById("w")) 1227 and a1.isId 1228 and a2.isId) 1229 # replace the a1 node; the new node should *not* be an ID 1230 a3 = doc.createAttributeNS(NS1, "a1") 1231 a3.value = "v" 1232 e.setAttributeNode(a3) 1233 confirm(e.isSameNode(doc.getElementById("w"))) 1234 confirm(not a1.isId) 1235 confirm(a2.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")) 1241 and a2.isId) 1242 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 1254 and not a1.isId 1255 and not a2.isId) 1256 e.setIdAttributeNode(a1) 1257 confirm(e.isSameNode(doc.getElementById("v")) 1258 and a1.isId 1259 and not a2.isId) 1260 e.setIdAttributeNode(a2) 1261 confirm(e.isSameNode(doc.getElementById("v")) 1262 and e.isSameNode(doc.getElementById("w")) 1263 and a1.isId 1264 and a2.isId) 1265 # replace the a1 node; the new node should *not* be an ID 1266 a3 = doc.createAttributeNS(NS1, "a1") 1267 a3.value = "v" 1268 e.setAttributeNode(a3) 1269 confirm(e.isSameNode(doc.getElementById("w"))) 1270 confirm(not a1.isId) 1271 confirm(a2.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")) 1277 and a2.isId) 1278 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)] 1290 while stack: 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: 1298 len(n1.entities) 1299 len(n2.entities) 1300 len(n1.notations) 1301 len(n2.notations) 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])) 1323 1324 1325 # --- MAIN PROGRAM 1326 1327 names = globals().keys() 1328 names.sort() 1329 1330 failed = [] 1331 1332 try: 1333 Node.allnodes 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(): 1338 pass 1339 else: 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:" 1345 if verbose: 1346 print Node.allnodes.items()[0:10] 1347 else: 1348 # Don't print specific nodes if repeatable results 1349 # are needed 1350 print len(Node.allnodes) 1351 Node.allnodes = {} 1352 1353 for name in names: 1354 if name.startswith("test"): 1355 func = globals()[name] 1356 try: 1357 func() 1358 check_allnodes() 1359 except: 1360 failed.append(name) 1361 print "Test Failed: ", name 1362 sys.stdout.flush() 1363 traceback.print_exception(*sys.exc_info()) 1364 print repr(sys.exc_info()[1]) 1365 Node.allnodes = {} 1366 1367 if failed: 1368 print "\n\n\n**** Check for failures in these tests:" 1369 for name in failed: 1370 print " " + name 1371
Generated by PyXR 0.9.4