Home | Trees | Indices | Help |
|
---|
|
1 # -*- coding: utf-8 -*- 2 3 """ 4 Tests specific to the extended etree API 5 6 Tests that apply to the general ElementTree API should go into 7 test_elementtree 8 """ 9 10 import os.path 11 import unittest 12 import copy 13 import sys 14 import re 15 import operator 16 import tempfile 17 import gzip 18 19 this_dir = os.path.dirname(__file__) 20 if this_dir not in sys.path: 21 sys.path.insert(0, this_dir) # needed for Py3 22 23 from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir 24 from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest 25 from common_imports import canonicalize, sorted, _str, _bytes 26 27 print("") 28 print("TESTED VERSION: %s" % etree.__version__) 29 print(" Python: " + repr(sys.version_info)) 30 print(" lxml.etree: " + repr(etree.LXML_VERSION)) 31 print(" libxml used: " + repr(etree.LIBXML_VERSION)) 32 print(" libxml compiled: " + repr(etree.LIBXML_COMPILED_VERSION)) 33 print(" libxslt used: " + repr(etree.LIBXSLT_VERSION)) 34 print(" libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION)) 35 print("") 36 37 try: 38 _unicode = unicode 39 except NameError: 40 # Python 3 41 _unicode = str 4244 """Tests only for etree, not ElementTree""" 45 etree = etree 4655848 self.assert_(isinstance(etree.__version__, _unicode)) 49 self.assert_(isinstance(etree.LXML_VERSION, tuple)) 50 self.assertEqual(len(etree.LXML_VERSION), 4) 51 self.assert_(isinstance(etree.LXML_VERSION[0], int)) 52 self.assert_(isinstance(etree.LXML_VERSION[1], int)) 53 self.assert_(isinstance(etree.LXML_VERSION[2], int)) 54 self.assert_(isinstance(etree.LXML_VERSION[3], int)) 55 self.assert_(etree.__version__.startswith( 56 str(etree.LXML_VERSION[0])))5759 if hasattr(self.etree, '__pyx_capi__'): 60 # newer Pyrex compatible C-API 61 self.assert_(isinstance(self.etree.__pyx_capi__, dict)) 62 self.assert_(len(self.etree.__pyx_capi__) > 0) 63 else: 64 # older C-API mechanism 65 self.assert_(hasattr(self.etree, '_import_c_api'))6668 Element = self.etree.Element 69 el = Element('name') 70 self.assertEquals(el.tag, 'name') 71 el = Element('{}name') 72 self.assertEquals(el.tag, 'name')7375 Element = self.etree.Element 76 el = Element('name') 77 self.assertRaises(ValueError, Element, '{}') 78 self.assertRaises(ValueError, setattr, el, 'tag', '{}') 79 80 self.assertRaises(ValueError, Element, '{test}') 81 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')8284 Element = self.etree.Element 85 self.assertRaises(ValueError, Element, 'p:name') 86 self.assertRaises(ValueError, Element, '{test}p:name') 87 88 el = Element('name') 89 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')9092 Element = self.etree.Element 93 self.assertRaises(ValueError, Element, "p'name") 94 self.assertRaises(ValueError, Element, 'p"name') 95 96 self.assertRaises(ValueError, Element, "{test}p'name") 97 self.assertRaises(ValueError, Element, '{test}p"name') 98 99 el = Element('name') 100 self.assertRaises(ValueError, setattr, el, 'tag', "p'name") 101 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')102104 Element = self.etree.Element 105 self.assertRaises(ValueError, Element, ' name ') 106 self.assertRaises(ValueError, Element, 'na me') 107 self.assertRaises(ValueError, Element, '{test} name') 108 109 el = Element('name') 110 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')111113 Element = self.etree.Element 114 SubElement = self.etree.SubElement 115 116 el = Element('name') 117 self.assertRaises(ValueError, SubElement, el, '{}') 118 self.assertRaises(ValueError, SubElement, el, '{test}')119121 Element = self.etree.Element 122 SubElement = self.etree.SubElement 123 124 el = Element('name') 125 self.assertRaises(ValueError, SubElement, el, 'p:name') 126 self.assertRaises(ValueError, SubElement, el, '{test}p:name')127129 Element = self.etree.Element 130 SubElement = self.etree.SubElement 131 132 el = Element('name') 133 self.assertRaises(ValueError, SubElement, el, "p'name") 134 self.assertRaises(ValueError, SubElement, el, "{test}p'name") 135 136 self.assertRaises(ValueError, SubElement, el, 'p"name') 137 self.assertRaises(ValueError, SubElement, el, '{test}p"name')138140 Element = self.etree.Element 141 SubElement = self.etree.SubElement 142 143 el = Element('name') 144 self.assertRaises(ValueError, SubElement, el, ' name ') 145 self.assertRaises(ValueError, SubElement, el, 'na me') 146 self.assertRaises(ValueError, SubElement, el, '{test} name')147149 Element = self.etree.Element 150 SubElement = self.etree.SubElement 151 152 el = Element('name') 153 self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'}) 154 self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'}) 155 self.assertEquals(0, len(el))156158 QName = self.etree.QName 159 self.assertRaises(ValueError, QName, '') 160 self.assertRaises(ValueError, QName, 'test', '')161163 QName = self.etree.QName 164 self.assertRaises(ValueError, QName, 'p:name') 165 self.assertRaises(ValueError, QName, 'test', 'p:name')166168 QName = self.etree.QName 169 self.assertRaises(ValueError, QName, ' name ') 170 self.assertRaises(ValueError, QName, 'na me') 171 self.assertRaises(ValueError, QName, 'test', ' name')172174 # ET doesn't have namespace/localname properties on QNames 175 QName = self.etree.QName 176 namespace, localname = 'http://myns', 'a' 177 qname = QName(namespace, localname) 178 self.assertEquals(namespace, qname.namespace) 179 self.assertEquals(localname, qname.localname)180182 # ET doesn't have namespace/localname properties on QNames 183 QName = self.etree.QName 184 qname1 = QName('http://myns', 'a') 185 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'}) 186 187 qname2 = QName(a) 188 self.assertEquals(a.tag, qname1.text) 189 self.assertEquals(qname1.text, qname2.text) 190 self.assertEquals(qname1, qname2)191193 # ET doesn't resove QNames as text values 194 etree = self.etree 195 qname = etree.QName('http://myns', 'a') 196 a = etree.Element(qname, nsmap={'p' : 'http://myns'}) 197 a.text = qname 198 199 self.assertEquals("p:a", a.text)200202 etree = self.etree 203 self.assertRaises(ValueError, 204 etree.Element, "root", nsmap={'"' : 'testns'}) 205 self.assertRaises(ValueError, 206 etree.Element, "root", nsmap={'&' : 'testns'}) 207 self.assertRaises(ValueError, 208 etree.Element, "root", nsmap={'a:b' : 'testns'})209211 Element = self.etree.Element 212 root = Element("root") 213 root.set("attr", "TEST") 214 self.assertEquals("TEST", root.get("attr"))215217 # ElementTree accepts arbitrary attribute values 218 # lxml.etree allows only strings 219 Element = self.etree.Element 220 root = Element("root") 221 self.assertRaises(TypeError, root.set, "newattr", 5) 222 self.assertRaises(TypeError, root.set, "newattr", None)223225 XML = self.etree.XML 226 xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>') 227 228 root = XML(xml) 229 self.etree.strip_attributes(root, 'a') 230 self.assertEquals(_bytes('<test b="10" c="20"><x b="2"></x></test>'), 231 self._writeElement(root)) 232 233 root = XML(xml) 234 self.etree.strip_attributes(root, 'b', 'c') 235 self.assertEquals(_bytes('<test a="5"><x a="4"></x></test>'), 236 self._writeElement(root))237239 XML = self.etree.XML 240 xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>') 241 242 root = XML(xml) 243 self.etree.strip_attributes(root, 'a') 244 self.assertEquals( 245 _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'), 246 self._writeElement(root)) 247 248 root = XML(xml) 249 self.etree.strip_attributes(root, '{http://test/ns}a', 'c') 250 self.assertEquals( 251 _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'), 252 self._writeElement(root)) 253 254 root = XML(xml) 255 self.etree.strip_attributes(root, '{http://test/ns}*') 256 self.assertEquals( 257 _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'), 258 self._writeElement(root))259261 XML = self.etree.XML 262 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>') 263 264 root = XML(xml) 265 self.etree.strip_elements(root, 'a') 266 self.assertEquals(_bytes('<test><x></x></test>'), 267 self._writeElement(root)) 268 269 root = XML(xml) 270 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z') 271 self.assertEquals(_bytes('<test><a></a><x><a></a></x></test>'), 272 self._writeElement(root)) 273 274 root = XML(xml) 275 self.etree.strip_elements(root, 'c') 276 self.assertEquals(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'), 277 self._writeElement(root))278280 XML = self.etree.XML 281 xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>C</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>') 282 283 root = XML(xml) 284 self.etree.strip_elements(root, 'a') 285 self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X</x>XT</test>'), 286 self._writeElement(root)) 287 288 root = XML(xml) 289 self.etree.strip_elements(root, '{urn:a}b', 'c') 290 self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 291 self._writeElement(root)) 292 293 root = XML(xml) 294 self.etree.strip_elements(root, '{urn:a}*', 'c') 295 self.assertEquals(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 296 self._writeElement(root)) 297 298 root = XML(xml) 299 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False) 300 self.assertEquals(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 301 self._writeElement(root))302 321 347 374 400 419421 # lxml.etree separates target and text 422 Element = self.etree.Element 423 SubElement = self.etree.SubElement 424 ProcessingInstruction = self.etree.ProcessingInstruction 425 426 a = Element('a') 427 a.append(ProcessingInstruction('foo', 'some more text')) 428 self.assertEquals(a[0].target, 'foo') 429 self.assertEquals(a[0].text, 'some more text')430432 XML = self.etree.XML 433 root = XML(_bytes("<test><?mypi my test ?></test>")) 434 self.assertEquals(root[0].target, "mypi") 435 self.assertEquals(root[0].text, "my test ")436438 # previously caused a crash 439 ProcessingInstruction = self.etree.ProcessingInstruction 440 441 a = ProcessingInstruction("PI", "ONE") 442 b = copy.deepcopy(a) 443 b.text = "ANOTHER" 444 445 self.assertEquals('ONE', a.text) 446 self.assertEquals('ANOTHER', b.text)447449 XML = self.etree.XML 450 tostring = self.etree.tostring 451 root = XML(_bytes("<?mypi my test ?><test/><!--comment -->")) 452 tree1 = self.etree.ElementTree(root) 453 self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"), 454 tostring(tree1)) 455 456 tree2 = copy.deepcopy(tree1) 457 self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"), 458 tostring(tree2)) 459 460 root2 = copy.deepcopy(tree1.getroot()) 461 self.assertEquals(_bytes("<test/>"), 462 tostring(root2))463465 XML = self.etree.XML 466 tostring = self.etree.tostring 467 xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') 468 root = XML(xml) 469 tree1 = self.etree.ElementTree(root) 470 self.assertEquals(xml, tostring(tree1)) 471 472 tree2 = copy.deepcopy(tree1) 473 self.assertEquals(xml, tostring(tree2)) 474 475 root2 = copy.deepcopy(tree1.getroot()) 476 self.assertEquals(_bytes("<test/>"), 477 tostring(root2))478480 # ElementTree accepts arbitrary attribute values 481 # lxml.etree allows only strings 482 Element = self.etree.Element 483 484 root = Element("root") 485 root.set("attr", "TEST") 486 self.assertEquals("TEST", root.get("attr")) 487 self.assertRaises(TypeError, root.set, "newattr", 5)488490 fromstring = self.etree.fromstring 491 tostring = self.etree.tostring 492 XMLParser = self.etree.XMLParser 493 494 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 495 parser = XMLParser(remove_comments=True) 496 root = fromstring(xml, parser) 497 self.assertEquals( 498 _bytes('<a><b><c/></b></a>'), 499 tostring(root))500502 parse = self.etree.parse 503 tostring = self.etree.tostring 504 XMLParser = self.etree.XMLParser 505 506 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>') 507 508 f = BytesIO(xml) 509 tree = parse(f) 510 self.assertEquals( 511 xml, 512 tostring(tree)) 513 514 parser = XMLParser(remove_pis=True) 515 tree = parse(f, parser) 516 self.assertEquals( 517 _bytes('<a><b><c/></b></a>'), 518 tostring(tree))519521 # ET raises IOError only 522 parse = self.etree.parse 523 self.assertRaises(TypeError, parse, 'notthere.xml', object())524526 # ET removes comments 527 iterparse = self.etree.iterparse 528 tostring = self.etree.tostring 529 530 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 531 events = list(iterparse(f)) 532 root = events[-1][1] 533 self.assertEquals(3, len(events)) 534 self.assertEquals( 535 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 536 tostring(root))537539 # ET removes comments 540 iterparse = self.etree.iterparse 541 tostring = self.etree.tostring 542 543 def name(event, el): 544 if event == 'comment': 545 return el.text 546 else: 547 return el.tag548 549 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 550 events = list(iterparse(f, events=('end', 'comment'))) 551 root = events[-1][1] 552 self.assertEquals(6, len(events)) 553 self.assertEquals(['A', ' B ', 'c', 'b', 'C', 'a'], 554 [ name(*item) for item in events ]) 555 self.assertEquals( 556 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 557 tostring(root))560 # ET removes pis 561 iterparse = self.etree.iterparse 562 tostring = self.etree.tostring 563 ElementTree = self.etree.ElementTree 564 565 def name(event, el): 566 if event == 'pi': 567 return (el.target, el.text) 568 else: 569 return el.tag570 571 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>') 572 events = list(iterparse(f, events=('end', 'pi'))) 573 root = events[-2][1] 574 self.assertEquals(8, len(events)) 575 self.assertEquals([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b', 576 ('pid','d'), 'a', ('pie','e')], 577 [ name(*item) for item in events ]) 578 self.assertEquals( 579 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'), 580 tostring(ElementTree(root))) 581583 iterparse = self.etree.iterparse 584 tostring = self.etree.tostring 585 586 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 587 events = list(iterparse(f, remove_comments=True, 588 events=('end', 'comment'))) 589 root = events[-1][1] 590 self.assertEquals(3, len(events)) 591 self.assertEquals(['c', 'b', 'a'], 592 [ el.tag for (event, el) in events ]) 593 self.assertEquals( 594 _bytes('<a><b><c/></b></a>'), 595 tostring(root))596598 iterparse = self.etree.iterparse 599 f = BytesIO('<a><b><c/></a>') 600 # ET raises ExpatError, lxml raises XMLSyntaxError 601 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))602604 iterparse = self.etree.iterparse 605 f = BytesIO(""" 606 <a> \n \n <b> b test </b> \n 607 608 \n\t <c> \n </c> </a> \n """) 609 iterator = iterparse(f, remove_blank_text=True) 610 text = [ (element.text, element.tail) 611 for event, element in iterator ] 612 self.assertEquals( 613 [(" b test ", None), (" \n ", None), (None, None)], 614 text)615617 iterparse = self.etree.iterparse 618 f = BytesIO('<a><b><d/></b><c/></a>') 619 620 iterator = iterparse(f, tag="b", events=('start', 'end')) 621 events = list(iterator) 622 root = iterator.root 623 self.assertEquals( 624 [('start', root[0]), ('end', root[0])], 625 events)626628 iterparse = self.etree.iterparse 629 f = BytesIO('<a><b><d/></b><c/></a>') 630 631 iterator = iterparse(f, tag="*", events=('start', 'end')) 632 events = list(iterator) 633 self.assertEquals( 634 8, 635 len(events))636638 text = _str('Søk på nettet') 639 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 640 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 641 ).encode('iso-8859-1') 642 643 self.assertRaises(self.etree.ParseError, 644 list, self.etree.iterparse(BytesIO(xml_latin1)))645647 text = _str('Søk på nettet', encoding="UTF-8") 648 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 649 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 650 ).encode('iso-8859-1') 651 652 iterator = self.etree.iterparse(BytesIO(xml_latin1), 653 encoding="iso-8859-1") 654 self.assertEquals(1, len(list(iterator))) 655 656 a = iterator.root 657 self.assertEquals(a.text, text)658660 tostring = self.etree.tostring 661 f = BytesIO('<root><![CDATA[test]]></root>') 662 context = self.etree.iterparse(f, strip_cdata=False) 663 content = [ el.text for event,el in context ] 664 665 self.assertEquals(['test'], content) 666 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 667 tostring(context.root))668 672674 self.etree.XMLParser(encoding="ascii") 675 self.etree.XMLParser(encoding="utf-8") 676 self.etree.XMLParser(encoding="iso-8859-1")677679 parser = self.etree.XMLParser(recover=True) 680 681 parser.feed('<?xml version=') 682 parser.feed('"1.0"?><ro') 683 parser.feed('ot><') 684 parser.feed('a test="works"') 685 parser.feed('><othertag/></root') # <a> not closed! 686 parser.feed('>') 687 688 root = parser.close() 689 690 self.assertEquals(root.tag, "root") 691 self.assertEquals(len(root), 1) 692 self.assertEquals(root[0].tag, "a") 693 self.assertEquals(root[0].get("test"), "works") 694 self.assertEquals(len(root[0]), 1) 695 self.assertEquals(root[0][0].tag, "othertag")696 # FIXME: would be nice to get some errors logged ... 697 #self.assert_(len(parser.error_log) > 0, "error log is empty") 698700 assertEquals = self.assertEquals 701 assertFalse = self.assertFalse 702 703 events = [] 704 class Target(object): 705 def start(self, tag, attrib): 706 events.append("start") 707 assertFalse(attrib) 708 assertEquals("TAG", tag)709 def end(self, tag): 710 events.append("end") 711 assertEquals("TAG", tag) 712 def close(self): 713 return "DONE" # no Element! 714 715 parser = self.etree.XMLParser(target=Target()) 716 tree = self.etree.ElementTree() 717 718 self.assertRaises(TypeError, 719 tree.parse, BytesIO("<TAG/>"), parser=parser) 720 self.assertEquals(["start", "end"], events) 721723 events = [] 724 class Target(object): 725 def start(self, tag, attrib): 726 events.append("start-" + tag)727 def end(self, tag): 728 events.append("end-" + tag) 729 def data(self, data): 730 events.append("data-" + data) 731 def comment(self, text): 732 events.append("comment-" + text) 733 def close(self): 734 return "DONE" 735 736 parser = self.etree.XMLParser(target=Target()) 737 738 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')) 739 done = parser.close() 740 741 self.assertEquals("DONE", done) 742 self.assertEquals(["comment-a", "start-root", "data-A", "comment-b", 743 "start-sub", "end-sub", "comment-c", "data-B", 744 "end-root", "comment-d"], 745 events) 746748 events = [] 749 class Target(object): 750 def start(self, tag, attrib): 751 events.append("start-" + tag)752 def end(self, tag): 753 events.append("end-" + tag) 754 def data(self, data): 755 events.append("data-" + data) 756 def pi(self, target, data): 757 events.append("pi-" + target + "-" + data) 758 def close(self): 759 return "DONE" 760 761 parser = self.etree.XMLParser(target=Target()) 762 763 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>')) 764 done = parser.close() 765 766 self.assertEquals("DONE", done) 767 self.assertEquals(["pi-test-a", "start-root", "data-A", "pi-test-b", 768 "data-B", "end-root", "pi-test-c"], 769 events) 770772 events = [] 773 class Target(object): 774 def start(self, tag, attrib): 775 events.append("start-" + tag)776 def end(self, tag): 777 events.append("end-" + tag) 778 def data(self, data): 779 events.append("data-" + data) 780 def close(self): 781 return "DONE" 782 783 parser = self.etree.XMLParser(target=Target(), 784 strip_cdata=False) 785 786 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>')) 787 done = parser.close() 788 789 self.assertEquals("DONE", done) 790 self.assertEquals(["start-root", "data-A", "start-a", 791 "data-ca", "end-a", "data-B", "end-root"], 792 events) 793795 events = [] 796 class Target(object): 797 def start(self, tag, attrib): 798 events.append("start-" + tag)799 def end(self, tag): 800 events.append("end-" + tag) 801 def data(self, data): 802 events.append("data-" + data) 803 def close(self): 804 events.append("close") 805 return "DONE" 806 807 parser = self.etree.XMLParser(target=Target(), 808 recover=True) 809 810 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>')) 811 done = parser.close() 812 813 self.assertEquals("DONE", done) 814 self.assertEquals(["start-root", "data-A", "start-a", 815 "data-ca", "end-a", "data-B", 816 "end-root", "close"], 817 events) 818820 iterwalk = self.etree.iterwalk 821 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 822 823 iterator = iterwalk(root, tag="b", events=('start', 'end')) 824 events = list(iterator) 825 self.assertEquals( 826 [('start', root[0]), ('end', root[0])], 827 events)828830 iterwalk = self.etree.iterwalk 831 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 832 833 iterator = iterwalk(root, tag="*", events=('start', 'end')) 834 events = list(iterator) 835 self.assertEquals( 836 8, 837 len(events))838840 iterwalk = self.etree.iterwalk 841 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 842 843 events = list(iterwalk(root)) 844 self.assertEquals( 845 [('end', root[0]), ('end', root[1]), ('end', root)], 846 events)847849 iterwalk = self.etree.iterwalk 850 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 851 852 iterator = iterwalk(root, events=('start',)) 853 events = list(iterator) 854 self.assertEquals( 855 [('start', root), ('start', root[0]), ('start', root[1])], 856 events)857859 iterwalk = self.etree.iterwalk 860 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 861 862 iterator = iterwalk(root, events=('start','end')) 863 events = list(iterator) 864 self.assertEquals( 865 [('start', root), ('start', root[0]), ('end', root[0]), 866 ('start', root[1]), ('end', root[1]), ('end', root)], 867 events)868870 iterwalk = self.etree.iterwalk 871 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 872 873 iterator = iterwalk(root) 874 for event, elem in iterator: 875 elem.clear() 876 877 self.assertEquals(0, 878 len(root))879881 iterwalk = self.etree.iterwalk 882 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')) 883 884 attr_name = '{testns}bla' 885 events = [] 886 iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 887 for event, elem in iterator: 888 events.append(event) 889 if event == 'start': 890 if elem.tag != '{ns1}a': 891 elem.set(attr_name, 'value') 892 893 self.assertEquals( 894 ['start-ns', 'start', 'start', 'start-ns', 'start', 895 'end', 'end-ns', 'end', 'end', 'end-ns'], 896 events) 897 898 self.assertEquals( 899 None, 900 root.get(attr_name)) 901 self.assertEquals( 902 'value', 903 root[0].get(attr_name))904906 iterwalk = self.etree.iterwalk 907 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 908 909 counts = [] 910 for event, elem in iterwalk(root): 911 counts.append(len(list(elem.getiterator()))) 912 self.assertEquals( 913 [1,2,1,4], 914 counts)915917 parse = self.etree.parse 918 parser = self.etree.XMLParser(dtd_validation=True) 919 assertEqual = self.assertEqual 920 test_url = _str("__nosuch.dtd") 921 922 class MyResolver(self.etree.Resolver): 923 def resolve(self, url, id, context): 924 assertEqual(url, test_url) 925 return self.resolve_string( 926 _str('''<!ENTITY myentity "%s"> 927 <!ELEMENT doc ANY>''') % url, context)928 929 parser.resolvers.add(MyResolver()) 930 931 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 932 tree = parse(StringIO(xml), parser) 933 root = tree.getroot() 934 self.assertEquals(root.text, test_url) 935937 parse = self.etree.parse 938 parser = self.etree.XMLParser(dtd_validation=True) 939 assertEqual = self.assertEqual 940 test_url = _str("__nosuch.dtd") 941 942 class MyResolver(self.etree.Resolver): 943 def resolve(self, url, id, context): 944 assertEqual(url, test_url) 945 return self.resolve_string( 946 (_str('''<!ENTITY myentity "%s"> 947 <!ELEMENT doc ANY>''') % url).encode('utf-8'), 948 context)949 950 parser.resolvers.add(MyResolver()) 951 952 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 953 tree = parse(StringIO(xml), parser) 954 root = tree.getroot() 955 self.assertEquals(root.text, test_url) 956958 parse = self.etree.parse 959 parser = self.etree.XMLParser(dtd_validation=True) 960 assertEqual = self.assertEqual 961 test_url = _str("__nosuch.dtd") 962 963 class MyResolver(self.etree.Resolver): 964 def resolve(self, url, id, context): 965 assertEqual(url, test_url) 966 return self.resolve_file( 967 SillyFileLike( 968 _str('''<!ENTITY myentity "%s"> 969 <!ELEMENT doc ANY>''') % url), context)970 971 parser.resolvers.add(MyResolver()) 972 973 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 974 tree = parse(StringIO(xml), parser) 975 root = tree.getroot() 976 self.assertEquals(root.text, test_url) 977979 parse = self.etree.parse 980 parser = self.etree.XMLParser(attribute_defaults=True) 981 assertEqual = self.assertEqual 982 test_url = _str("__nosuch.dtd") 983 984 class MyResolver(self.etree.Resolver): 985 def resolve(self, url, id, context): 986 assertEqual(url, test_url) 987 return self.resolve_filename( 988 fileInTestDir('test.dtd'), context)989 990 parser.resolvers.add(MyResolver()) 991 992 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 993 tree = parse(StringIO(xml), parser) 994 root = tree.getroot() 995 self.assertEquals( 996 root.attrib, {'default': 'valueA'}) 997 self.assertEquals( 998 root[0].attrib, {'default': 'valueB'}) 9991001 parse = self.etree.parse 1002 parser = self.etree.XMLParser(attribute_defaults=True) 1003 assertEqual = self.assertEqual 1004 test_url = _str("__nosuch.dtd") 1005 1006 class MyResolver(self.etree.Resolver): 1007 def resolve(self, url, id, context): 1008 assertEqual(url, fileInTestDir(test_url)) 1009 return self.resolve_filename( 1010 fileInTestDir('test.dtd'), context)1011 1012 parser.resolvers.add(MyResolver()) 1013 1014 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1015 tree = parse(StringIO(xml), parser, 1016 base_url=fileInTestDir('__test.xml')) 1017 root = tree.getroot() 1018 self.assertEquals( 1019 root.attrib, {'default': 'valueA'}) 1020 self.assertEquals( 1021 root[0].attrib, {'default': 'valueB'}) 10221024 parse = self.etree.parse 1025 parser = self.etree.XMLParser(attribute_defaults=True) 1026 assertEqual = self.assertEqual 1027 test_url = _str("__nosuch.dtd") 1028 1029 class MyResolver(self.etree.Resolver): 1030 def resolve(self, url, id, context): 1031 assertEqual(url, test_url) 1032 return self.resolve_file( 1033 open(fileInTestDir('test.dtd'), 'rb'), context)1034 1035 parser.resolvers.add(MyResolver()) 1036 1037 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1038 tree = parse(StringIO(xml), parser) 1039 root = tree.getroot() 1040 self.assertEquals( 1041 root.attrib, {'default': 'valueA'}) 1042 self.assertEquals( 1043 root[0].attrib, {'default': 'valueB'}) 10441046 parse = self.etree.parse 1047 parser = self.etree.XMLParser(load_dtd=True) 1048 assertEqual = self.assertEqual 1049 test_url = _str("__nosuch.dtd") 1050 1051 class check(object): 1052 resolved = False1053 1054 class MyResolver(self.etree.Resolver): 1055 def resolve(self, url, id, context): 1056 assertEqual(url, test_url) 1057 check.resolved = True 1058 return self.resolve_empty(context) 1059 1060 parser.resolvers.add(MyResolver()) 1061 1062 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1063 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 1064 self.assert_(check.resolved) 10651067 parse = self.etree.parse 1068 parser = self.etree.XMLParser(dtd_validation=True) 1069 1070 class _LocalException(Exception): 1071 pass1072 1073 class MyResolver(self.etree.Resolver): 1074 def resolve(self, url, id, context): 1075 raise _LocalException 1076 1077 parser.resolvers.add(MyResolver()) 1078 1079 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 1080 self.assertRaises(_LocalException, parse, BytesIO(xml), parser) 1081 1082 if etree.LIBXML_VERSION > (2,6,20):1084 parse = self.etree.parse 1085 tostring = self.etree.tostring 1086 parser = self.etree.XMLParser(resolve_entities=False) 1087 Entity = self.etree.Entity 1088 1089 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>') 1090 tree = parse(BytesIO(xml), parser) 1091 root = tree.getroot() 1092 self.assertEquals(root[0].tag, Entity) 1093 self.assertEquals(root[0].text, "&myentity;") 1094 self.assertEquals(root[0].tail, None) 1095 self.assertEquals(root[0].name, "myentity") 1096 1097 self.assertEquals(_bytes('<doc>&myentity;</doc>'), 1098 tostring(root))10991101 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]> 1102 <root> 1103 <child1/> 1104 <child2/> 1105 <child3> </child3> 1106 </root>''') 1107 1108 parser = self.etree.XMLParser(resolve_entities=False) 1109 root = etree.fromstring(xml, parser) 1110 self.assertEquals([ el.tag for el in root ], 1111 ['child1', 'child2', 'child3']) 1112 1113 root[0] = root[-1] 1114 self.assertEquals([ el.tag for el in root ], 1115 ['child3', 'child2']) 1116 self.assertEquals(root[0][0].text, ' ') 1117 self.assertEquals(root[0][0].name, 'nbsp')11181120 Entity = self.etree.Entity 1121 Element = self.etree.Element 1122 tostring = self.etree.tostring 1123 1124 root = Element("root") 1125 root.append( Entity("test") ) 1126 1127 self.assertEquals(root[0].tag, Entity) 1128 self.assertEquals(root[0].text, "&test;") 1129 self.assertEquals(root[0].tail, None) 1130 self.assertEquals(root[0].name, "test") 1131 1132 self.assertEquals(_bytes('<root>&test;</root>'), 1133 tostring(root))11341136 Entity = self.etree.Entity 1137 self.assertEquals(Entity("test").text, '&test;') 1138 self.assertEquals(Entity("#17683").text, '䔓') 1139 self.assertEquals(Entity("#x1768").text, 'ᝨ') 1140 self.assertEquals(Entity("#x98AF").text, '颯')11411143 Entity = self.etree.Entity 1144 self.assertRaises(ValueError, Entity, 'a b c') 1145 self.assertRaises(ValueError, Entity, 'a,b') 1146 self.assertRaises(ValueError, Entity, 'a\0b') 1147 self.assertRaises(ValueError, Entity, '#abc') 1148 self.assertRaises(ValueError, Entity, '#xxyz')11491151 CDATA = self.etree.CDATA 1152 Element = self.etree.Element 1153 tostring = self.etree.tostring 1154 1155 root = Element("root") 1156 root.text = CDATA('test') 1157 1158 self.assertEquals('test', 1159 root.text) 1160 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 1161 tostring(root))11621164 CDATA = self.etree.CDATA 1165 Element = self.etree.Element 1166 root = Element("root") 1167 1168 root.text = CDATA("test") 1169 self.assertEquals('test', root.text) 1170 1171 root.text = CDATA(_str("test")) 1172 self.assertEquals('test', root.text) 1173 1174 self.assertRaises(TypeError, CDATA, 1)11751177 CDATA = self.etree.CDATA 1178 Element = self.etree.Element 1179 1180 root = Element("root") 1181 cdata = CDATA('test') 1182 1183 self.assertRaises(TypeError, 1184 setattr, root, 'tail', cdata) 1185 self.assertRaises(TypeError, 1186 root.set, 'attr', cdata) 1187 self.assertRaises(TypeError, 1188 operator.setitem, root.attrib, 'attr', cdata)11891191 tostring = self.etree.tostring 1192 parser = self.etree.XMLParser(strip_cdata=False) 1193 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1194 1195 self.assertEquals('test', root.text) 1196 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 1197 tostring(root))11981200 tostring = self.etree.tostring 1201 parser = self.etree.XMLParser(strip_cdata=False) 1202 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1203 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 1204 tostring(root)) 1205 1206 self.assertEquals(['test'], root.xpath('//text()'))1207 1208 # TypeError in etree, AssertionError in ElementTree;1210 Element = self.etree.Element 1211 SubElement = self.etree.SubElement 1212 1213 a = Element('a') 1214 b = SubElement(a, 'b') 1215 1216 self.assertRaises(TypeError, 1217 a.__setitem__, 0, 'foo')12181220 # raises AssertionError in ElementTree 1221 Element = self.etree.Element 1222 self.assertRaises(TypeError, Element('a').append, None)12231225 Element = self.etree.Element 1226 SubElement = self.etree.SubElement 1227 root = Element('root') 1228 SubElement(root, 'a') 1229 SubElement(root, 'b') 1230 1231 self.assertEquals(['a', 'b'], 1232 [c.tag for c in root]) 1233 root[1].addnext(root[0]) 1234 self.assertEquals(['b', 'a'], 1235 [c.tag for c in root])12361238 Element = self.etree.Element 1239 SubElement = self.etree.SubElement 1240 root = Element('root') 1241 SubElement(root, 'a') 1242 SubElement(root, 'b') 1243 1244 self.assertEquals(['a', 'b'], 1245 [c.tag for c in root]) 1246 root[0].addprevious(root[1]) 1247 self.assertEquals(['b', 'a'], 1248 [c.tag for c in root])12491251 Element = self.etree.Element 1252 a = Element('a') 1253 b = Element('b') 1254 self.assertRaises(TypeError, a.addnext, b)12551257 Element = self.etree.Element 1258 a = Element('a') 1259 b = Element('b') 1260 self.assertRaises(TypeError, a.addnext, b)12611263 Element = self.etree.Element 1264 SubElement = self.etree.SubElement 1265 PI = self.etree.PI 1266 root = Element('root') 1267 SubElement(root, 'a') 1268 pi = PI('TARGET', 'TEXT') 1269 pi.tail = "TAIL" 1270 1271 self.assertEquals(_bytes('<root><a></a></root>'), 1272 self._writeElement(root)) 1273 root[0].addprevious(pi) 1274 self.assertEquals(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 1275 self._writeElement(root))12761278 Element = self.etree.Element 1279 PI = self.etree.PI 1280 root = Element('root') 1281 pi = PI('TARGET', 'TEXT') 1282 pi.tail = "TAIL" 1283 1284 self.assertEquals(_bytes('<root></root>'), 1285 self._writeElement(root)) 1286 root.addprevious(pi) 1287 self.assertEquals(_bytes('<?TARGET TEXT?>\n<root></root>'), 1288 self._writeElement(root))12891291 Element = self.etree.Element 1292 SubElement = self.etree.SubElement 1293 PI = self.etree.PI 1294 root = Element('root') 1295 SubElement(root, 'a') 1296 pi = PI('TARGET', 'TEXT') 1297 pi.tail = "TAIL" 1298 1299 self.assertEquals(_bytes('<root><a></a></root>'), 1300 self._writeElement(root)) 1301 root[0].addnext(pi) 1302 self.assertEquals(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 1303 self._writeElement(root))13041306 Element = self.etree.Element 1307 PI = self.etree.PI 1308 root = Element('root') 1309 pi = PI('TARGET', 'TEXT') 1310 pi.tail = "TAIL" 1311 1312 self.assertEquals(_bytes('<root></root>'), 1313 self._writeElement(root)) 1314 root.addnext(pi) 1315 self.assertEquals(_bytes('<root></root>\n<?TARGET TEXT?>'), 1316 self._writeElement(root))13171319 Element = self.etree.Element 1320 SubElement = self.etree.SubElement 1321 Comment = self.etree.Comment 1322 root = Element('root') 1323 SubElement(root, 'a') 1324 comment = Comment('TEXT ') 1325 comment.tail = "TAIL" 1326 1327 self.assertEquals(_bytes('<root><a></a></root>'), 1328 self._writeElement(root)) 1329 root[0].addnext(comment) 1330 self.assertEquals(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 1331 self._writeElement(root))13321334 Element = self.etree.Element 1335 Comment = self.etree.Comment 1336 root = Element('root') 1337 comment = Comment('TEXT ') 1338 comment.tail = "TAIL" 1339 1340 self.assertEquals(_bytes('<root></root>'), 1341 self._writeElement(root)) 1342 root.addnext(comment) 1343 self.assertEquals(_bytes('<root></root>\n<!--TEXT -->'), 1344 self._writeElement(root))13451347 Element = self.etree.Element 1348 SubElement = self.etree.SubElement 1349 Comment = self.etree.Comment 1350 root = Element('root') 1351 SubElement(root, 'a') 1352 comment = Comment('TEXT ') 1353 comment.tail = "TAIL" 1354 1355 self.assertEquals(_bytes('<root><a></a></root>'), 1356 self._writeElement(root)) 1357 root[0].addprevious(comment) 1358 self.assertEquals(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 1359 self._writeElement(root))13601362 Element = self.etree.Element 1363 Comment = self.etree.Comment 1364 root = Element('root') 1365 comment = Comment('TEXT ') 1366 comment.tail = "TAIL" 1367 1368 self.assertEquals(_bytes('<root></root>'), 1369 self._writeElement(root)) 1370 root.addprevious(comment) 1371 self.assertEquals(_bytes('<!--TEXT -->\n<root></root>'), 1372 self._writeElement(root))1373 1374 # ET's Elements have items() and key(), but not values()1376 XML = self.etree.XML 1377 1378 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 1379 values = root.values() 1380 values.sort() 1381 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)1382 1383 # gives error in ElementTree1385 Element = self.etree.Element 1386 Comment = self.etree.Comment 1387 1388 a = Element('a') 1389 a.append(Comment()) 1390 self.assertEquals( 1391 _bytes('<a><!----></a>'), 1392 self._writeElement(a))1393 1394 # ElementTree ignores comments1396 ElementTree = self.etree.ElementTree 1397 tostring = self.etree.tostring 1398 1399 xml = _bytes('<a><b/><!----><c/></a>') 1400 f = BytesIO(xml) 1401 doc = ElementTree(file=f) 1402 a = doc.getroot() 1403 self.assertEquals( 1404 '', 1405 a[1].text) 1406 self.assertEquals( 1407 xml, 1408 tostring(a))1409 1410 # ElementTree ignores comments1412 ElementTree = self.etree.ElementTree 1413 1414 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 1415 doc = ElementTree(file=f) 1416 a = doc.getroot() 1417 self.assertEquals( 1418 ' hoi ', 1419 a[1].text)1420 1421 # does not raise an exception in ElementTree1423 Element = self.etree.Element 1424 Comment = self.etree.Comment 1425 1426 c = Comment() 1427 el = Element('myel') 1428 1429 self.assertRaises(TypeError, c.append, el) 1430 self.assertRaises(TypeError, c.insert, 0, el) 1431 self.assertRaises(TypeError, c.set, "myattr", "test")1432 1433 # test passing 'None' to dump 14361438 ElementTree = self.etree.ElementTree 1439 1440 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 1441 doc = ElementTree(file=f) 1442 a = doc.getroot() 1443 self.assertEquals( 1444 None, 1445 a.prefix) 1446 self.assertEquals( 1447 'foo', 1448 a[0].prefix)14491451 ElementTree = self.etree.ElementTree 1452 1453 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 1454 doc = ElementTree(file=f) 1455 a = doc.getroot() 1456 self.assertEquals( 1457 None, 1458 a.prefix) 1459 self.assertEquals( 1460 None, 1461 a[0].prefix)14621464 Element = self.etree.Element 1465 SubElement = self.etree.SubElement 1466 1467 a = Element('a') 1468 b = SubElement(a, 'b') 1469 c = SubElement(a, 'c') 1470 d = SubElement(b, 'd') 1471 self.assertEquals( 1472 None, 1473 a.getparent()) 1474 self.assertEquals( 1475 a, 1476 b.getparent()) 1477 self.assertEquals( 1478 b.getparent(), 1479 c.getparent()) 1480 self.assertEquals( 1481 b, 1482 d.getparent())14831485 XML = self.etree.XML 1486 1487 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1488 result = [] 1489 for el in root.iterchildren(): 1490 result.append(el.tag) 1491 self.assertEquals(['one', 'two', 'three'], result)14921494 XML = self.etree.XML 1495 1496 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1497 result = [] 1498 for el in root.iterchildren(reversed=True): 1499 result.append(el.tag) 1500 self.assertEquals(['three', 'two', 'one'], result)15011503 XML = self.etree.XML 1504 1505 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1506 result = [] 1507 for el in root.iterchildren(tag='two'): 1508 result.append(el.text) 1509 self.assertEquals(['Two', 'Bla'], result)15101512 XML = self.etree.XML 1513 1514 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1515 result = [] 1516 for el in root.iterchildren(reversed=True, tag='two'): 1517 result.append(el.text) 1518 self.assertEquals(['Bla', 'Two'], result)15191521 Element = self.etree.Element 1522 SubElement = self.etree.SubElement 1523 1524 a = Element('a') 1525 b = SubElement(a, 'b') 1526 c = SubElement(a, 'c') 1527 d = SubElement(b, 'd') 1528 self.assertEquals( 1529 [], 1530 list(a.iterancestors())) 1531 self.assertEquals( 1532 [a], 1533 list(b.iterancestors())) 1534 self.assertEquals( 1535 [a], 1536 list(c.iterancestors())) 1537 self.assertEquals( 1538 [b, a], 1539 list(d.iterancestors()))15401542 Element = self.etree.Element 1543 SubElement = self.etree.SubElement 1544 1545 a = Element('a') 1546 b = SubElement(a, 'b') 1547 c = SubElement(a, 'c') 1548 d = SubElement(b, 'd') 1549 self.assertEquals( 1550 [a], 1551 list(d.iterancestors(tag='a')))15521554 Element = self.etree.Element 1555 SubElement = self.etree.SubElement 1556 1557 a = Element('a') 1558 b = SubElement(a, 'b') 1559 c = SubElement(a, 'c') 1560 d = SubElement(b, 'd') 1561 e = SubElement(c, 'e') 1562 1563 self.assertEquals( 1564 [b, d, c, e], 1565 list(a.iterdescendants())) 1566 self.assertEquals( 1567 [], 1568 list(d.iterdescendants()))15691571 Element = self.etree.Element 1572 SubElement = self.etree.SubElement 1573 1574 a = Element('a') 1575 b = SubElement(a, 'b') 1576 c = SubElement(a, 'c') 1577 d = SubElement(b, 'd') 1578 e = SubElement(c, 'e') 1579 1580 self.assertEquals( 1581 [], 1582 list(a.iterdescendants('a'))) 1583 a2 = SubElement(e, 'a') 1584 self.assertEquals( 1585 [a2], 1586 list(a.iterdescendants('a'))) 1587 self.assertEquals( 1588 [a2], 1589 list(c.iterdescendants('a')))15901592 Element = self.etree.Element 1593 SubElement = self.etree.SubElement 1594 1595 a = Element('a') 1596 b = SubElement(a, 'b') 1597 c = SubElement(a, 'c') 1598 d = SubElement(b, 'd') 1599 self.assertEquals( 1600 a, 1601 a.getroottree().getroot()) 1602 self.assertEquals( 1603 a, 1604 b.getroottree().getroot()) 1605 self.assertEquals( 1606 a, 1607 d.getroottree().getroot())16081610 Element = self.etree.Element 1611 SubElement = self.etree.SubElement 1612 1613 a = Element('a') 1614 b = SubElement(a, 'b') 1615 c = SubElement(a, 'c') 1616 self.assertEquals( 1617 None, 1618 a.getnext()) 1619 self.assertEquals( 1620 c, 1621 b.getnext()) 1622 self.assertEquals( 1623 None, 1624 c.getnext())16251627 Element = self.etree.Element 1628 SubElement = self.etree.SubElement 1629 1630 a = Element('a') 1631 b = SubElement(a, 'b') 1632 c = SubElement(a, 'c') 1633 d = SubElement(b, 'd') 1634 self.assertEquals( 1635 None, 1636 a.getprevious()) 1637 self.assertEquals( 1638 b, 1639 c.getprevious()) 1640 self.assertEquals( 1641 None, 1642 b.getprevious())16431645 Element = self.etree.Element 1646 SubElement = self.etree.SubElement 1647 1648 a = Element('a') 1649 b = SubElement(a, 'b') 1650 c = SubElement(a, 'c') 1651 d = SubElement(b, 'd') 1652 self.assertEquals( 1653 [], 1654 list(a.itersiblings())) 1655 self.assertEquals( 1656 [c], 1657 list(b.itersiblings())) 1658 self.assertEquals( 1659 [], 1660 list(c.itersiblings())) 1661 self.assertEquals( 1662 [b], 1663 list(c.itersiblings(preceding=True))) 1664 self.assertEquals( 1665 [], 1666 list(b.itersiblings(preceding=True)))16671669 Element = self.etree.Element 1670 SubElement = self.etree.SubElement 1671 1672 a = Element('a') 1673 b = SubElement(a, 'b') 1674 c = SubElement(a, 'c') 1675 d = SubElement(b, 'd') 1676 self.assertEquals( 1677 [], 1678 list(a.itersiblings(tag='XXX'))) 1679 self.assertEquals( 1680 [c], 1681 list(b.itersiblings(tag='c'))) 1682 self.assertEquals( 1683 [b], 1684 list(c.itersiblings(preceding=True, tag='b'))) 1685 self.assertEquals( 1686 [], 1687 list(c.itersiblings(preceding=True, tag='c')))16881690 parseid = self.etree.parseid 1691 XML = self.etree.XML 1692 xml_text = _bytes(''' 1693 <!DOCTYPE document [ 1694 <!ELEMENT document (h1,p)*> 1695 <!ELEMENT h1 (#PCDATA)> 1696 <!ATTLIST h1 myid ID #REQUIRED> 1697 <!ELEMENT p (#PCDATA)> 1698 <!ATTLIST p someid ID #REQUIRED> 1699 ]> 1700 <document> 1701 <h1 myid="chapter1">...</h1> 1702 <p id="note1" class="note">...</p> 1703 <p>Regular paragraph.</p> 1704 <p xml:id="xmlid">XML:ID paragraph.</p> 1705 <p someid="warn1" class="warning">...</p> 1706 </document> 1707 ''') 1708 1709 tree, dic = parseid(BytesIO(xml_text)) 1710 root = tree.getroot() 1711 root2 = XML(xml_text) 1712 self.assertEquals(self._writeElement(root), 1713 self._writeElement(root2)) 1714 expected = { 1715 "chapter1" : root[0], 1716 "xmlid" : root[3], 1717 "warn1" : root[4] 1718 } 1719 self.assert_("chapter1" in dic) 1720 self.assert_("warn1" in dic) 1721 self.assert_("xmlid" in dic) 1722 self._checkIDDict(dic, expected)17231725 XMLDTDID = self.etree.XMLDTDID 1726 XML = self.etree.XML 1727 xml_text = _bytes(''' 1728 <!DOCTYPE document [ 1729 <!ELEMENT document (h1,p)*> 1730 <!ELEMENT h1 (#PCDATA)> 1731 <!ATTLIST h1 myid ID #REQUIRED> 1732 <!ELEMENT p (#PCDATA)> 1733 <!ATTLIST p someid ID #REQUIRED> 1734 ]> 1735 <document> 1736 <h1 myid="chapter1">...</h1> 1737 <p id="note1" class="note">...</p> 1738 <p>Regular paragraph.</p> 1739 <p xml:id="xmlid">XML:ID paragraph.</p> 1740 <p someid="warn1" class="warning">...</p> 1741 </document> 1742 ''') 1743 1744 root, dic = XMLDTDID(xml_text) 1745 root2 = XML(xml_text) 1746 self.assertEquals(self._writeElement(root), 1747 self._writeElement(root2)) 1748 expected = { 1749 "chapter1" : root[0], 1750 "xmlid" : root[3], 1751 "warn1" : root[4] 1752 } 1753 self.assert_("chapter1" in dic) 1754 self.assert_("warn1" in dic) 1755 self.assert_("xmlid" in dic) 1756 self._checkIDDict(dic, expected)17571759 XMLDTDID = self.etree.XMLDTDID 1760 XML = self.etree.XML 1761 xml_text = _bytes(''' 1762 <document> 1763 <h1 myid="chapter1">...</h1> 1764 <p id="note1" class="note">...</p> 1765 <p>Regular paragraph.</p> 1766 <p someid="warn1" class="warning">...</p> 1767 </document> 1768 ''') 1769 1770 root, dic = XMLDTDID(xml_text) 1771 root2 = XML(xml_text) 1772 self.assertEquals(self._writeElement(root), 1773 self._writeElement(root2)) 1774 expected = {} 1775 self._checkIDDict(dic, expected)17761778 self.assertEquals(len(dic), 1779 len(expected)) 1780 self.assertEquals(sorted(dic.items()), 1781 sorted(expected.items())) 1782 if sys.version_info < (3,): 1783 self.assertEquals(sorted(dic.iteritems()), 1784 sorted(expected.iteritems())) 1785 self.assertEquals(sorted(dic.keys()), 1786 sorted(expected.keys())) 1787 if sys.version_info < (3,): 1788 self.assertEquals(sorted(dic.iterkeys()), 1789 sorted(expected.iterkeys())) 1790 if sys.version_info < (3,): 1791 self.assertEquals(sorted(dic.values()), 1792 sorted(expected.values())) 1793 self.assertEquals(sorted(dic.itervalues()), 1794 sorted(expected.itervalues()))17951797 etree = self.etree 1798 1799 r = {'foo': 'http://ns.infrae.com/foo'} 1800 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1801 self.assertEquals( 1802 'foo', 1803 e.prefix) 1804 self.assertEquals( 1805 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 1806 self._writeElement(e))18071809 etree = self.etree 1810 1811 r = {None: 'http://ns.infrae.com/foo'} 1812 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1813 self.assertEquals( 1814 None, 1815 e.prefix) 1816 self.assertEquals( 1817 '{http://ns.infrae.com/foo}bar', 1818 e.tag) 1819 self.assertEquals( 1820 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 1821 self._writeElement(e))18221824 etree = self.etree 1825 1826 r = {None: 'http://ns.infrae.com/foo', 1827 'hoi': 'http://ns.infrae.com/hoi'} 1828 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1829 e.set('{http://ns.infrae.com/hoi}test', 'value') 1830 self.assertEquals( 1831 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 1832 self._writeElement(e))18331835 etree = self.etree 1836 r = {None: 'http://ns.infrae.com/foo', 1837 'hoi': 'http://ns.infrae.com/hoi'} 1838 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 1839 tree = etree.ElementTree(element=e) 1840 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 1841 self.assertEquals( 1842 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 1843 self._writeElement(e))18441846 etree = self.etree 1847 1848 r = {None: 'http://ns.infrae.com/foo'} 1849 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1850 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1851 1852 e1.append(e2) 1853 1854 self.assertEquals( 1855 None, 1856 e1.prefix) 1857 self.assertEquals( 1858 None, 1859 e1[0].prefix) 1860 self.assertEquals( 1861 '{http://ns.infrae.com/foo}bar', 1862 e1.tag) 1863 self.assertEquals( 1864 '{http://ns.infrae.com/foo}bar', 1865 e1[0].tag)18661868 etree = self.etree 1869 1870 r = {None: 'http://ns.infrae.com/BAR'} 1871 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 1872 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1873 1874 e1.append(e2) 1875 1876 self.assertEquals( 1877 None, 1878 e1.prefix) 1879 self.assertNotEquals( 1880 None, 1881 e2.prefix) 1882 self.assertEquals( 1883 '{http://ns.infrae.com/BAR}bar', 1884 e1.tag) 1885 self.assertEquals( 1886 '{http://ns.infrae.com/foo}bar', 1887 e2.tag)18881890 ns_href = "http://a.b.c" 1891 one = self.etree.fromstring( 1892 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 1893 baz = one[0][0] 1894 1895 two = self.etree.fromstring( 1896 _bytes('<root xmlns:ns="%s"/>' % ns_href)) 1897 two.append(baz) 1898 del one # make sure the source document is deallocated 1899 1900 self.assertEquals('{%s}baz' % ns_href, baz.tag) 1901 self.assertEquals( 1902 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 1903 self.etree.tostring(two))19041906 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>') 1907 root = self.etree.fromstring(xml) 1908 self.assertEquals(xml, 1909 self.etree.tostring(root)) 1910 self.etree.cleanup_namespaces(root) 1911 self.assertEquals( 1912 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 1913 self.etree.tostring(root))1914