1
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 gc
16 import operator
17 import tempfile
18 import zlib
19 import gzip
20
21 this_dir = os.path.dirname(__file__)
22 if this_dir not in sys.path:
23 sys.path.insert(0, this_dir)
24
25 from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir, read_file
26 from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest
27 from common_imports import canonicalize, sorted, _str, _bytes
28
29 print("")
30 print("TESTED VERSION: %s" % etree.__version__)
31 print(" Python: " + repr(sys.version_info))
32 print(" lxml.etree: " + repr(etree.LXML_VERSION))
33 print(" libxml used: " + repr(etree.LIBXML_VERSION))
34 print(" libxml compiled: " + repr(etree.LIBXML_COMPILED_VERSION))
35 print(" libxslt used: " + repr(etree.LIBXSLT_VERSION))
36 print(" libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION))
37 print("")
38
39 try:
40 _unicode = unicode
41 except NameError:
42
43 _unicode = str
44
46 """Tests only for etree, not ElementTree"""
47 etree = etree
48
59
68
75
77 Element = self.etree.Element
78 el = Element('name')
79 self.assertRaises(ValueError, Element, '{}')
80 self.assertRaises(ValueError, setattr, el, 'tag', '{}')
81
82 self.assertRaises(ValueError, Element, '{test}')
83 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
84
92
94 Element = self.etree.Element
95 self.assertRaises(ValueError, Element, "p'name")
96 self.assertRaises(ValueError, Element, 'p"name')
97
98 self.assertRaises(ValueError, Element, "{test}p'name")
99 self.assertRaises(ValueError, Element, '{test}p"name')
100
101 el = Element('name')
102 self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
103 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
104
106 Element = self.etree.Element
107 self.assertRaises(ValueError, Element, ' name ')
108 self.assertRaises(ValueError, Element, 'na me')
109 self.assertRaises(ValueError, Element, '{test} name')
110
111 el = Element('name')
112 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
113
121
129
131 Element = self.etree.Element
132 SubElement = self.etree.SubElement
133
134 el = Element('name')
135 self.assertRaises(ValueError, SubElement, el, "p'name")
136 self.assertRaises(ValueError, SubElement, el, "{test}p'name")
137
138 self.assertRaises(ValueError, SubElement, el, 'p"name')
139 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
140
149
158
160 QName = self.etree.QName
161 self.assertRaises(ValueError, QName, '')
162 self.assertRaises(ValueError, QName, 'test', '')
163
165 QName = self.etree.QName
166 self.assertRaises(ValueError, QName, 'p:name')
167 self.assertRaises(ValueError, QName, 'test', 'p:name')
168
170 QName = self.etree.QName
171 self.assertRaises(ValueError, QName, ' name ')
172 self.assertRaises(ValueError, QName, 'na me')
173 self.assertRaises(ValueError, QName, 'test', ' name')
174
182
184
185 QName = self.etree.QName
186 qname1 = QName('http://myns', 'a')
187 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
188
189 qname2 = QName(a)
190 self.assertEqual(a.tag, qname1.text)
191 self.assertEqual(qname1.text, qname2.text)
192 self.assertEqual(qname1, qname2)
193
195
196 etree = self.etree
197 qname = etree.QName('http://myns', 'a')
198 a = etree.Element(qname, nsmap={'p' : 'http://myns'})
199 a.text = qname
200
201 self.assertEqual("p:a", a.text)
202
211
226
232
240
254
276
278 XML = self.etree.XML
279 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
280
281 root = XML(xml)
282 self.etree.strip_elements(root, 'a')
283 self.assertEqual(_bytes('<test><x></x></test>'),
284 self._writeElement(root))
285
286 root = XML(xml)
287 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
288 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'),
289 self._writeElement(root))
290
291 root = XML(xml)
292 self.etree.strip_elements(root, 'c')
293 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
294 self._writeElement(root))
295
297 XML = self.etree.XML
298 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>')
299
300 root = XML(xml)
301 self.etree.strip_elements(root, 'a')
302 self.assertEqual(_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>'),
303 self._writeElement(root))
304
305 root = XML(xml)
306 self.etree.strip_elements(root, '{urn:a}b', 'c')
307 self.assertEqual(_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>'),
308 self._writeElement(root))
309
310 root = XML(xml)
311 self.etree.strip_elements(root, '{urn:a}*', 'c')
312 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
313 self._writeElement(root))
314
315 root = XML(xml)
316 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
317 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
318 self._writeElement(root))
319
338
364
391
418
437
450
461
467
469 XML = self.etree.XML
470 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
471 self.assertEqual(root[0].target, "mypi")
472 self.assertEqual(root[0].get('my'), "1")
473 self.assertEqual(root[0].get('test'), " abc ")
474 self.assertEqual(root[0].get('quotes'), "' '")
475 self.assertEqual(root[0].get('only'), None)
476 self.assertEqual(root[0].get('names'), None)
477 self.assertEqual(root[0].get('nope'), None)
478
480 XML = self.etree.XML
481 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
482 self.assertEqual(root[0].target, "mypi")
483 self.assertEqual(root[0].attrib['my'], "1")
484 self.assertEqual(root[0].attrib['test'], " abc ")
485 self.assertEqual(root[0].attrib['quotes'], "' '")
486 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
487 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
488 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
489
491
492 ProcessingInstruction = self.etree.ProcessingInstruction
493
494 a = ProcessingInstruction("PI", "ONE")
495 b = copy.deepcopy(a)
496 b.text = "ANOTHER"
497
498 self.assertEqual('ONE', a.text)
499 self.assertEqual('ANOTHER', b.text)
500
516
531
541
553
572
577
590
601
602 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
603 events = list(iterparse(f, events=('end', 'comment')))
604 root = events[-1][1]
605 self.assertEqual(6, len(events))
606 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'],
607 [ name(*item) for item in events ])
608 self.assertEqual(
609 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
610 tostring(root))
611
623
624 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
625 events = list(iterparse(f, events=('end', 'pi')))
626 root = events[-2][1]
627 self.assertEqual(8, len(events))
628 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
629 ('pid','d'), 'a', ('pie','e')],
630 [ name(*item) for item in events ])
631 self.assertEqual(
632 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
633 tostring(ElementTree(root)))
634
649
655
657 iterparse = self.etree.iterparse
658 f = BytesIO('<a><b><c/></a>')
659 it = iterparse(f, events=('start', 'end'), recover=True)
660 events = [(ev, el.tag) for ev, el in it]
661 root = it.root
662 self.assertTrue(root is not None)
663
664 self.assertEqual(1, events.count(('start', 'a')))
665 self.assertEqual(1, events.count(('end', 'a')))
666
667 self.assertEqual(1, events.count(('start', 'b')))
668 self.assertEqual(1, events.count(('end', 'b')))
669
670 self.assertEqual(1, events.count(('start', 'c')))
671 self.assertEqual(1, events.count(('end', 'c')))
672
674 iterparse = self.etree.iterparse
675 f = BytesIO('<a><b><c/></d><b><c/></a></b>')
676 it = iterparse(f, events=('start', 'end'), recover=True)
677 events = [(ev, el.tag) for ev, el in it]
678 root = it.root
679 self.assertTrue(root is not None)
680
681 self.assertEqual(1, events.count(('start', 'a')))
682 self.assertEqual(1, events.count(('end', 'a')))
683
684 self.assertEqual(2, events.count(('start', 'b')))
685 self.assertEqual(2, events.count(('end', 'b')))
686
687 self.assertEqual(2, events.count(('start', 'c')))
688 self.assertEqual(2, events.count(('end', 'c')))
689
691 iterparse = self.etree.iterparse
692 f = BytesIO("""
693 <a> \n \n <b> b test </b> \n
694
695 \n\t <c> \n </c> </a> \n """)
696 iterator = iterparse(f, remove_blank_text=True)
697 text = [ (element.text, element.tail)
698 for event, element in iterator ]
699 self.assertEqual(
700 [(" b test ", None), (" \n ", None), (None, None)],
701 text)
702
704 iterparse = self.etree.iterparse
705 f = BytesIO('<a><b><d/></b><c/></a>')
706
707 iterator = iterparse(f, tag="b", events=('start', 'end'))
708 events = list(iterator)
709 root = iterator.root
710 self.assertEqual(
711 [('start', root[0]), ('end', root[0])],
712 events)
713
715 iterparse = self.etree.iterparse
716 f = BytesIO('<a><b><d/></b><c/></a>')
717
718 iterator = iterparse(f, tag="*", events=('start', 'end'))
719 events = list(iterator)
720 self.assertEqual(
721 8,
722 len(events))
723
725 iterparse = self.etree.iterparse
726 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
727
728 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
729 events = list(iterator)
730 root = iterator.root
731 self.assertEqual(
732 [('start', root[0]), ('end', root[0])],
733 events)
734
736 iterparse = self.etree.iterparse
737 f = BytesIO('<a><b><d/></b><c/></a>')
738 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
739 events = list(iterator)
740 root = iterator.root
741 self.assertEqual(
742 [('start', root[0]), ('end', root[0])],
743 events)
744
745 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
746 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
747 events = list(iterator)
748 root = iterator.root
749 self.assertEqual([], events)
750
752 iterparse = self.etree.iterparse
753 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
754 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
755 events = list(iterator)
756 self.assertEqual(8, len(events))
757
759 iterparse = self.etree.iterparse
760 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
761 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
762 events = list(iterator)
763 self.assertEqual([], events)
764
765 f = BytesIO('<a><b><d/></b><c/></a>')
766 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
767 events = list(iterator)
768 self.assertEqual(8, len(events))
769
771 text = _str('Søk på nettet')
772 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
773 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
774 ).encode('iso-8859-1')
775
776 self.assertRaises(self.etree.ParseError,
777 list, self.etree.iterparse(BytesIO(xml_latin1)))
778
780 text = _str('Søk på nettet', encoding="UTF-8")
781 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
782 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
783 ).encode('iso-8859-1')
784
785 iterator = self.etree.iterparse(BytesIO(xml_latin1),
786 encoding="iso-8859-1")
787 self.assertEqual(1, len(list(iterator)))
788
789 a = iterator.root
790 self.assertEqual(a.text, text)
791
793 tostring = self.etree.tostring
794 f = BytesIO('<root><![CDATA[test]]></root>')
795 context = self.etree.iterparse(f, strip_cdata=False)
796 content = [ el.text for event,el in context ]
797
798 self.assertEqual(['test'], content)
799 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
800 tostring(context.root))
801
805
810
829
830
831
842 def end(self, tag):
843 events.append("end")
844 assertEqual("TAG", tag)
845 def close(self):
846 return "DONE"
847
848 parser = self.etree.XMLParser(target=Target())
849 tree = self.etree.ElementTree()
850
851 self.assertRaises(TypeError,
852 tree.parse, BytesIO("<TAG/>"), parser=parser)
853 self.assertEqual(["start", "end"], events)
854
856
857 events = []
858 class Target(object):
859 def start(self, tag, attrib):
860 events.append("start-" + tag)
861 def end(self, tag):
862 events.append("end-" + tag)
863 if tag == 'a':
864 raise ValueError("dead and gone")
865 def data(self, data):
866 events.append("data-" + data)
867 def close(self):
868 events.append("close")
869 return "DONE"
870
871 parser = self.etree.XMLParser(target=Target())
872
873 try:
874 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
875 done = parser.close()
876 self.fail("error expected, but parsing succeeded")
877 except ValueError:
878 done = 'value error received as expected'
879
880 self.assertEqual(["start-root", "data-A", "start-a",
881 "data-ca", "end-a", "close"],
882 events)
883
885
886 events = []
887 class Target(object):
888 def start(self, tag, attrib):
889 events.append("start-" + tag)
890 def end(self, tag):
891 events.append("end-" + tag)
892 if tag == 'a':
893 raise ValueError("dead and gone")
894 def data(self, data):
895 events.append("data-" + data)
896 def close(self):
897 events.append("close")
898 return "DONE"
899
900 parser = self.etree.XMLParser(target=Target())
901
902 try:
903 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
904 parser=parser)
905 self.fail("error expected, but parsing succeeded")
906 except ValueError:
907 done = 'value error received as expected'
908
909 self.assertEqual(["start-root", "data-A", "start-a",
910 "data-ca", "end-a", "close"],
911 events)
912
918 def end(self, tag):
919 events.append("end-" + tag)
920 def data(self, data):
921 events.append("data-" + data)
922 def comment(self, text):
923 events.append("comment-" + text)
924 def close(self):
925 return "DONE"
926
927 parser = self.etree.XMLParser(target=Target())
928
929 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
930 done = parser.close()
931
932 self.assertEqual("DONE", done)
933 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
934 "start-sub", "end-sub", "comment-c", "data-B",
935 "end-root", "comment-d"],
936 events)
937
939 events = []
940 class Target(object):
941 def start(self, tag, attrib):
942 events.append("start-" + tag)
943 def end(self, tag):
944 events.append("end-" + tag)
945 def data(self, data):
946 events.append("data-" + data)
947 def pi(self, target, data):
948 events.append("pi-" + target + "-" + data)
949 def close(self):
950 return "DONE"
951
952 parser = self.etree.XMLParser(target=Target())
953
954 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
955 done = parser.close()
956
957 self.assertEqual("DONE", done)
958 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b",
959 "data-B", "end-root", "pi-test-c"],
960 events)
961
963 events = []
964 class Target(object):
965 def start(self, tag, attrib):
966 events.append("start-" + tag)
967 def end(self, tag):
968 events.append("end-" + tag)
969 def data(self, data):
970 events.append("data-" + data)
971 def close(self):
972 return "DONE"
973
974 parser = self.etree.XMLParser(target=Target(),
975 strip_cdata=False)
976
977 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
978 done = parser.close()
979
980 self.assertEqual("DONE", done)
981 self.assertEqual(["start-root", "data-A", "start-a",
982 "data-ca", "end-a", "data-B", "end-root"],
983 events)
984
986 events = []
987 class Target(object):
988 def start(self, tag, attrib):
989 events.append("start-" + tag)
990 def end(self, tag):
991 events.append("end-" + tag)
992 def data(self, data):
993 events.append("data-" + data)
994 def close(self):
995 events.append("close")
996 return "DONE"
997
998 parser = self.etree.XMLParser(target=Target(),
999 recover=True)
1000
1001 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
1002 done = parser.close()
1003
1004 self.assertEqual("DONE", done)
1005 self.assertEqual(["start-root", "data-A", "start-a",
1006 "data-ca", "end-a", "data-B",
1007 "end-root", "close"],
1008 events)
1009
1019
1029
1038
1048
1050 iterwalk = self.etree.iterwalk
1051 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1052
1053 iterator = iterwalk(root, events=('start','end'))
1054 events = list(iterator)
1055 self.assertEqual(
1056 [('start', root), ('start', root[0]), ('end', root[0]),
1057 ('start', root[1]), ('end', root[1]), ('end', root)],
1058 events)
1059
1070
1072 iterwalk = self.etree.iterwalk
1073 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1074
1075 attr_name = '{testns}bla'
1076 events = []
1077 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1078 for event, elem in iterator:
1079 events.append(event)
1080 if event == 'start':
1081 if elem.tag != '{ns1}a':
1082 elem.set(attr_name, 'value')
1083
1084 self.assertEqual(
1085 ['start-ns', 'start', 'start', 'start-ns', 'start',
1086 'end', 'end-ns', 'end', 'end', 'end-ns'],
1087 events)
1088
1089 self.assertEqual(
1090 None,
1091 root.get(attr_name))
1092 self.assertEqual(
1093 'value',
1094 root[0].get(attr_name))
1095
1106
1108 parse = self.etree.parse
1109 parser = self.etree.XMLParser(dtd_validation=True)
1110 assertEqual = self.assertEqual
1111 test_url = _str("__nosuch.dtd")
1112
1113 class MyResolver(self.etree.Resolver):
1114 def resolve(self, url, id, context):
1115 assertEqual(url, test_url)
1116 return self.resolve_string(
1117 _str('''<!ENTITY myentity "%s">
1118 <!ELEMENT doc ANY>''') % url, context)
1119
1120 parser.resolvers.add(MyResolver())
1121
1122 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1123 tree = parse(StringIO(xml), parser)
1124 root = tree.getroot()
1125 self.assertEqual(root.text, test_url)
1126
1128 parse = self.etree.parse
1129 parser = self.etree.XMLParser(dtd_validation=True)
1130 assertEqual = self.assertEqual
1131 test_url = _str("__nosuch.dtd")
1132
1133 class MyResolver(self.etree.Resolver):
1134 def resolve(self, url, id, context):
1135 assertEqual(url, test_url)
1136 return self.resolve_string(
1137 (_str('''<!ENTITY myentity "%s">
1138 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1139 context)
1140
1141 parser.resolvers.add(MyResolver())
1142
1143 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1144 tree = parse(StringIO(xml), parser)
1145 root = tree.getroot()
1146 self.assertEqual(root.text, test_url)
1147
1149 parse = self.etree.parse
1150 parser = self.etree.XMLParser(dtd_validation=True)
1151 assertEqual = self.assertEqual
1152 test_url = _str("__nosuch.dtd")
1153
1154 class MyResolver(self.etree.Resolver):
1155 def resolve(self, url, id, context):
1156 assertEqual(url, test_url)
1157 return self.resolve_file(
1158 SillyFileLike(
1159 _str('''<!ENTITY myentity "%s">
1160 <!ELEMENT doc ANY>''') % url), context)
1161
1162 parser.resolvers.add(MyResolver())
1163
1164 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1165 tree = parse(StringIO(xml), parser)
1166 root = tree.getroot()
1167 self.assertEqual(root.text, test_url)
1168
1170 parse = self.etree.parse
1171 parser = self.etree.XMLParser(attribute_defaults=True)
1172 assertEqual = self.assertEqual
1173 test_url = _str("__nosuch.dtd")
1174
1175 class MyResolver(self.etree.Resolver):
1176 def resolve(self, url, id, context):
1177 assertEqual(url, test_url)
1178 return self.resolve_filename(
1179 fileInTestDir('test.dtd'), context)
1180
1181 parser.resolvers.add(MyResolver())
1182
1183 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1184 tree = parse(StringIO(xml), parser)
1185 root = tree.getroot()
1186 self.assertEqual(
1187 root.attrib, {'default': 'valueA'})
1188 self.assertEqual(
1189 root[0].attrib, {'default': 'valueB'})
1190
1202
1203 parser.resolvers.add(MyResolver())
1204
1205 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1206 tree = parse(StringIO(xml), parser,
1207 base_url=fileInTestDir('__test.xml'))
1208 root = tree.getroot()
1209 self.assertEqual(
1210 root.attrib, {'default': 'valueA'})
1211 self.assertEqual(
1212 root[0].attrib, {'default': 'valueB'})
1213
1215 parse = self.etree.parse
1216 parser = self.etree.XMLParser(attribute_defaults=True)
1217 assertEqual = self.assertEqual
1218 test_url = _str("__nosuch.dtd")
1219
1220 class MyResolver(self.etree.Resolver):
1221 def resolve(self, url, id, context):
1222 assertEqual(url, test_url)
1223 return self.resolve_file(
1224 open(fileInTestDir('test.dtd'), 'rb'), context)
1225
1226 parser.resolvers.add(MyResolver())
1227
1228 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1229 tree = parse(StringIO(xml), parser)
1230 root = tree.getroot()
1231 self.assertEqual(
1232 root.attrib, {'default': 'valueA'})
1233 self.assertEqual(
1234 root[0].attrib, {'default': 'valueB'})
1235
1237 parse = self.etree.parse
1238 parser = self.etree.XMLParser(load_dtd=True)
1239 assertEqual = self.assertEqual
1240 test_url = _str("__nosuch.dtd")
1241
1242 class check(object):
1243 resolved = False
1244
1245 class MyResolver(self.etree.Resolver):
1246 def resolve(self, url, id, context):
1247 assertEqual(url, test_url)
1248 check.resolved = True
1249 return self.resolve_empty(context)
1250
1251 parser.resolvers.add(MyResolver())
1252
1253 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1254 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1255 self.assertTrue(check.resolved)
1256
1263
1264 class MyResolver(self.etree.Resolver):
1265 def resolve(self, url, id, context):
1266 raise _LocalException
1267
1268 parser.resolvers.add(MyResolver())
1269
1270 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1271 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1272
1273 if etree.LIBXML_VERSION > (2,6,20):
1290
1292 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1293 <root>
1294 <child1/>
1295 <child2/>
1296 <child3> </child3>
1297 </root>''')
1298
1299 parser = self.etree.XMLParser(resolve_entities=False)
1300 root = etree.fromstring(xml, parser)
1301 self.assertEqual([ el.tag for el in root ],
1302 ['child1', 'child2', 'child3'])
1303
1304 root[0] = root[-1]
1305 self.assertEqual([ el.tag for el in root ],
1306 ['child3', 'child2'])
1307 self.assertEqual(root[0][0].text, ' ')
1308 self.assertEqual(root[0][0].name, 'nbsp')
1309
1325
1332
1334 Entity = self.etree.Entity
1335 self.assertRaises(ValueError, Entity, 'a b c')
1336 self.assertRaises(ValueError, Entity, 'a,b')
1337 self.assertRaises(ValueError, Entity, 'a\0b')
1338 self.assertRaises(ValueError, Entity, '#abc')
1339 self.assertRaises(ValueError, Entity, '#xxyz')
1340
1353
1366
1368 CDATA = self.etree.CDATA
1369 Element = self.etree.Element
1370
1371 root = Element("root")
1372 cdata = CDATA('test')
1373
1374 self.assertRaises(TypeError,
1375 setattr, root, 'tail', cdata)
1376 self.assertRaises(TypeError,
1377 root.set, 'attr', cdata)
1378 self.assertRaises(TypeError,
1379 operator.setitem, root.attrib, 'attr', cdata)
1380
1389
1398
1399
1409
1418
1420 Element = self.etree.Element
1421 SubElement = self.etree.SubElement
1422 root = Element('root')
1423 self.assertRaises(ValueError, root.append, root)
1424 child = SubElement(root, 'child')
1425 self.assertRaises(ValueError, child.append, root)
1426 child2 = SubElement(child, 'child2')
1427 self.assertRaises(ValueError, child2.append, root)
1428 self.assertRaises(ValueError, child2.append, child)
1429 self.assertEqual('child2', root[0][0].tag)
1430
1443
1456
1472
1488
1494
1509
1522
1537
1550
1565
1578
1593
1606
1607
1615
1616
1626
1627
1642
1643
1653
1654
1665
1666
1668 self.assertRaises(TypeError, self.etree.dump, None)
1669
1682
1695
1716
1725
1734
1743
1752
1761
1763 XML = self.etree.XML
1764
1765 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1766 result = []
1767 for el in root.iterchildren(tag=['two', 'three']):
1768 result.append(el.text)
1769 self.assertEqual(['Two', 'Bla', None], result)
1770
1772 XML = self.etree.XML
1773
1774 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1775 result = []
1776 for el in root.iterchildren('two', 'three'):
1777 result.append(el.text)
1778 self.assertEqual(['Two', 'Bla', None], result)
1779
1788
1809
1831
1833 Element = self.etree.Element
1834 SubElement = self.etree.SubElement
1835
1836 a = Element('a')
1837 b = SubElement(a, 'b')
1838 c = SubElement(a, 'c')
1839 d = SubElement(b, 'd')
1840 self.assertEqual(
1841 [b, a],
1842 list(d.iterancestors(tag=('a', 'b'))))
1843 self.assertEqual(
1844 [b, a],
1845 list(d.iterancestors('a', 'b')))
1846
1847 self.assertEqual(
1848 [],
1849 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
1850 self.assertEqual(
1851 [],
1852 list(d.iterancestors('w', 'x', 'y', 'z')))
1853
1854 self.assertEqual(
1855 [],
1856 list(d.iterancestors(tag=('d', 'x'))))
1857 self.assertEqual(
1858 [],
1859 list(d.iterancestors('d', 'x')))
1860
1861 self.assertEqual(
1862 [b, a],
1863 list(d.iterancestors(tag=('b', '*'))))
1864 self.assertEqual(
1865 [b, a],
1866 list(d.iterancestors('b', '*')))
1867
1868 self.assertEqual(
1869 [b],
1870 list(d.iterancestors(tag=('b', 'c'))))
1871 self.assertEqual(
1872 [b],
1873 list(d.iterancestors('b', 'c')))
1874
1891
1893 Element = self.etree.Element
1894 SubElement = self.etree.SubElement
1895
1896 a = Element('a')
1897 b = SubElement(a, 'b')
1898 c = SubElement(a, 'c')
1899 d = SubElement(b, 'd')
1900 e = SubElement(c, 'e')
1901
1902 self.assertEqual(
1903 [],
1904 list(a.iterdescendants('a')))
1905 self.assertEqual(
1906 [],
1907 list(a.iterdescendants(tag='a')))
1908
1909 a2 = SubElement(e, 'a')
1910 self.assertEqual(
1911 [a2],
1912 list(a.iterdescendants('a')))
1913
1914 self.assertEqual(
1915 [a2],
1916 list(c.iterdescendants('a')))
1917 self.assertEqual(
1918 [a2],
1919 list(c.iterdescendants(tag='a')))
1920
1922 Element = self.etree.Element
1923 SubElement = self.etree.SubElement
1924
1925 a = Element('a')
1926 b = SubElement(a, 'b')
1927 c = SubElement(a, 'c')
1928 d = SubElement(b, 'd')
1929 e = SubElement(c, 'e')
1930
1931 self.assertEqual(
1932 [b, e],
1933 list(a.iterdescendants(tag=('a', 'b', 'e'))))
1934 self.assertEqual(
1935 [b, e],
1936 list(a.iterdescendants('a', 'b', 'e')))
1937
1938 a2 = SubElement(e, 'a')
1939 self.assertEqual(
1940 [b, a2],
1941 list(a.iterdescendants(tag=('a', 'b'))))
1942 self.assertEqual(
1943 [b, a2],
1944 list(a.iterdescendants('a', 'b')))
1945
1946 self.assertEqual(
1947 [],
1948 list(c.iterdescendants(tag=('x', 'y', 'z'))))
1949 self.assertEqual(
1950 [],
1951 list(c.iterdescendants('x', 'y', 'z')))
1952
1953 self.assertEqual(
1954 [b, d, c, e, a2],
1955 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
1956 self.assertEqual(
1957 [b, d, c, e, a2],
1958 list(a.iterdescendants('x', 'y', 'z', '*')))
1959
1977
1994
2012
2036
2038 Element = self.etree.Element
2039 SubElement = self.etree.SubElement
2040
2041 a = Element('a')
2042 b = SubElement(a, 'b')
2043 c = SubElement(a, 'c')
2044 d = SubElement(b, 'd')
2045 self.assertEqual(
2046 [],
2047 list(a.itersiblings(tag='XXX')))
2048 self.assertEqual(
2049 [c],
2050 list(b.itersiblings(tag='c')))
2051 self.assertEqual(
2052 [c],
2053 list(b.itersiblings(tag='*')))
2054 self.assertEqual(
2055 [b],
2056 list(c.itersiblings(preceding=True, tag='b')))
2057 self.assertEqual(
2058 [],
2059 list(c.itersiblings(preceding=True, tag='c')))
2060
2062 Element = self.etree.Element
2063 SubElement = self.etree.SubElement
2064
2065 a = Element('a')
2066 b = SubElement(a, 'b')
2067 c = SubElement(a, 'c')
2068 d = SubElement(b, 'd')
2069 e = SubElement(a, 'e')
2070 self.assertEqual(
2071 [],
2072 list(a.itersiblings(tag=('XXX', 'YYY'))))
2073 self.assertEqual(
2074 [c, e],
2075 list(b.itersiblings(tag=('c', 'd', 'e'))))
2076 self.assertEqual(
2077 [b],
2078 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2079 self.assertEqual(
2080 [c, b],
2081 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2082
2084 parseid = self.etree.parseid
2085 XML = self.etree.XML
2086 xml_text = _bytes('''
2087 <!DOCTYPE document [
2088 <!ELEMENT document (h1,p)*>
2089 <!ELEMENT h1 (#PCDATA)>
2090 <!ATTLIST h1 myid ID #REQUIRED>
2091 <!ELEMENT p (#PCDATA)>
2092 <!ATTLIST p someid ID #REQUIRED>
2093 ]>
2094 <document>
2095 <h1 myid="chapter1">...</h1>
2096 <p id="note1" class="note">...</p>
2097 <p>Regular paragraph.</p>
2098 <p xml:id="xmlid">XML:ID paragraph.</p>
2099 <p someid="warn1" class="warning">...</p>
2100 </document>
2101 ''')
2102
2103 tree, dic = parseid(BytesIO(xml_text))
2104 root = tree.getroot()
2105 root2 = XML(xml_text)
2106 self.assertEqual(self._writeElement(root),
2107 self._writeElement(root2))
2108 expected = {
2109 "chapter1" : root[0],
2110 "xmlid" : root[3],
2111 "warn1" : root[4]
2112 }
2113 self.assertTrue("chapter1" in dic)
2114 self.assertTrue("warn1" in dic)
2115 self.assertTrue("xmlid" in dic)
2116 self._checkIDDict(dic, expected)
2117
2119 XMLDTDID = self.etree.XMLDTDID
2120 XML = self.etree.XML
2121 xml_text = _bytes('''
2122 <!DOCTYPE document [
2123 <!ELEMENT document (h1,p)*>
2124 <!ELEMENT h1 (#PCDATA)>
2125 <!ATTLIST h1 myid ID #REQUIRED>
2126 <!ELEMENT p (#PCDATA)>
2127 <!ATTLIST p someid ID #REQUIRED>
2128 ]>
2129 <document>
2130 <h1 myid="chapter1">...</h1>
2131 <p id="note1" class="note">...</p>
2132 <p>Regular paragraph.</p>
2133 <p xml:id="xmlid">XML:ID paragraph.</p>
2134 <p someid="warn1" class="warning">...</p>
2135 </document>
2136 ''')
2137
2138 root, dic = XMLDTDID(xml_text)
2139 root2 = XML(xml_text)
2140 self.assertEqual(self._writeElement(root),
2141 self._writeElement(root2))
2142 expected = {
2143 "chapter1" : root[0],
2144 "xmlid" : root[3],
2145 "warn1" : root[4]
2146 }
2147 self.assertTrue("chapter1" in dic)
2148 self.assertTrue("warn1" in dic)
2149 self.assertTrue("xmlid" in dic)
2150 self._checkIDDict(dic, expected)
2151
2153 XMLDTDID = self.etree.XMLDTDID
2154 XML = self.etree.XML
2155 xml_text = _bytes('''
2156 <document>
2157 <h1 myid="chapter1">...</h1>
2158 <p id="note1" class="note">...</p>
2159 <p>Regular paragraph.</p>
2160 <p someid="warn1" class="warning">...</p>
2161 </document>
2162 ''')
2163
2164 root, dic = XMLDTDID(xml_text)
2165 root2 = XML(xml_text)
2166 self.assertEqual(self._writeElement(root),
2167 self._writeElement(root2))
2168 expected = {}
2169 self._checkIDDict(dic, expected)
2170
2172 self.assertEqual(len(dic),
2173 len(expected))
2174 self.assertEqual(sorted(dic.items()),
2175 sorted(expected.items()))
2176 if sys.version_info < (3,):
2177 self.assertEqual(sorted(dic.iteritems()),
2178 sorted(expected.iteritems()))
2179 self.assertEqual(sorted(dic.keys()),
2180 sorted(expected.keys()))
2181 if sys.version_info < (3,):
2182 self.assertEqual(sorted(dic.iterkeys()),
2183 sorted(expected.iterkeys()))
2184 if sys.version_info < (3,):
2185 self.assertEqual(sorted(dic.values()),
2186 sorted(expected.values()))
2187 self.assertEqual(sorted(dic.itervalues()),
2188 sorted(expected.itervalues()))
2189
2191 etree = self.etree
2192
2193 r = {'foo': 'http://ns.infrae.com/foo'}
2194 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2195 self.assertEqual(
2196 'foo',
2197 e.prefix)
2198 self.assertEqual(
2199 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2200 self._writeElement(e))
2201
2203 etree = self.etree
2204
2205 r = {None: 'http://ns.infrae.com/foo'}
2206 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2207 self.assertEqual(
2208 None,
2209 e.prefix)
2210 self.assertEqual(
2211 '{http://ns.infrae.com/foo}bar',
2212 e.tag)
2213 self.assertEqual(
2214 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2215 self._writeElement(e))
2216
2218 etree = self.etree
2219
2220 r = {None: 'http://ns.infrae.com/foo',
2221 'hoi': 'http://ns.infrae.com/hoi'}
2222 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2223 e.set('{http://ns.infrae.com/hoi}test', 'value')
2224 self.assertEqual(
2225 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2226 self._writeElement(e))
2227
2229 etree = self.etree
2230
2231 root = etree.Element('{http://test/ns}root',
2232 nsmap={None: 'http://test/ns'})
2233 sub = etree.Element('{http://test/ns}sub',
2234 nsmap={'test': 'http://test/ns'})
2235
2236 sub.attrib['{http://test/ns}attr'] = 'value'
2237 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2238 self.assertEqual(
2239 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2240 etree.tostring(sub))
2241
2242 root.append(sub)
2243 self.assertEqual(
2244 _bytes('<root xmlns="http://test/ns">'
2245 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2246 '</root>'),
2247 etree.tostring(root))
2248
2250 etree = self.etree
2251
2252 root = etree.Element('root')
2253 sub = etree.Element('{http://test/ns}sub',
2254 nsmap={'test': 'http://test/ns'})
2255
2256 sub.attrib['{http://test/ns}attr'] = 'value'
2257 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2258 self.assertEqual(
2259 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2260 etree.tostring(sub))
2261
2262 root.append(sub)
2263 self.assertEqual(
2264 _bytes('<root>'
2265 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2266 '</root>'),
2267 etree.tostring(root))
2268
2270 etree = self.etree
2271
2272 root = etree.Element('root')
2273 sub = etree.Element('{http://test/ns}sub',
2274 nsmap={None: 'http://test/ns'})
2275
2276 sub.attrib['{http://test/ns}attr'] = 'value'
2277 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2278 self.assertEqual(
2279 _bytes('<sub xmlns="http://test/ns" '
2280 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2281 etree.tostring(sub))
2282
2283 root.append(sub)
2284 self.assertEqual(
2285 _bytes('<root>'
2286 '<sub xmlns="http://test/ns"'
2287 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2288 '</root>'),
2289 etree.tostring(root))
2290
2292 etree = self.etree
2293
2294 root = etree.Element('{http://test/ns}root',
2295 nsmap={'test': 'http://test/ns',
2296 None: 'http://test/ns'})
2297 sub = etree.Element('{http://test/ns}sub',
2298 nsmap={None: 'http://test/ns'})
2299
2300 sub.attrib['{http://test/ns}attr'] = 'value'
2301 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2302 self.assertEqual(
2303 _bytes('<sub xmlns="http://test/ns" '
2304 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2305 etree.tostring(sub))
2306
2307 root.append(sub)
2308 self.assertEqual(
2309 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2310 '<test:sub test:attr="value"/>'
2311 '</test:root>'),
2312 etree.tostring(root))
2313
2315 etree = self.etree
2316 r = {None: 'http://ns.infrae.com/foo',
2317 'hoi': 'http://ns.infrae.com/hoi'}
2318 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2319 tree = etree.ElementTree(element=e)
2320 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2321 self.assertEqual(
2322 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2323 self._writeElement(e))
2324
2326 etree = self.etree
2327
2328 r = {None: 'http://ns.infrae.com/foo'}
2329 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2330 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2331
2332 e1.append(e2)
2333
2334 self.assertEqual(
2335 None,
2336 e1.prefix)
2337 self.assertEqual(
2338 None,
2339 e1[0].prefix)
2340 self.assertEqual(
2341 '{http://ns.infrae.com/foo}bar',
2342 e1.tag)
2343 self.assertEqual(
2344 '{http://ns.infrae.com/foo}bar',
2345 e1[0].tag)
2346
2348 etree = self.etree
2349
2350 r = {None: 'http://ns.infrae.com/BAR'}
2351 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2352 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2353
2354 e1.append(e2)
2355
2356 self.assertEqual(
2357 None,
2358 e1.prefix)
2359 self.assertNotEqual(
2360 None,
2361 e2.prefix)
2362 self.assertEqual(
2363 '{http://ns.infrae.com/BAR}bar',
2364 e1.tag)
2365 self.assertEqual(
2366 '{http://ns.infrae.com/foo}bar',
2367 e2.tag)
2368
2370 ns_href = "http://a.b.c"
2371 one = self.etree.fromstring(
2372 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2373 baz = one[0][0]
2374
2375 two = self.etree.fromstring(
2376 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2377 two.append(baz)
2378 del one
2379
2380 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2381 self.assertEqual(
2382 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2383 self.etree.tostring(two))
2384
2394
2396 etree = self.etree
2397
2398 r = {None: 'http://ns.infrae.com/foo',
2399 'hoi': 'http://ns.infrae.com/hoi'}
2400 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2401 self.assertEqual(
2402 r,
2403 e.nsmap)
2404
2406 etree = self.etree
2407
2408 re = {None: 'http://ns.infrae.com/foo',
2409 'hoi': 'http://ns.infrae.com/hoi'}
2410 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2411
2412 rs = {None: 'http://ns.infrae.com/honk',
2413 'top': 'http://ns.infrae.com/top'}
2414 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2415
2416 r = re.copy()
2417 r.update(rs)
2418 self.assertEqual(re, e.nsmap)
2419 self.assertEqual(r, s.nsmap)
2420
2422 etree = self.etree
2423 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2424 self.assertEqual({'hha': None}, el.nsmap)
2425
2427 Element = self.etree.Element
2428 SubElement = self.etree.SubElement
2429
2430 a = Element('a')
2431 b = SubElement(a, 'b')
2432 c = SubElement(a, 'c')
2433 d = SubElement(b, 'd')
2434 e = SubElement(c, 'e')
2435 f = SubElement(c, 'f')
2436
2437 self.assertEqual(
2438 [a, b],
2439 list(a.getiterator('a', 'b')))
2440 self.assertEqual(
2441 [],
2442 list(a.getiterator('x', 'y')))
2443 self.assertEqual(
2444 [a, f],
2445 list(a.getiterator('f', 'a')))
2446 self.assertEqual(
2447 [c, e, f],
2448 list(c.getiterator('c', '*', 'a')))
2449 self.assertEqual(
2450 [],
2451 list(a.getiterator( (), () )))
2452
2454 Element = self.etree.Element
2455 SubElement = self.etree.SubElement
2456
2457 a = Element('a')
2458 b = SubElement(a, 'b')
2459 c = SubElement(a, 'c')
2460 d = SubElement(b, 'd')
2461 e = SubElement(c, 'e')
2462 f = SubElement(c, 'f')
2463
2464 self.assertEqual(
2465 [a, b],
2466 list(a.getiterator( ('a', 'b') )))
2467 self.assertEqual(
2468 [],
2469 list(a.getiterator( ('x', 'y') )))
2470 self.assertEqual(
2471 [a, f],
2472 list(a.getiterator( ('f', 'a') )))
2473 self.assertEqual(
2474 [c, e, f],
2475 list(c.getiterator( ('c', '*', 'a') )))
2476 self.assertEqual(
2477 [],
2478 list(a.getiterator( () )))
2479
2481 Element = self.etree.Element
2482 SubElement = self.etree.SubElement
2483
2484 a = Element('{a}a')
2485 b = SubElement(a, '{a}b')
2486 c = SubElement(a, '{a}c')
2487 d = SubElement(b, '{b}d')
2488 e = SubElement(c, '{a}e')
2489 f = SubElement(c, '{b}f')
2490 g = SubElement(c, 'g')
2491
2492 self.assertEqual(
2493 [a],
2494 list(a.getiterator('{a}a')))
2495 self.assertEqual(
2496 [],
2497 list(a.getiterator('{b}a')))
2498 self.assertEqual(
2499 [],
2500 list(a.getiterator('a')))
2501 self.assertEqual(
2502 [a,b,d,c,e,f,g],
2503 list(a.getiterator('*')))
2504 self.assertEqual(
2505 [f],
2506 list(c.getiterator('{b}*')))
2507 self.assertEqual(
2508 [d, f],
2509 list(a.getiterator('{b}*')))
2510 self.assertEqual(
2511 [g],
2512 list(a.getiterator('g')))
2513 self.assertEqual(
2514 [g],
2515 list(a.getiterator('{}g')))
2516 self.assertEqual(
2517 [g],
2518 list(a.getiterator('{}*')))
2519
2521 Element = self.etree.Element
2522 SubElement = self.etree.SubElement
2523
2524 a = Element('{a}a')
2525 b = SubElement(a, '{nsA}b')
2526 c = SubElement(b, '{nsB}b')
2527 d = SubElement(a, 'b')
2528 e = SubElement(a, '{nsA}e')
2529 f = SubElement(e, '{nsB}e')
2530 g = SubElement(e, 'e')
2531
2532 self.assertEqual(
2533 [b, c, d],
2534 list(a.getiterator('{*}b')))
2535 self.assertEqual(
2536 [e, f, g],
2537 list(a.getiterator('{*}e')))
2538 self.assertEqual(
2539 [a, b, c, d, e, f, g],
2540 list(a.getiterator('{*}*')))
2541
2566
2582
2599
2606
2613
2622
2624 XML = self.etree.XML
2625 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2626 self.assertEqual(len(root.findall(".//{X}b")), 2)
2627 self.assertEqual(len(root.findall(".//{X}*")), 2)
2628 self.assertEqual(len(root.findall(".//b")), 3)
2629
2631 XML = self.etree.XML
2632 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2633 nsmap = {'xx': 'X'}
2634 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2635 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2636 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2637 nsmap = {'xx': 'Y'}
2638 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2639 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2640 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2641
2643 XML = self.etree.XML
2644 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2645 nsmap = {'xx': 'X'}
2646 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2647 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2648 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2649 nsmap = {'xx': 'Y'}
2650 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2651 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2652 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2653
2660
2662 etree = self.etree
2663 e = etree.Element('foo')
2664 for i in range(10):
2665 etree.SubElement(e, 'a%s' % i)
2666 for i in range(10):
2667 self.assertEqual(
2668 i,
2669 e.index(e[i]))
2670 self.assertEqual(
2671 3, e.index(e[3], 3))
2672 self.assertRaises(
2673 ValueError, e.index, e[3], 4)
2674 self.assertRaises(
2675 ValueError, e.index, e[3], 0, 2)
2676 self.assertRaises(
2677 ValueError, e.index, e[8], 0, -3)
2678 self.assertRaises(
2679 ValueError, e.index, e[8], -5, -3)
2680 self.assertEqual(
2681 8, e.index(e[8], 0, -1))
2682 self.assertEqual(
2683 8, e.index(e[8], -12, -1))
2684 self.assertEqual(
2685 0, e.index(e[0], -12, -1))
2686
2688 etree = self.etree
2689 e = etree.Element('foo')
2690 for i in range(10):
2691 el = etree.SubElement(e, 'a%s' % i)
2692 el.text = "text%d" % i
2693 el.tail = "tail%d" % i
2694
2695 child0 = e[0]
2696 child1 = e[1]
2697 child2 = e[2]
2698
2699 e.replace(e[0], e[1])
2700 self.assertEqual(
2701 9, len(e))
2702 self.assertEqual(
2703 child1, e[0])
2704 self.assertEqual(
2705 child1.text, "text1")
2706 self.assertEqual(
2707 child1.tail, "tail1")
2708 self.assertEqual(
2709 child0.tail, "tail0")
2710 self.assertEqual(
2711 child2, e[1])
2712
2713 e.replace(e[-1], e[0])
2714 self.assertEqual(
2715 child1, e[-1])
2716 self.assertEqual(
2717 child1.text, "text1")
2718 self.assertEqual(
2719 child1.tail, "tail1")
2720 self.assertEqual(
2721 child2, e[0])
2722
2724 etree = self.etree
2725 e = etree.Element('foo')
2726 for i in range(10):
2727 etree.SubElement(e, 'a%s' % i)
2728
2729 new_element = etree.Element("test")
2730 new_element.text = "TESTTEXT"
2731 new_element.tail = "TESTTAIL"
2732 child1 = e[1]
2733 e.replace(e[0], new_element)
2734 self.assertEqual(
2735 new_element, e[0])
2736 self.assertEqual(
2737 "TESTTEXT",
2738 e[0].text)
2739 self.assertEqual(
2740 "TESTTAIL",
2741 e[0].tail)
2742 self.assertEqual(
2743 child1, e[1])
2744
2760
2778
2796
2814
2816 Element = self.etree.Element
2817 SubElement = self.etree.SubElement
2818 try:
2819 slice
2820 except NameError:
2821 print("slice() not found")
2822 return
2823
2824 a = Element('a')
2825 b = SubElement(a, 'b')
2826 c = SubElement(a, 'c')
2827 d = SubElement(a, 'd')
2828 e = SubElement(a, 'e')
2829
2830 x = Element('x')
2831 y = Element('y')
2832 z = Element('z')
2833
2834 self.assertRaises(
2835 ValueError,
2836 operator.setitem, a, slice(1,None,2), [x, y, z])
2837
2838 self.assertEqual(
2839 [b, c, d, e],
2840 list(a))
2841
2854
2862
2871
2881
2891
2897
2905
2911
2918
2924
2926 etree = self.etree
2927 xml_header = '<?xml version="1.0" encoding="ascii"?>'
2928 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2929 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2930 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
2931
2932 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2933
2934 tree = etree.parse(BytesIO(xml))
2935 docinfo = tree.docinfo
2936 self.assertEqual(docinfo.encoding, "ascii")
2937 self.assertEqual(docinfo.xml_version, "1.0")
2938 self.assertEqual(docinfo.public_id, pub_id)
2939 self.assertEqual(docinfo.system_url, sys_id)
2940 self.assertEqual(docinfo.root_name, 'html')
2941 self.assertEqual(docinfo.doctype, doctype_string)
2942
2958
2970
2982
2988
2990 etree = self.etree
2991 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2992 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2993 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
2994
2995 xml = _bytes('<!DOCTYPE root>\n<root/>')
2996 tree = etree.parse(BytesIO(xml))
2997 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
2998 etree.tostring(tree, doctype=doctype_string))
2999
3001 etree = self.etree
3002 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3003 self.assertEqual(root.base, "http://no/such/url")
3004 self.assertEqual(
3005 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3006 root.base = "https://secret/url"
3007 self.assertEqual(root.base, "https://secret/url")
3008 self.assertEqual(
3009 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3010 "https://secret/url")
3011
3013 etree = self.etree
3014 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3015 self.assertEqual(root.base, "http://no/such/url")
3016 self.assertEqual(
3017 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3018 root.set('{http://www.w3.org/XML/1998/namespace}base',
3019 "https://secret/url")
3020 self.assertEqual(root.base, "https://secret/url")
3021 self.assertEqual(
3022 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3023 "https://secret/url")
3024
3030
3035
3042
3056
3058 Element = self.etree.Element
3059
3060 a = Element('a')
3061 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3062 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3063
3064 self.assertRaises(ValueError, Element, 'ha\0ho')
3065
3067 Element = self.etree.Element
3068
3069 a = Element('a')
3070 self.assertRaises(ValueError, setattr, a, "text",
3071 _str('ha\0ho'))
3072 self.assertRaises(ValueError, setattr, a, "tail",
3073 _str('ha\0ho'))
3074
3075 self.assertRaises(ValueError, Element,
3076 _str('ha\0ho'))
3077
3079 Element = self.etree.Element
3080
3081 a = Element('a')
3082 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3083 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3084
3085 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3086 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3087
3088 self.assertRaises(ValueError, Element, 'ha\x07ho')
3089 self.assertRaises(ValueError, Element, 'ha\x02ho')
3090
3092 Element = self.etree.Element
3093
3094 a = Element('a')
3095 self.assertRaises(ValueError, setattr, a, "text",
3096 _str('ha\x07ho'))
3097 self.assertRaises(ValueError, setattr, a, "text",
3098 _str('ha\x02ho'))
3099
3100 self.assertRaises(ValueError, setattr, a, "tail",
3101 _str('ha\x07ho'))
3102 self.assertRaises(ValueError, setattr, a, "tail",
3103 _str('ha\x02ho'))
3104
3105 self.assertRaises(ValueError, Element,
3106 _str('ha\x07ho'))
3107 self.assertRaises(ValueError, Element,
3108 _str('ha\x02ho'))
3109
3111 Element = self.etree.Element
3112
3113 a = Element('a')
3114 self.assertRaises(ValueError, setattr, a, "text",
3115 _str('ha\u1234\x07ho'))
3116 self.assertRaises(ValueError, setattr, a, "text",
3117 _str('ha\u1234\x02ho'))
3118
3119 self.assertRaises(ValueError, setattr, a, "tail",
3120 _str('ha\u1234\x07ho'))
3121 self.assertRaises(ValueError, setattr, a, "tail",
3122 _str('ha\u1234\x02ho'))
3123
3124 self.assertRaises(ValueError, Element,
3125 _str('ha\u1234\x07ho'))
3126 self.assertRaises(ValueError, Element,
3127 _str('ha\u1234\x02ho'))
3128
3142
3147
3165
3185
3207
3209 tostring = self.etree.tostring
3210 XML = self.etree.XML
3211 ElementTree = self.etree.ElementTree
3212
3213 root = XML(_bytes("<root/>"))
3214
3215 tree = ElementTree(root)
3216 self.assertEqual(None, tree.docinfo.standalone)
3217
3218 result = tostring(root, xml_declaration=True, encoding="ASCII")
3219 self.assertEqual(result, _bytes(
3220 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3221
3222 result = tostring(root, xml_declaration=True, encoding="ASCII",
3223 standalone=True)
3224 self.assertEqual(result, _bytes(
3225 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3226
3227 tree = ElementTree(XML(result))
3228 self.assertEqual(True, tree.docinfo.standalone)
3229
3230 result = tostring(root, xml_declaration=True, encoding="ASCII",
3231 standalone=False)
3232 self.assertEqual(result, _bytes(
3233 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3234
3235 tree = ElementTree(XML(result))
3236 self.assertEqual(False, tree.docinfo.standalone)
3237
3257
3259 tostring = self.etree.tostring
3260 Element = self.etree.Element
3261 SubElement = self.etree.SubElement
3262
3263 a = Element('a')
3264 a.text = "A"
3265 a.tail = "tail"
3266 b = SubElement(a, 'b')
3267 b.text = "B"
3268 b.tail = _str("Søk på nettet")
3269 c = SubElement(a, 'c')
3270 c.text = "C"
3271
3272 result = tostring(a, method="text", encoding="UTF-16")
3273
3274 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3275 result)
3276
3278 tostring = self.etree.tostring
3279 Element = self.etree.Element
3280 SubElement = self.etree.SubElement
3281
3282 a = Element('a')
3283 a.text = _str('Søk på nettetA')
3284 a.tail = "tail"
3285 b = SubElement(a, 'b')
3286 b.text = "B"
3287 b.tail = _str('Søk på nettetB')
3288 c = SubElement(a, 'c')
3289 c.text = "C"
3290
3291 self.assertRaises(UnicodeEncodeError,
3292 tostring, a, method="text")
3293
3294 self.assertEqual(
3295 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3296 tostring(a, encoding="UTF-8", method="text"))
3297
3310
3326
3330
3345
3363
3376
3378 tostring = self.etree.tostring
3379 Element = self.etree.Element
3380 SubElement = self.etree.SubElement
3381
3382 a = Element('a')
3383 b = SubElement(a, 'b')
3384 c = SubElement(a, 'c')
3385 d = SubElement(c, 'd')
3386 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3387 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3388 self.assertEqual(_bytes('<b></b>'),
3389 canonicalize(tostring(b, encoding=_unicode)))
3390 self.assertEqual(_bytes('<c><d></d></c>'),
3391 canonicalize(tostring(c, encoding=_unicode)))
3392
3397
3412
3414 tostring = self.etree.tostring
3415 Element = self.etree.Element
3416 SubElement = self.etree.SubElement
3417
3418 a = Element('a')
3419 b = SubElement(a, 'b')
3420 c = SubElement(a, 'c')
3421
3422 result = tostring(a, encoding=_unicode)
3423 self.assertEqual(result, "<a><b/><c/></a>")
3424
3425 result = tostring(a, encoding=_unicode, pretty_print=False)
3426 self.assertEqual(result, "<a><b/><c/></a>")
3427
3428 result = tostring(a, encoding=_unicode, pretty_print=True)
3429 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3430
3442
3444 class SubEl(etree.ElementBase):
3445 pass
3446
3447 el1 = SubEl()
3448 el2 = SubEl()
3449 self.assertEqual('SubEl', el1.tag)
3450 self.assertEqual('SubEl', el2.tag)
3451 el1.other = el2
3452 el2.other = el1
3453
3454 del el1, el2
3455 gc.collect()
3456
3457
3458
3459
3460 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3471
3472
3475 filename = fileInTestDir('test_broken.xml')
3476 root = etree.XML(_bytes('''\
3477 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3478 <xi:include href="%s" parse="text"/>
3479 </doc>
3480 ''' % filename))
3481 old_text = root.text
3482 content = read_file(filename)
3483 old_tail = root[0].tail
3484
3485 self.include( etree.ElementTree(root) )
3486 self.assertEqual(old_text + content + old_tail,
3487 root.text)
3488
3500
3502 class res(etree.Resolver):
3503 include_text = read_file(fileInTestDir('test.xml'))
3504 called = {}
3505 def resolve(self, url, id, context):
3506 if url.endswith(".dtd"):
3507 self.called["dtd"] = True
3508 return self.resolve_filename(
3509 fileInTestDir('test.dtd'), context)
3510 elif url.endswith("test_xinclude.xml"):
3511 self.called["input"] = True
3512 return None
3513 else:
3514 self.called["include"] = True
3515 return self.resolve_string(self.include_text, context)
3516
3517 res_instance = res()
3518 parser = etree.XMLParser(load_dtd = True)
3519 parser.resolvers.add(res_instance)
3520
3521 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3522 parser = parser)
3523
3524 self.include(tree)
3525
3526 called = list(res_instance.called.items())
3527 called.sort()
3528 self.assertEqual(
3529 [("dtd", True), ("include", True), ("input", True)],
3530 called)
3531
3535
3536
3541
3542
3545 tree = self.parse(_bytes('<a><b/></a>'))
3546 f = BytesIO()
3547 tree.write_c14n(f)
3548 s = f.getvalue()
3549 self.assertEqual(_bytes('<a><b></b></a>'),
3550 s)
3551
3553 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3554 f = BytesIO()
3555 tree.write_c14n(f, compression=9)
3556 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3557 try:
3558 s = gzfile.read()
3559 finally:
3560 gzfile.close()
3561 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3562 s)
3563
3575
3591
3609
3621
3633
3635 tree = self.parse(_bytes(
3636 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3637 f = BytesIO()
3638 tree.write_c14n(f)
3639 s = f.getvalue()
3640 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3641 s)
3642 f = BytesIO()
3643 tree.write_c14n(f, exclusive=False)
3644 s = f.getvalue()
3645 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3646 s)
3647 f = BytesIO()
3648 tree.write_c14n(f, exclusive=True)
3649 s = f.getvalue()
3650 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3651 s)
3652
3653 f = BytesIO()
3654 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
3655 s = f.getvalue()
3656 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
3657 s)
3658
3660 tree = self.parse(_bytes(
3661 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3662 s = etree.tostring(tree, method='c14n')
3663 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3664 s)
3665 s = etree.tostring(tree, method='c14n', exclusive=False)
3666 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3667 s)
3668 s = etree.tostring(tree, method='c14n', exclusive=True)
3669 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3670 s)
3671
3672 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3673 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
3674 s)
3675
3677 tree = self.parse(_bytes(
3678 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3679 s = etree.tostring(tree.getroot(), method='c14n')
3680 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3681 s)
3682 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3683 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3684 s)
3685 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3686 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3687 s)
3688
3689 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3690 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3691 s)
3692 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3693 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3694 s)
3695
3696 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3697 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3698 s)
3699
3701 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
3702 tree = self.parse(_bytes(
3703 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3704
3705 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
3706 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3707 s)
3708
3709
3712 tree = self.parse(_bytes('<a><b/></a>'))
3713 f = BytesIO()
3714 tree.write(f)
3715 s = f.getvalue()
3716 self.assertEqual(_bytes('<a><b/></a>'),
3717 s)
3718
3720 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3721 f = BytesIO()
3722 tree.write(f, compression=9)
3723 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3724 try:
3725 s = gzfile.read()
3726 finally:
3727 gzfile.close()
3728 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3729 s)
3730
3732 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3733 f = BytesIO()
3734 tree.write(f, compression=0)
3735 s0 = f.getvalue()
3736
3737 f = BytesIO()
3738 tree.write(f)
3739 self.assertEqual(f.getvalue(), s0)
3740
3741 f = BytesIO()
3742 tree.write(f, compression=1)
3743 s = f.getvalue()
3744 self.assertTrue(len(s) <= len(s0))
3745 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3746 try:
3747 s1 = gzfile.read()
3748 finally:
3749 gzfile.close()
3750
3751 f = BytesIO()
3752 tree.write(f, compression=9)
3753 s = f.getvalue()
3754 self.assertTrue(len(s) <= len(s0))
3755 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3756 try:
3757 s9 = gzfile.read()
3758 finally:
3759 gzfile.close()
3760
3761 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3762 s0)
3763 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3764 s1)
3765 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3766 s9)
3767
3779
3795
3807
3820
3822 etree = etree
3823
3845
3847 """This can't really be tested as long as there isn't a way to
3848 reset the logging setup ...
3849 """
3850 parse = self.etree.parse
3851
3852 messages = []
3853 class Logger(self.etree.PyErrorLog):
3854 def log(self, entry, message, *args):
3855 messages.append(message)
3856
3857 self.etree.use_global_python_log(Logger())
3858 f = BytesIO('<a><b></c></b></a>')
3859 try:
3860 parse(f)
3861 except SyntaxError:
3862 pass
3863 f.close()
3864
3865 self.assertTrue([ message for message in messages
3866 if 'mismatch' in message ])
3867 self.assertTrue([ message for message in messages
3868 if ':PARSER:' in message])
3869 self.assertTrue([ message for message in messages
3870 if ':ERR_TAG_NAME_MISMATCH:' in message ])
3871 self.assertTrue([ message for message in messages
3872 if ':1:15:' in message ])
3873
3874
3876 etree = etree
3877
3881
3883 class Target(object):
3884 def start(self, tag, attrib):
3885 return 'start(%s)' % tag
3886 def end(self, tag):
3887 return 'end(%s)' % tag
3888 def close(self):
3889 return 'close()'
3890
3891 parser = self.etree.XMLPullParser(target=Target())
3892 events = parser.read_events()
3893
3894 parser.feed('<root><element>')
3895 self.assertFalse(list(events))
3896 self.assertFalse(list(events))
3897 parser.feed('</element><child>')
3898 self.assertEqual([('end', 'end(element)')], list(events))
3899 parser.feed('</child>')
3900 self.assertEqual([('end', 'end(child)')], list(events))
3901 parser.feed('</root>')
3902 self.assertEqual([('end', 'end(root)')], list(events))
3903 self.assertFalse(list(events))
3904 self.assertEqual('close()', parser.close())
3905
3907 class Target(object):
3908 def start(self, tag, attrib):
3909 return 'start(%s)' % tag
3910 def end(self, tag):
3911 return 'end(%s)' % tag
3912 def close(self):
3913 return 'close()'
3914
3915 parser = self.etree.XMLPullParser(
3916 ['start', 'end'], target=Target())
3917 events = parser.read_events()
3918
3919 parser.feed('<root><element>')
3920 self.assertEqual(
3921 [('start', 'start(root)'), ('start', 'start(element)')],
3922 list(events))
3923 self.assertFalse(list(events))
3924 parser.feed('</element><child>')
3925 self.assertEqual(
3926 [('end', 'end(element)'), ('start', 'start(child)')],
3927 list(events))
3928 parser.feed('</child>')
3929 self.assertEqual(
3930 [('end', 'end(child)')],
3931 list(events))
3932 parser.feed('</root>')
3933 self.assertEqual(
3934 [('end', 'end(root)')],
3935 list(events))
3936 self.assertFalse(list(events))
3937 self.assertEqual('close()', parser.close())
3938
3940 parser = self.etree.XMLPullParser(
3941 ['start', 'end'], target=etree.TreeBuilder())
3942 events = parser.read_events()
3943
3944 parser.feed('<root><element>')
3945 self.assert_event_tags(
3946 events, [('start', 'root'), ('start', 'element')])
3947 self.assertFalse(list(events))
3948 parser.feed('</element><child>')
3949 self.assert_event_tags(
3950 events, [('end', 'element'), ('start', 'child')])
3951 parser.feed('</child>')
3952 self.assert_event_tags(
3953 events, [('end', 'child')])
3954 parser.feed('</root>')
3955 self.assert_event_tags(
3956 events, [('end', 'root')])
3957 self.assertFalse(list(events))
3958 root = parser.close()
3959 self.assertEqual('root', root.tag)
3960
3962 class Target(etree.TreeBuilder):
3963 def end(self, tag):
3964 el = super(Target, self).end(tag)
3965 el.tag += '-huhu'
3966 return el
3967
3968 parser = self.etree.XMLPullParser(
3969 ['start', 'end'], target=Target())
3970 events = parser.read_events()
3971
3972 parser.feed('<root><element>')
3973 self.assert_event_tags(
3974 events, [('start', 'root'), ('start', 'element')])
3975 self.assertFalse(list(events))
3976 parser.feed('</element><child>')
3977 self.assert_event_tags(
3978 events, [('end', 'element-huhu'), ('start', 'child')])
3979 parser.feed('</child>')
3980 self.assert_event_tags(
3981 events, [('end', 'child-huhu')])
3982 parser.feed('</root>')
3983 self.assert_event_tags(
3984 events, [('end', 'root-huhu')])
3985 self.assertFalse(list(events))
3986 root = parser.close()
3987 self.assertEqual('root-huhu', root.tag)
3988
3989
4012
4013 if __name__ == '__main__':
4014 print('to test use test.py %s' % __file__)
4015