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("""
659 <a> \n \n <b> b test </b> \n
660
661 \n\t <c> \n </c> </a> \n """)
662 iterator = iterparse(f, remove_blank_text=True)
663 text = [ (element.text, element.tail)
664 for event, element in iterator ]
665 self.assertEqual(
666 [(" b test ", None), (" \n ", None), (None, None)],
667 text)
668
670 iterparse = self.etree.iterparse
671 f = BytesIO('<a><b><d/></b><c/></a>')
672
673 iterator = iterparse(f, tag="b", events=('start', 'end'))
674 events = list(iterator)
675 root = iterator.root
676 self.assertEqual(
677 [('start', root[0]), ('end', root[0])],
678 events)
679
681 iterparse = self.etree.iterparse
682 f = BytesIO('<a><b><d/></b><c/></a>')
683
684 iterator = iterparse(f, tag="*", events=('start', 'end'))
685 events = list(iterator)
686 self.assertEqual(
687 8,
688 len(events))
689
691 iterparse = self.etree.iterparse
692 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
693
694 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
695 events = list(iterator)
696 root = iterator.root
697 self.assertEqual(
698 [('start', root[0]), ('end', root[0])],
699 events)
700
702 iterparse = self.etree.iterparse
703 f = BytesIO('<a><b><d/></b><c/></a>')
704 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
705 events = list(iterator)
706 root = iterator.root
707 self.assertEqual(
708 [('start', root[0]), ('end', root[0])],
709 events)
710
711 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
712 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
713 events = list(iterator)
714 root = iterator.root
715 self.assertEqual([], events)
716
718 iterparse = self.etree.iterparse
719 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
720 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
721 events = list(iterator)
722 self.assertEqual(8, len(events))
723
725 iterparse = self.etree.iterparse
726 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
727 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
728 events = list(iterator)
729 self.assertEqual([], events)
730
731 f = BytesIO('<a><b><d/></b><c/></a>')
732 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
733 events = list(iterator)
734 self.assertEqual(8, len(events))
735
737 text = _str('Søk på nettet')
738 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
739 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
740 ).encode('iso-8859-1')
741
742 self.assertRaises(self.etree.ParseError,
743 list, self.etree.iterparse(BytesIO(xml_latin1)))
744
746 text = _str('Søk på nettet', encoding="UTF-8")
747 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
748 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
749 ).encode('iso-8859-1')
750
751 iterator = self.etree.iterparse(BytesIO(xml_latin1),
752 encoding="iso-8859-1")
753 self.assertEqual(1, len(list(iterator)))
754
755 a = iterator.root
756 self.assertEqual(a.text, text)
757
759 tostring = self.etree.tostring
760 f = BytesIO('<root><![CDATA[test]]></root>')
761 context = self.etree.iterparse(f, strip_cdata=False)
762 content = [ el.text for event,el in context ]
763
764 self.assertEqual(['test'], content)
765 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
766 tostring(context.root))
767
771
776
795
796
797
808 def end(self, tag):
809 events.append("end")
810 assertEqual("TAG", tag)
811 def close(self):
812 return "DONE"
813
814 parser = self.etree.XMLParser(target=Target())
815 tree = self.etree.ElementTree()
816
817 self.assertRaises(TypeError,
818 tree.parse, BytesIO("<TAG/>"), parser=parser)
819 self.assertEqual(["start", "end"], events)
820
822
823 events = []
824 class Target(object):
825 def start(self, tag, attrib):
826 events.append("start-" + tag)
827 def end(self, tag):
828 events.append("end-" + tag)
829 if tag == 'a':
830 raise ValueError("dead and gone")
831 def data(self, data):
832 events.append("data-" + data)
833 def close(self):
834 events.append("close")
835 return "DONE"
836
837 parser = self.etree.XMLParser(target=Target())
838
839 try:
840 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
841 done = parser.close()
842 self.fail("error expected, but parsing succeeded")
843 except ValueError:
844 done = 'value error received as expected'
845
846 self.assertEqual(["start-root", "data-A", "start-a",
847 "data-ca", "end-a", "close"],
848 events)
849
851
852 events = []
853 class Target(object):
854 def start(self, tag, attrib):
855 events.append("start-" + tag)
856 def end(self, tag):
857 events.append("end-" + tag)
858 if tag == 'a':
859 raise ValueError("dead and gone")
860 def data(self, data):
861 events.append("data-" + data)
862 def close(self):
863 events.append("close")
864 return "DONE"
865
866 parser = self.etree.XMLParser(target=Target())
867
868 try:
869 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
870 parser=parser)
871 self.fail("error expected, but parsing succeeded")
872 except ValueError:
873 done = 'value error received as expected'
874
875 self.assertEqual(["start-root", "data-A", "start-a",
876 "data-ca", "end-a", "close"],
877 events)
878
884 def end(self, tag):
885 events.append("end-" + tag)
886 def data(self, data):
887 events.append("data-" + data)
888 def comment(self, text):
889 events.append("comment-" + text)
890 def close(self):
891 return "DONE"
892
893 parser = self.etree.XMLParser(target=Target())
894
895 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
896 done = parser.close()
897
898 self.assertEqual("DONE", done)
899 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
900 "start-sub", "end-sub", "comment-c", "data-B",
901 "end-root", "comment-d"],
902 events)
903
905 events = []
906 class Target(object):
907 def start(self, tag, attrib):
908 events.append("start-" + tag)
909 def end(self, tag):
910 events.append("end-" + tag)
911 def data(self, data):
912 events.append("data-" + data)
913 def pi(self, target, data):
914 events.append("pi-" + target + "-" + data)
915 def close(self):
916 return "DONE"
917
918 parser = self.etree.XMLParser(target=Target())
919
920 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
921 done = parser.close()
922
923 self.assertEqual("DONE", done)
924 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b",
925 "data-B", "end-root", "pi-test-c"],
926 events)
927
929 events = []
930 class Target(object):
931 def start(self, tag, attrib):
932 events.append("start-" + tag)
933 def end(self, tag):
934 events.append("end-" + tag)
935 def data(self, data):
936 events.append("data-" + data)
937 def close(self):
938 return "DONE"
939
940 parser = self.etree.XMLParser(target=Target(),
941 strip_cdata=False)
942
943 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
944 done = parser.close()
945
946 self.assertEqual("DONE", done)
947 self.assertEqual(["start-root", "data-A", "start-a",
948 "data-ca", "end-a", "data-B", "end-root"],
949 events)
950
952 events = []
953 class Target(object):
954 def start(self, tag, attrib):
955 events.append("start-" + tag)
956 def end(self, tag):
957 events.append("end-" + tag)
958 def data(self, data):
959 events.append("data-" + data)
960 def close(self):
961 events.append("close")
962 return "DONE"
963
964 parser = self.etree.XMLParser(target=Target(),
965 recover=True)
966
967 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
968 done = parser.close()
969
970 self.assertEqual("DONE", done)
971 self.assertEqual(["start-root", "data-A", "start-a",
972 "data-ca", "end-a", "data-B",
973 "end-root", "close"],
974 events)
975
985
995
1004
1014
1016 iterwalk = self.etree.iterwalk
1017 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1018
1019 iterator = iterwalk(root, events=('start','end'))
1020 events = list(iterator)
1021 self.assertEqual(
1022 [('start', root), ('start', root[0]), ('end', root[0]),
1023 ('start', root[1]), ('end', root[1]), ('end', root)],
1024 events)
1025
1036
1038 iterwalk = self.etree.iterwalk
1039 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1040
1041 attr_name = '{testns}bla'
1042 events = []
1043 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1044 for event, elem in iterator:
1045 events.append(event)
1046 if event == 'start':
1047 if elem.tag != '{ns1}a':
1048 elem.set(attr_name, 'value')
1049
1050 self.assertEqual(
1051 ['start-ns', 'start', 'start', 'start-ns', 'start',
1052 'end', 'end-ns', 'end', 'end', 'end-ns'],
1053 events)
1054
1055 self.assertEqual(
1056 None,
1057 root.get(attr_name))
1058 self.assertEqual(
1059 'value',
1060 root[0].get(attr_name))
1061
1072
1074 parse = self.etree.parse
1075 parser = self.etree.XMLParser(dtd_validation=True)
1076 assertEqual = self.assertEqual
1077 test_url = _str("__nosuch.dtd")
1078
1079 class MyResolver(self.etree.Resolver):
1080 def resolve(self, url, id, context):
1081 assertEqual(url, test_url)
1082 return self.resolve_string(
1083 _str('''<!ENTITY myentity "%s">
1084 <!ELEMENT doc ANY>''') % url, context)
1085
1086 parser.resolvers.add(MyResolver())
1087
1088 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1089 tree = parse(StringIO(xml), parser)
1090 root = tree.getroot()
1091 self.assertEqual(root.text, test_url)
1092
1094 parse = self.etree.parse
1095 parser = self.etree.XMLParser(dtd_validation=True)
1096 assertEqual = self.assertEqual
1097 test_url = _str("__nosuch.dtd")
1098
1099 class MyResolver(self.etree.Resolver):
1100 def resolve(self, url, id, context):
1101 assertEqual(url, test_url)
1102 return self.resolve_string(
1103 (_str('''<!ENTITY myentity "%s">
1104 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1105 context)
1106
1107 parser.resolvers.add(MyResolver())
1108
1109 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1110 tree = parse(StringIO(xml), parser)
1111 root = tree.getroot()
1112 self.assertEqual(root.text, test_url)
1113
1115 parse = self.etree.parse
1116 parser = self.etree.XMLParser(dtd_validation=True)
1117 assertEqual = self.assertEqual
1118 test_url = _str("__nosuch.dtd")
1119
1120 class MyResolver(self.etree.Resolver):
1121 def resolve(self, url, id, context):
1122 assertEqual(url, test_url)
1123 return self.resolve_file(
1124 SillyFileLike(
1125 _str('''<!ENTITY myentity "%s">
1126 <!ELEMENT doc ANY>''') % url), context)
1127
1128 parser.resolvers.add(MyResolver())
1129
1130 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1131 tree = parse(StringIO(xml), parser)
1132 root = tree.getroot()
1133 self.assertEqual(root.text, test_url)
1134
1136 parse = self.etree.parse
1137 parser = self.etree.XMLParser(attribute_defaults=True)
1138 assertEqual = self.assertEqual
1139 test_url = _str("__nosuch.dtd")
1140
1141 class MyResolver(self.etree.Resolver):
1142 def resolve(self, url, id, context):
1143 assertEqual(url, test_url)
1144 return self.resolve_filename(
1145 fileInTestDir('test.dtd'), context)
1146
1147 parser.resolvers.add(MyResolver())
1148
1149 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1150 tree = parse(StringIO(xml), parser)
1151 root = tree.getroot()
1152 self.assertEqual(
1153 root.attrib, {'default': 'valueA'})
1154 self.assertEqual(
1155 root[0].attrib, {'default': 'valueB'})
1156
1168
1169 parser.resolvers.add(MyResolver())
1170
1171 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1172 tree = parse(StringIO(xml), parser,
1173 base_url=fileInTestDir('__test.xml'))
1174 root = tree.getroot()
1175 self.assertEqual(
1176 root.attrib, {'default': 'valueA'})
1177 self.assertEqual(
1178 root[0].attrib, {'default': 'valueB'})
1179
1181 parse = self.etree.parse
1182 parser = self.etree.XMLParser(attribute_defaults=True)
1183 assertEqual = self.assertEqual
1184 test_url = _str("__nosuch.dtd")
1185
1186 class MyResolver(self.etree.Resolver):
1187 def resolve(self, url, id, context):
1188 assertEqual(url, test_url)
1189 return self.resolve_file(
1190 open(fileInTestDir('test.dtd'), 'rb'), context)
1191
1192 parser.resolvers.add(MyResolver())
1193
1194 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1195 tree = parse(StringIO(xml), parser)
1196 root = tree.getroot()
1197 self.assertEqual(
1198 root.attrib, {'default': 'valueA'})
1199 self.assertEqual(
1200 root[0].attrib, {'default': 'valueB'})
1201
1203 parse = self.etree.parse
1204 parser = self.etree.XMLParser(load_dtd=True)
1205 assertEqual = self.assertEqual
1206 test_url = _str("__nosuch.dtd")
1207
1208 class check(object):
1209 resolved = False
1210
1211 class MyResolver(self.etree.Resolver):
1212 def resolve(self, url, id, context):
1213 assertEqual(url, test_url)
1214 check.resolved = True
1215 return self.resolve_empty(context)
1216
1217 parser.resolvers.add(MyResolver())
1218
1219 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1220 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1221 self.assertTrue(check.resolved)
1222
1229
1230 class MyResolver(self.etree.Resolver):
1231 def resolve(self, url, id, context):
1232 raise _LocalException
1233
1234 parser.resolvers.add(MyResolver())
1235
1236 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1237 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1238
1239 if etree.LIBXML_VERSION > (2,6,20):
1256
1258 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1259 <root>
1260 <child1/>
1261 <child2/>
1262 <child3> </child3>
1263 </root>''')
1264
1265 parser = self.etree.XMLParser(resolve_entities=False)
1266 root = etree.fromstring(xml, parser)
1267 self.assertEqual([ el.tag for el in root ],
1268 ['child1', 'child2', 'child3'])
1269
1270 root[0] = root[-1]
1271 self.assertEqual([ el.tag for el in root ],
1272 ['child3', 'child2'])
1273 self.assertEqual(root[0][0].text, ' ')
1274 self.assertEqual(root[0][0].name, 'nbsp')
1275
1291
1298
1300 Entity = self.etree.Entity
1301 self.assertRaises(ValueError, Entity, 'a b c')
1302 self.assertRaises(ValueError, Entity, 'a,b')
1303 self.assertRaises(ValueError, Entity, 'a\0b')
1304 self.assertRaises(ValueError, Entity, '#abc')
1305 self.assertRaises(ValueError, Entity, '#xxyz')
1306
1319
1332
1334 CDATA = self.etree.CDATA
1335 Element = self.etree.Element
1336
1337 root = Element("root")
1338 cdata = CDATA('test')
1339
1340 self.assertRaises(TypeError,
1341 setattr, root, 'tail', cdata)
1342 self.assertRaises(TypeError,
1343 root.set, 'attr', cdata)
1344 self.assertRaises(TypeError,
1345 operator.setitem, root.attrib, 'attr', cdata)
1346
1355
1364
1365
1375
1384
1386 Element = self.etree.Element
1387 SubElement = self.etree.SubElement
1388 root = Element('root')
1389 self.assertRaises(ValueError, root.append, root)
1390 child = SubElement(root, 'child')
1391 self.assertRaises(ValueError, child.append, root)
1392 child2 = SubElement(child, 'child2')
1393 self.assertRaises(ValueError, child2.append, root)
1394 self.assertRaises(ValueError, child2.append, child)
1395 self.assertEqual('child2', root[0][0].tag)
1396
1409
1422
1438
1454
1460
1475
1488
1503
1516
1531
1544
1559
1572
1573
1581
1582
1592
1593
1608
1609
1619
1620
1631
1632
1634 self.assertRaises(TypeError, self.etree.dump, None)
1635
1648
1661
1682
1691
1700
1709
1718
1727
1729 XML = self.etree.XML
1730
1731 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1732 result = []
1733 for el in root.iterchildren(tag=['two', 'three']):
1734 result.append(el.text)
1735 self.assertEqual(['Two', 'Bla', None], result)
1736
1738 XML = self.etree.XML
1739
1740 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1741 result = []
1742 for el in root.iterchildren('two', 'three'):
1743 result.append(el.text)
1744 self.assertEqual(['Two', 'Bla', None], result)
1745
1754
1775
1797
1799 Element = self.etree.Element
1800 SubElement = self.etree.SubElement
1801
1802 a = Element('a')
1803 b = SubElement(a, 'b')
1804 c = SubElement(a, 'c')
1805 d = SubElement(b, 'd')
1806 self.assertEqual(
1807 [b, a],
1808 list(d.iterancestors(tag=('a', 'b'))))
1809 self.assertEqual(
1810 [b, a],
1811 list(d.iterancestors('a', 'b')))
1812
1813 self.assertEqual(
1814 [],
1815 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
1816 self.assertEqual(
1817 [],
1818 list(d.iterancestors('w', 'x', 'y', 'z')))
1819
1820 self.assertEqual(
1821 [],
1822 list(d.iterancestors(tag=('d', 'x'))))
1823 self.assertEqual(
1824 [],
1825 list(d.iterancestors('d', 'x')))
1826
1827 self.assertEqual(
1828 [b, a],
1829 list(d.iterancestors(tag=('b', '*'))))
1830 self.assertEqual(
1831 [b, a],
1832 list(d.iterancestors('b', '*')))
1833
1834 self.assertEqual(
1835 [b],
1836 list(d.iterancestors(tag=('b', 'c'))))
1837 self.assertEqual(
1838 [b],
1839 list(d.iterancestors('b', 'c')))
1840
1857
1859 Element = self.etree.Element
1860 SubElement = self.etree.SubElement
1861
1862 a = Element('a')
1863 b = SubElement(a, 'b')
1864 c = SubElement(a, 'c')
1865 d = SubElement(b, 'd')
1866 e = SubElement(c, 'e')
1867
1868 self.assertEqual(
1869 [],
1870 list(a.iterdescendants('a')))
1871 self.assertEqual(
1872 [],
1873 list(a.iterdescendants(tag='a')))
1874
1875 a2 = SubElement(e, 'a')
1876 self.assertEqual(
1877 [a2],
1878 list(a.iterdescendants('a')))
1879
1880 self.assertEqual(
1881 [a2],
1882 list(c.iterdescendants('a')))
1883 self.assertEqual(
1884 [a2],
1885 list(c.iterdescendants(tag='a')))
1886
1888 Element = self.etree.Element
1889 SubElement = self.etree.SubElement
1890
1891 a = Element('a')
1892 b = SubElement(a, 'b')
1893 c = SubElement(a, 'c')
1894 d = SubElement(b, 'd')
1895 e = SubElement(c, 'e')
1896
1897 self.assertEqual(
1898 [b, e],
1899 list(a.iterdescendants(tag=('a', 'b', 'e'))))
1900 self.assertEqual(
1901 [b, e],
1902 list(a.iterdescendants('a', 'b', 'e')))
1903
1904 a2 = SubElement(e, 'a')
1905 self.assertEqual(
1906 [b, a2],
1907 list(a.iterdescendants(tag=('a', 'b'))))
1908 self.assertEqual(
1909 [b, a2],
1910 list(a.iterdescendants('a', 'b')))
1911
1912 self.assertEqual(
1913 [],
1914 list(c.iterdescendants(tag=('x', 'y', 'z'))))
1915 self.assertEqual(
1916 [],
1917 list(c.iterdescendants('x', 'y', 'z')))
1918
1919 self.assertEqual(
1920 [b, d, c, e, a2],
1921 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
1922 self.assertEqual(
1923 [b, d, c, e, a2],
1924 list(a.iterdescendants('x', 'y', 'z', '*')))
1925
1943
1960
1978
2002
2004 Element = self.etree.Element
2005 SubElement = self.etree.SubElement
2006
2007 a = Element('a')
2008 b = SubElement(a, 'b')
2009 c = SubElement(a, 'c')
2010 d = SubElement(b, 'd')
2011 self.assertEqual(
2012 [],
2013 list(a.itersiblings(tag='XXX')))
2014 self.assertEqual(
2015 [c],
2016 list(b.itersiblings(tag='c')))
2017 self.assertEqual(
2018 [c],
2019 list(b.itersiblings(tag='*')))
2020 self.assertEqual(
2021 [b],
2022 list(c.itersiblings(preceding=True, tag='b')))
2023 self.assertEqual(
2024 [],
2025 list(c.itersiblings(preceding=True, tag='c')))
2026
2028 Element = self.etree.Element
2029 SubElement = self.etree.SubElement
2030
2031 a = Element('a')
2032 b = SubElement(a, 'b')
2033 c = SubElement(a, 'c')
2034 d = SubElement(b, 'd')
2035 e = SubElement(a, 'e')
2036 self.assertEqual(
2037 [],
2038 list(a.itersiblings(tag=('XXX', 'YYY'))))
2039 self.assertEqual(
2040 [c, e],
2041 list(b.itersiblings(tag=('c', 'd', 'e'))))
2042 self.assertEqual(
2043 [b],
2044 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2045 self.assertEqual(
2046 [c, b],
2047 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2048
2050 parseid = self.etree.parseid
2051 XML = self.etree.XML
2052 xml_text = _bytes('''
2053 <!DOCTYPE document [
2054 <!ELEMENT document (h1,p)*>
2055 <!ELEMENT h1 (#PCDATA)>
2056 <!ATTLIST h1 myid ID #REQUIRED>
2057 <!ELEMENT p (#PCDATA)>
2058 <!ATTLIST p someid ID #REQUIRED>
2059 ]>
2060 <document>
2061 <h1 myid="chapter1">...</h1>
2062 <p id="note1" class="note">...</p>
2063 <p>Regular paragraph.</p>
2064 <p xml:id="xmlid">XML:ID paragraph.</p>
2065 <p someid="warn1" class="warning">...</p>
2066 </document>
2067 ''')
2068
2069 tree, dic = parseid(BytesIO(xml_text))
2070 root = tree.getroot()
2071 root2 = XML(xml_text)
2072 self.assertEqual(self._writeElement(root),
2073 self._writeElement(root2))
2074 expected = {
2075 "chapter1" : root[0],
2076 "xmlid" : root[3],
2077 "warn1" : root[4]
2078 }
2079 self.assertTrue("chapter1" in dic)
2080 self.assertTrue("warn1" in dic)
2081 self.assertTrue("xmlid" in dic)
2082 self._checkIDDict(dic, expected)
2083
2085 XMLDTDID = self.etree.XMLDTDID
2086 XML = self.etree.XML
2087 xml_text = _bytes('''
2088 <!DOCTYPE document [
2089 <!ELEMENT document (h1,p)*>
2090 <!ELEMENT h1 (#PCDATA)>
2091 <!ATTLIST h1 myid ID #REQUIRED>
2092 <!ELEMENT p (#PCDATA)>
2093 <!ATTLIST p someid ID #REQUIRED>
2094 ]>
2095 <document>
2096 <h1 myid="chapter1">...</h1>
2097 <p id="note1" class="note">...</p>
2098 <p>Regular paragraph.</p>
2099 <p xml:id="xmlid">XML:ID paragraph.</p>
2100 <p someid="warn1" class="warning">...</p>
2101 </document>
2102 ''')
2103
2104 root, dic = XMLDTDID(xml_text)
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 <document>
2123 <h1 myid="chapter1">...</h1>
2124 <p id="note1" class="note">...</p>
2125 <p>Regular paragraph.</p>
2126 <p someid="warn1" class="warning">...</p>
2127 </document>
2128 ''')
2129
2130 root, dic = XMLDTDID(xml_text)
2131 root2 = XML(xml_text)
2132 self.assertEqual(self._writeElement(root),
2133 self._writeElement(root2))
2134 expected = {}
2135 self._checkIDDict(dic, expected)
2136
2138 self.assertEqual(len(dic),
2139 len(expected))
2140 self.assertEqual(sorted(dic.items()),
2141 sorted(expected.items()))
2142 if sys.version_info < (3,):
2143 self.assertEqual(sorted(dic.iteritems()),
2144 sorted(expected.iteritems()))
2145 self.assertEqual(sorted(dic.keys()),
2146 sorted(expected.keys()))
2147 if sys.version_info < (3,):
2148 self.assertEqual(sorted(dic.iterkeys()),
2149 sorted(expected.iterkeys()))
2150 if sys.version_info < (3,):
2151 self.assertEqual(sorted(dic.values()),
2152 sorted(expected.values()))
2153 self.assertEqual(sorted(dic.itervalues()),
2154 sorted(expected.itervalues()))
2155
2157 etree = self.etree
2158
2159 r = {'foo': 'http://ns.infrae.com/foo'}
2160 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2161 self.assertEqual(
2162 'foo',
2163 e.prefix)
2164 self.assertEqual(
2165 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2166 self._writeElement(e))
2167
2169 etree = self.etree
2170
2171 r = {None: 'http://ns.infrae.com/foo'}
2172 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2173 self.assertEqual(
2174 None,
2175 e.prefix)
2176 self.assertEqual(
2177 '{http://ns.infrae.com/foo}bar',
2178 e.tag)
2179 self.assertEqual(
2180 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2181 self._writeElement(e))
2182
2184 etree = self.etree
2185
2186 r = {None: 'http://ns.infrae.com/foo',
2187 'hoi': 'http://ns.infrae.com/hoi'}
2188 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2189 e.set('{http://ns.infrae.com/hoi}test', 'value')
2190 self.assertEqual(
2191 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2192 self._writeElement(e))
2193
2195 etree = self.etree
2196
2197 root = etree.Element('{http://test/ns}root',
2198 nsmap={None: 'http://test/ns'})
2199 sub = etree.Element('{http://test/ns}sub',
2200 nsmap={'test': 'http://test/ns'})
2201
2202 sub.attrib['{http://test/ns}attr'] = 'value'
2203 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2204 self.assertEqual(
2205 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2206 etree.tostring(sub))
2207
2208 root.append(sub)
2209 self.assertEqual(
2210 _bytes('<root xmlns="http://test/ns">'
2211 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2212 '</root>'),
2213 etree.tostring(root))
2214
2216 etree = self.etree
2217
2218 root = etree.Element('root')
2219 sub = etree.Element('{http://test/ns}sub',
2220 nsmap={'test': 'http://test/ns'})
2221
2222 sub.attrib['{http://test/ns}attr'] = 'value'
2223 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2224 self.assertEqual(
2225 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2226 etree.tostring(sub))
2227
2228 root.append(sub)
2229 self.assertEqual(
2230 _bytes('<root>'
2231 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2232 '</root>'),
2233 etree.tostring(root))
2234
2236 etree = self.etree
2237
2238 root = etree.Element('root')
2239 sub = etree.Element('{http://test/ns}sub',
2240 nsmap={None: 'http://test/ns'})
2241
2242 sub.attrib['{http://test/ns}attr'] = 'value'
2243 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2244 self.assertEqual(
2245 _bytes('<sub xmlns="http://test/ns" '
2246 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2247 etree.tostring(sub))
2248
2249 root.append(sub)
2250 self.assertEqual(
2251 _bytes('<root>'
2252 '<sub xmlns="http://test/ns"'
2253 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2254 '</root>'),
2255 etree.tostring(root))
2256
2258 etree = self.etree
2259
2260 root = etree.Element('{http://test/ns}root',
2261 nsmap={'test': 'http://test/ns',
2262 None: 'http://test/ns'})
2263 sub = etree.Element('{http://test/ns}sub',
2264 nsmap={None: 'http://test/ns'})
2265
2266 sub.attrib['{http://test/ns}attr'] = 'value'
2267 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2268 self.assertEqual(
2269 _bytes('<sub xmlns="http://test/ns" '
2270 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2271 etree.tostring(sub))
2272
2273 root.append(sub)
2274 self.assertEqual(
2275 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2276 '<test:sub test:attr="value"/>'
2277 '</test:root>'),
2278 etree.tostring(root))
2279
2281 etree = self.etree
2282 r = {None: 'http://ns.infrae.com/foo',
2283 'hoi': 'http://ns.infrae.com/hoi'}
2284 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2285 tree = etree.ElementTree(element=e)
2286 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2287 self.assertEqual(
2288 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2289 self._writeElement(e))
2290
2292 etree = self.etree
2293
2294 r = {None: 'http://ns.infrae.com/foo'}
2295 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2296 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2297
2298 e1.append(e2)
2299
2300 self.assertEqual(
2301 None,
2302 e1.prefix)
2303 self.assertEqual(
2304 None,
2305 e1[0].prefix)
2306 self.assertEqual(
2307 '{http://ns.infrae.com/foo}bar',
2308 e1.tag)
2309 self.assertEqual(
2310 '{http://ns.infrae.com/foo}bar',
2311 e1[0].tag)
2312
2314 etree = self.etree
2315
2316 r = {None: 'http://ns.infrae.com/BAR'}
2317 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2318 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2319
2320 e1.append(e2)
2321
2322 self.assertEqual(
2323 None,
2324 e1.prefix)
2325 self.assertNotEqual(
2326 None,
2327 e2.prefix)
2328 self.assertEqual(
2329 '{http://ns.infrae.com/BAR}bar',
2330 e1.tag)
2331 self.assertEqual(
2332 '{http://ns.infrae.com/foo}bar',
2333 e2.tag)
2334
2336 ns_href = "http://a.b.c"
2337 one = self.etree.fromstring(
2338 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2339 baz = one[0][0]
2340
2341 two = self.etree.fromstring(
2342 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2343 two.append(baz)
2344 del one
2345
2346 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2347 self.assertEqual(
2348 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2349 self.etree.tostring(two))
2350
2360
2362 etree = self.etree
2363
2364 r = {None: 'http://ns.infrae.com/foo',
2365 'hoi': 'http://ns.infrae.com/hoi'}
2366 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2367 self.assertEqual(
2368 r,
2369 e.nsmap)
2370
2372 etree = self.etree
2373
2374 re = {None: 'http://ns.infrae.com/foo',
2375 'hoi': 'http://ns.infrae.com/hoi'}
2376 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2377
2378 rs = {None: 'http://ns.infrae.com/honk',
2379 'top': 'http://ns.infrae.com/top'}
2380 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2381
2382 r = re.copy()
2383 r.update(rs)
2384 self.assertEqual(re, e.nsmap)
2385 self.assertEqual(r, s.nsmap)
2386
2388 etree = self.etree
2389 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2390 self.assertEqual({'hha': None}, el.nsmap)
2391
2393 Element = self.etree.Element
2394 SubElement = self.etree.SubElement
2395
2396 a = Element('a')
2397 b = SubElement(a, 'b')
2398 c = SubElement(a, 'c')
2399 d = SubElement(b, 'd')
2400 e = SubElement(c, 'e')
2401 f = SubElement(c, 'f')
2402
2403 self.assertEqual(
2404 [a, b],
2405 list(a.getiterator('a', 'b')))
2406 self.assertEqual(
2407 [],
2408 list(a.getiterator('x', 'y')))
2409 self.assertEqual(
2410 [a, f],
2411 list(a.getiterator('f', 'a')))
2412 self.assertEqual(
2413 [c, e, f],
2414 list(c.getiterator('c', '*', 'a')))
2415 self.assertEqual(
2416 [],
2417 list(a.getiterator( (), () )))
2418
2420 Element = self.etree.Element
2421 SubElement = self.etree.SubElement
2422
2423 a = Element('a')
2424 b = SubElement(a, 'b')
2425 c = SubElement(a, 'c')
2426 d = SubElement(b, 'd')
2427 e = SubElement(c, 'e')
2428 f = SubElement(c, 'f')
2429
2430 self.assertEqual(
2431 [a, b],
2432 list(a.getiterator( ('a', 'b') )))
2433 self.assertEqual(
2434 [],
2435 list(a.getiterator( ('x', 'y') )))
2436 self.assertEqual(
2437 [a, f],
2438 list(a.getiterator( ('f', 'a') )))
2439 self.assertEqual(
2440 [c, e, f],
2441 list(c.getiterator( ('c', '*', 'a') )))
2442 self.assertEqual(
2443 [],
2444 list(a.getiterator( () )))
2445
2447 Element = self.etree.Element
2448 SubElement = self.etree.SubElement
2449
2450 a = Element('{a}a')
2451 b = SubElement(a, '{a}b')
2452 c = SubElement(a, '{a}c')
2453 d = SubElement(b, '{b}d')
2454 e = SubElement(c, '{a}e')
2455 f = SubElement(c, '{b}f')
2456 g = SubElement(c, 'g')
2457
2458 self.assertEqual(
2459 [a],
2460 list(a.getiterator('{a}a')))
2461 self.assertEqual(
2462 [],
2463 list(a.getiterator('{b}a')))
2464 self.assertEqual(
2465 [],
2466 list(a.getiterator('a')))
2467 self.assertEqual(
2468 [a,b,d,c,e,f,g],
2469 list(a.getiterator('*')))
2470 self.assertEqual(
2471 [f],
2472 list(c.getiterator('{b}*')))
2473 self.assertEqual(
2474 [d, f],
2475 list(a.getiterator('{b}*')))
2476 self.assertEqual(
2477 [g],
2478 list(a.getiterator('g')))
2479 self.assertEqual(
2480 [g],
2481 list(a.getiterator('{}g')))
2482 self.assertEqual(
2483 [g],
2484 list(a.getiterator('{}*')))
2485
2487 Element = self.etree.Element
2488 SubElement = self.etree.SubElement
2489
2490 a = Element('{a}a')
2491 b = SubElement(a, '{nsA}b')
2492 c = SubElement(b, '{nsB}b')
2493 d = SubElement(a, 'b')
2494 e = SubElement(a, '{nsA}e')
2495 f = SubElement(e, '{nsB}e')
2496 g = SubElement(e, 'e')
2497
2498 self.assertEqual(
2499 [b, c, d],
2500 list(a.getiterator('{*}b')))
2501 self.assertEqual(
2502 [e, f, g],
2503 list(a.getiterator('{*}e')))
2504 self.assertEqual(
2505 [a, b, c, d, e, f, g],
2506 list(a.getiterator('{*}*')))
2507
2532
2548
2565
2572
2579
2588
2590 XML = self.etree.XML
2591 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2592 self.assertEqual(len(root.findall(".//{X}b")), 2)
2593 self.assertEqual(len(root.findall(".//{X}*")), 2)
2594 self.assertEqual(len(root.findall(".//b")), 3)
2595
2597 XML = self.etree.XML
2598 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2599 nsmap = {'xx': 'X'}
2600 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2601 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2602 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2603 nsmap = {'xx': 'Y'}
2604 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2605 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2606 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2607
2609 XML = self.etree.XML
2610 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2611 nsmap = {'xx': 'X'}
2612 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2613 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2614 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2615 nsmap = {'xx': 'Y'}
2616 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2617 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2618 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2619
2626
2628 etree = self.etree
2629 e = etree.Element('foo')
2630 for i in range(10):
2631 etree.SubElement(e, 'a%s' % i)
2632 for i in range(10):
2633 self.assertEqual(
2634 i,
2635 e.index(e[i]))
2636 self.assertEqual(
2637 3, e.index(e[3], 3))
2638 self.assertRaises(
2639 ValueError, e.index, e[3], 4)
2640 self.assertRaises(
2641 ValueError, e.index, e[3], 0, 2)
2642 self.assertRaises(
2643 ValueError, e.index, e[8], 0, -3)
2644 self.assertRaises(
2645 ValueError, e.index, e[8], -5, -3)
2646 self.assertEqual(
2647 8, e.index(e[8], 0, -1))
2648 self.assertEqual(
2649 8, e.index(e[8], -12, -1))
2650 self.assertEqual(
2651 0, e.index(e[0], -12, -1))
2652
2654 etree = self.etree
2655 e = etree.Element('foo')
2656 for i in range(10):
2657 el = etree.SubElement(e, 'a%s' % i)
2658 el.text = "text%d" % i
2659 el.tail = "tail%d" % i
2660
2661 child0 = e[0]
2662 child1 = e[1]
2663 child2 = e[2]
2664
2665 e.replace(e[0], e[1])
2666 self.assertEqual(
2667 9, len(e))
2668 self.assertEqual(
2669 child1, e[0])
2670 self.assertEqual(
2671 child1.text, "text1")
2672 self.assertEqual(
2673 child1.tail, "tail1")
2674 self.assertEqual(
2675 child0.tail, "tail0")
2676 self.assertEqual(
2677 child2, e[1])
2678
2679 e.replace(e[-1], e[0])
2680 self.assertEqual(
2681 child1, e[-1])
2682 self.assertEqual(
2683 child1.text, "text1")
2684 self.assertEqual(
2685 child1.tail, "tail1")
2686 self.assertEqual(
2687 child2, e[0])
2688
2690 etree = self.etree
2691 e = etree.Element('foo')
2692 for i in range(10):
2693 etree.SubElement(e, 'a%s' % i)
2694
2695 new_element = etree.Element("test")
2696 new_element.text = "TESTTEXT"
2697 new_element.tail = "TESTTAIL"
2698 child1 = e[1]
2699 e.replace(e[0], new_element)
2700 self.assertEqual(
2701 new_element, e[0])
2702 self.assertEqual(
2703 "TESTTEXT",
2704 e[0].text)
2705 self.assertEqual(
2706 "TESTTAIL",
2707 e[0].tail)
2708 self.assertEqual(
2709 child1, e[1])
2710
2726
2744
2762
2780
2782 Element = self.etree.Element
2783 SubElement = self.etree.SubElement
2784 try:
2785 slice
2786 except NameError:
2787 print("slice() not found")
2788 return
2789
2790 a = Element('a')
2791 b = SubElement(a, 'b')
2792 c = SubElement(a, 'c')
2793 d = SubElement(a, 'd')
2794 e = SubElement(a, 'e')
2795
2796 x = Element('x')
2797 y = Element('y')
2798 z = Element('z')
2799
2800 self.assertRaises(
2801 ValueError,
2802 operator.setitem, a, slice(1,None,2), [x, y, z])
2803
2804 self.assertEqual(
2805 [b, c, d, e],
2806 list(a))
2807
2820
2828
2837
2847
2857
2863
2871
2877
2884
2890
2892 etree = self.etree
2893 xml_header = '<?xml version="1.0" encoding="ascii"?>'
2894 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2895 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2896 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
2897
2898 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2899
2900 tree = etree.parse(BytesIO(xml))
2901 docinfo = tree.docinfo
2902 self.assertEqual(docinfo.encoding, "ascii")
2903 self.assertEqual(docinfo.xml_version, "1.0")
2904 self.assertEqual(docinfo.public_id, pub_id)
2905 self.assertEqual(docinfo.system_url, sys_id)
2906 self.assertEqual(docinfo.root_name, 'html')
2907 self.assertEqual(docinfo.doctype, doctype_string)
2908
2924
2936
2948
2954
2956 etree = self.etree
2957 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2958 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2959 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
2960
2961 xml = _bytes('<!DOCTYPE root>\n<root/>')
2962 tree = etree.parse(BytesIO(xml))
2963 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
2964 etree.tostring(tree, doctype=doctype_string))
2965
2967 etree = self.etree
2968 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2969 self.assertEqual(root.base, "http://no/such/url")
2970 self.assertEqual(
2971 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2972 root.base = "https://secret/url"
2973 self.assertEqual(root.base, "https://secret/url")
2974 self.assertEqual(
2975 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2976 "https://secret/url")
2977
2979 etree = self.etree
2980 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2981 self.assertEqual(root.base, "http://no/such/url")
2982 self.assertEqual(
2983 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2984 root.set('{http://www.w3.org/XML/1998/namespace}base',
2985 "https://secret/url")
2986 self.assertEqual(root.base, "https://secret/url")
2987 self.assertEqual(
2988 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2989 "https://secret/url")
2990
2996
3001
3008
3022
3024 Element = self.etree.Element
3025
3026 a = Element('a')
3027 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3028 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3029
3030 self.assertRaises(ValueError, Element, 'ha\0ho')
3031
3033 Element = self.etree.Element
3034
3035 a = Element('a')
3036 self.assertRaises(ValueError, setattr, a, "text",
3037 _str('ha\0ho'))
3038 self.assertRaises(ValueError, setattr, a, "tail",
3039 _str('ha\0ho'))
3040
3041 self.assertRaises(ValueError, Element,
3042 _str('ha\0ho'))
3043
3045 Element = self.etree.Element
3046
3047 a = Element('a')
3048 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3049 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3050
3051 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3052 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3053
3054 self.assertRaises(ValueError, Element, 'ha\x07ho')
3055 self.assertRaises(ValueError, Element, 'ha\x02ho')
3056
3058 Element = self.etree.Element
3059
3060 a = Element('a')
3061 self.assertRaises(ValueError, setattr, a, "text",
3062 _str('ha\x07ho'))
3063 self.assertRaises(ValueError, setattr, a, "text",
3064 _str('ha\x02ho'))
3065
3066 self.assertRaises(ValueError, setattr, a, "tail",
3067 _str('ha\x07ho'))
3068 self.assertRaises(ValueError, setattr, a, "tail",
3069 _str('ha\x02ho'))
3070
3071 self.assertRaises(ValueError, Element,
3072 _str('ha\x07ho'))
3073 self.assertRaises(ValueError, Element,
3074 _str('ha\x02ho'))
3075
3077 Element = self.etree.Element
3078
3079 a = Element('a')
3080 self.assertRaises(ValueError, setattr, a, "text",
3081 _str('ha\u1234\x07ho'))
3082 self.assertRaises(ValueError, setattr, a, "text",
3083 _str('ha\u1234\x02ho'))
3084
3085 self.assertRaises(ValueError, setattr, a, "tail",
3086 _str('ha\u1234\x07ho'))
3087 self.assertRaises(ValueError, setattr, a, "tail",
3088 _str('ha\u1234\x02ho'))
3089
3090 self.assertRaises(ValueError, Element,
3091 _str('ha\u1234\x07ho'))
3092 self.assertRaises(ValueError, Element,
3093 _str('ha\u1234\x02ho'))
3094
3108
3113
3131
3151
3173
3175 tostring = self.etree.tostring
3176 XML = self.etree.XML
3177 ElementTree = self.etree.ElementTree
3178
3179 root = XML(_bytes("<root/>"))
3180
3181 tree = ElementTree(root)
3182 self.assertEqual(None, tree.docinfo.standalone)
3183
3184 result = tostring(root, xml_declaration=True, encoding="ASCII")
3185 self.assertEqual(result, _bytes(
3186 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3187
3188 result = tostring(root, xml_declaration=True, encoding="ASCII",
3189 standalone=True)
3190 self.assertEqual(result, _bytes(
3191 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3192
3193 tree = ElementTree(XML(result))
3194 self.assertEqual(True, tree.docinfo.standalone)
3195
3196 result = tostring(root, xml_declaration=True, encoding="ASCII",
3197 standalone=False)
3198 self.assertEqual(result, _bytes(
3199 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3200
3201 tree = ElementTree(XML(result))
3202 self.assertEqual(False, tree.docinfo.standalone)
3203
3223
3225 tostring = self.etree.tostring
3226 Element = self.etree.Element
3227 SubElement = self.etree.SubElement
3228
3229 a = Element('a')
3230 a.text = "A"
3231 a.tail = "tail"
3232 b = SubElement(a, 'b')
3233 b.text = "B"
3234 b.tail = _str("Søk på nettet")
3235 c = SubElement(a, 'c')
3236 c.text = "C"
3237
3238 result = tostring(a, method="text", encoding="UTF-16")
3239
3240 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3241 result)
3242
3244 tostring = self.etree.tostring
3245 Element = self.etree.Element
3246 SubElement = self.etree.SubElement
3247
3248 a = Element('a')
3249 a.text = _str('Søk på nettetA')
3250 a.tail = "tail"
3251 b = SubElement(a, 'b')
3252 b.text = "B"
3253 b.tail = _str('Søk på nettetB')
3254 c = SubElement(a, 'c')
3255 c.text = "C"
3256
3257 self.assertRaises(UnicodeEncodeError,
3258 tostring, a, method="text")
3259
3260 self.assertEqual(
3261 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3262 tostring(a, encoding="UTF-8", method="text"))
3263
3276
3292
3296
3311
3329
3342
3344 tostring = self.etree.tostring
3345 Element = self.etree.Element
3346 SubElement = self.etree.SubElement
3347
3348 a = Element('a')
3349 b = SubElement(a, 'b')
3350 c = SubElement(a, 'c')
3351 d = SubElement(c, 'd')
3352 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3353 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3354 self.assertEqual(_bytes('<b></b>'),
3355 canonicalize(tostring(b, encoding=_unicode)))
3356 self.assertEqual(_bytes('<c><d></d></c>'),
3357 canonicalize(tostring(c, encoding=_unicode)))
3358
3363
3378
3380 tostring = self.etree.tostring
3381 Element = self.etree.Element
3382 SubElement = self.etree.SubElement
3383
3384 a = Element('a')
3385 b = SubElement(a, 'b')
3386 c = SubElement(a, 'c')
3387
3388 result = tostring(a, encoding=_unicode)
3389 self.assertEqual(result, "<a><b/><c/></a>")
3390
3391 result = tostring(a, encoding=_unicode, pretty_print=False)
3392 self.assertEqual(result, "<a><b/><c/></a>")
3393
3394 result = tostring(a, encoding=_unicode, pretty_print=True)
3395 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3396
3408
3410 class SubEl(etree.ElementBase):
3411 pass
3412
3413 el1 = SubEl()
3414 el2 = SubEl()
3415 self.assertEqual('SubEl', el1.tag)
3416 self.assertEqual('SubEl', el2.tag)
3417 el1.other = el2
3418 el2.other = el1
3419
3420 del el1, el2
3421 gc.collect()
3422
3423
3424
3425
3426 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3437
3438
3441 filename = fileInTestDir('test_broken.xml')
3442 root = etree.XML(_bytes('''\
3443 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3444 <xi:include href="%s" parse="text"/>
3445 </doc>
3446 ''' % filename))
3447 old_text = root.text
3448 content = read_file(filename)
3449 old_tail = root[0].tail
3450
3451 self.include( etree.ElementTree(root) )
3452 self.assertEqual(old_text + content + old_tail,
3453 root.text)
3454
3466
3468 class res(etree.Resolver):
3469 include_text = read_file(fileInTestDir('test.xml'))
3470 called = {}
3471 def resolve(self, url, id, context):
3472 if url.endswith(".dtd"):
3473 self.called["dtd"] = True
3474 return self.resolve_filename(
3475 fileInTestDir('test.dtd'), context)
3476 elif url.endswith("test_xinclude.xml"):
3477 self.called["input"] = True
3478 return None
3479 else:
3480 self.called["include"] = True
3481 return self.resolve_string(self.include_text, context)
3482
3483 res_instance = res()
3484 parser = etree.XMLParser(load_dtd = True)
3485 parser.resolvers.add(res_instance)
3486
3487 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3488 parser = parser)
3489
3490 self.include(tree)
3491
3492 called = list(res_instance.called.items())
3493 called.sort()
3494 self.assertEqual(
3495 [("dtd", True), ("include", True), ("input", True)],
3496 called)
3497
3501
3502
3507
3508
3511 tree = self.parse(_bytes('<a><b/></a>'))
3512 f = BytesIO()
3513 tree.write_c14n(f)
3514 s = f.getvalue()
3515 self.assertEqual(_bytes('<a><b></b></a>'),
3516 s)
3517
3519 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3520 f = BytesIO()
3521 tree.write_c14n(f, compression=9)
3522 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3523 try:
3524 s = gzfile.read()
3525 finally:
3526 gzfile.close()
3527 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3528 s)
3529
3541
3557
3575
3587
3599
3601 tree = self.parse(_bytes(
3602 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3603 f = BytesIO()
3604 tree.write_c14n(f)
3605 s = f.getvalue()
3606 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3607 s)
3608 f = BytesIO()
3609 tree.write_c14n(f, exclusive=False)
3610 s = f.getvalue()
3611 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3612 s)
3613 f = BytesIO()
3614 tree.write_c14n(f, exclusive=True)
3615 s = f.getvalue()
3616 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3617 s)
3618
3619 f = BytesIO()
3620 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
3621 s = f.getvalue()
3622 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
3623 s)
3624
3626 tree = self.parse(_bytes(
3627 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3628 s = etree.tostring(tree, method='c14n')
3629 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3630 s)
3631 s = etree.tostring(tree, method='c14n', exclusive=False)
3632 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3633 s)
3634 s = etree.tostring(tree, method='c14n', exclusive=True)
3635 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3636 s)
3637
3638 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3639 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
3640 s)
3641
3643 tree = self.parse(_bytes(
3644 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3645 s = etree.tostring(tree.getroot(), method='c14n')
3646 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3647 s)
3648 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3649 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3650 s)
3651 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3652 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3653 s)
3654
3655 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3656 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3657 s)
3658 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3659 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3660 s)
3661
3662 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3663 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3664 s)
3665
3667 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
3668 tree = self.parse(_bytes(
3669 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3670
3671 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
3672 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3673 s)
3674
3675
3678 tree = self.parse(_bytes('<a><b/></a>'))
3679 f = BytesIO()
3680 tree.write(f)
3681 s = f.getvalue()
3682 self.assertEqual(_bytes('<a><b/></a>'),
3683 s)
3684
3686 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3687 f = BytesIO()
3688 tree.write(f, compression=9)
3689 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3690 try:
3691 s = gzfile.read()
3692 finally:
3693 gzfile.close()
3694 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3695 s)
3696
3698 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3699 f = BytesIO()
3700 tree.write(f, compression=0)
3701 s0 = f.getvalue()
3702
3703 f = BytesIO()
3704 tree.write(f)
3705 self.assertEqual(f.getvalue(), s0)
3706
3707 f = BytesIO()
3708 tree.write(f, compression=1)
3709 s = f.getvalue()
3710 self.assertTrue(len(s) <= len(s0))
3711 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3712 try:
3713 s1 = gzfile.read()
3714 finally:
3715 gzfile.close()
3716
3717 f = BytesIO()
3718 tree.write(f, compression=9)
3719 s = f.getvalue()
3720 self.assertTrue(len(s) <= len(s0))
3721 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3722 try:
3723 s9 = gzfile.read()
3724 finally:
3725 gzfile.close()
3726
3727 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3728 s0)
3729 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3730 s1)
3731 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3732 s9)
3733
3745
3761
3773
3786
3788 etree = etree
3789
3811
3813 """This can't really be tested as long as there isn't a way to
3814 reset the logging setup ...
3815 """
3816 parse = self.etree.parse
3817
3818 messages = []
3819 class Logger(self.etree.PyErrorLog):
3820 def log(self, entry, message, *args):
3821 messages.append(message)
3822
3823 self.etree.use_global_python_log(Logger())
3824 f = BytesIO('<a><b></c></b></a>')
3825 try:
3826 parse(f)
3827 except SyntaxError:
3828 pass
3829 f.close()
3830
3831 self.assertTrue([ message for message in messages
3832 if 'mismatch' in message ])
3833 self.assertTrue([ message for message in messages
3834 if ':PARSER:' in message])
3835 self.assertTrue([ message for message in messages
3836 if ':ERR_TAG_NAME_MISMATCH:' in message ])
3837 self.assertTrue([ message for message in messages
3838 if ':1:15:' in message ])
3839
3840
3842 etree = etree
3843
3847
3849 class Target(object):
3850 def start(self, tag, attrib):
3851 return 'start(%s)' % tag
3852 def end(self, tag):
3853 return 'end(%s)' % tag
3854 def close(self):
3855 return 'close()'
3856
3857 parser = self.etree.XMLPullParser(target=Target())
3858 events = parser.read_events()
3859
3860 parser.feed('<root><element>')
3861 self.assertFalse(list(events))
3862 self.assertFalse(list(events))
3863 parser.feed('</element><child>')
3864 self.assertEqual([('end', 'end(element)')], list(events))
3865 parser.feed('</child>')
3866 self.assertEqual([('end', 'end(child)')], list(events))
3867 parser.feed('</root>')
3868 self.assertEqual([('end', 'end(root)')], list(events))
3869 self.assertFalse(list(events))
3870 self.assertEqual('close()', parser.close())
3871
3873 class Target(object):
3874 def start(self, tag, attrib):
3875 return 'start(%s)' % tag
3876 def end(self, tag):
3877 return 'end(%s)' % tag
3878 def close(self):
3879 return 'close()'
3880
3881 parser = self.etree.XMLPullParser(
3882 ['start', 'end'], target=Target())
3883 events = parser.read_events()
3884
3885 parser.feed('<root><element>')
3886 self.assertEqual(
3887 [('start', 'start(root)'), ('start', 'start(element)')],
3888 list(events))
3889 self.assertFalse(list(events))
3890 parser.feed('</element><child>')
3891 self.assertEqual(
3892 [('end', 'end(element)'), ('start', 'start(child)')],
3893 list(events))
3894 parser.feed('</child>')
3895 self.assertEqual(
3896 [('end', 'end(child)')],
3897 list(events))
3898 parser.feed('</root>')
3899 self.assertEqual(
3900 [('end', 'end(root)')],
3901 list(events))
3902 self.assertFalse(list(events))
3903 self.assertEqual('close()', parser.close())
3904
3906 parser = self.etree.XMLPullParser(
3907 ['start', 'end'], target=etree.TreeBuilder())
3908 events = parser.read_events()
3909
3910 parser.feed('<root><element>')
3911 self.assert_event_tags(
3912 events, [('start', 'root'), ('start', 'element')])
3913 self.assertFalse(list(events))
3914 parser.feed('</element><child>')
3915 self.assert_event_tags(
3916 events, [('end', 'element'), ('start', 'child')])
3917 parser.feed('</child>')
3918 self.assert_event_tags(
3919 events, [('end', 'child')])
3920 parser.feed('</root>')
3921 self.assert_event_tags(
3922 events, [('end', 'root')])
3923 self.assertFalse(list(events))
3924 root = parser.close()
3925 self.assertEqual('root', root.tag)
3926
3928 class Target(etree.TreeBuilder):
3929 def end(self, tag):
3930 el = super(Target, self).end(tag)
3931 el.tag += '-huhu'
3932 return el
3933
3934 parser = self.etree.XMLPullParser(
3935 ['start', 'end'], target=Target())
3936 events = parser.read_events()
3937
3938 parser.feed('<root><element>')
3939 self.assert_event_tags(
3940 events, [('start', 'root'), ('start', 'element')])
3941 self.assertFalse(list(events))
3942 parser.feed('</element><child>')
3943 self.assert_event_tags(
3944 events, [('end', 'element-huhu'), ('start', 'child')])
3945 parser.feed('</child>')
3946 self.assert_event_tags(
3947 events, [('end', 'child-huhu')])
3948 parser.feed('</root>')
3949 self.assert_event_tags(
3950 events, [('end', 'root-huhu')])
3951 self.assertFalse(list(events))
3952 root = parser.close()
3953 self.assertEqual('root-huhu', root.tag)
3954
3955
3978
3979 if __name__ == '__main__':
3980 print('to test use test.py %s' % __file__)
3981