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
244
246 Element = self.etree.Element
247
248 keys = ["attr%d" % i for i in range(10)]
249 values = ["TEST-%d" % i for i in range(10)]
250 items = list(zip(keys, values))
251
252 root = Element("root")
253 for key, value in items:
254 root.set(key, value)
255 self.assertEqual(keys, root.attrib.keys())
256 self.assertEqual(values, root.attrib.values())
257
258 root2 = Element("root2", root.attrib,
259 attr_99='TOAST-1', attr_98='TOAST-2')
260 self.assertEqual(['attr_98', 'attr_99'] + keys,
261 root2.attrib.keys())
262 self.assertEqual(['TOAST-2', 'TOAST-1'] + values,
263 root2.attrib.values())
264
265 self.assertEqual(keys, root.attrib.keys())
266 self.assertEqual(values, root.attrib.values())
267
275
289
311
313 XML = self.etree.XML
314 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
315
316 root = XML(xml)
317 self.etree.strip_elements(root, 'a')
318 self.assertEqual(_bytes('<test><x></x></test>'),
319 self._writeElement(root))
320
321 root = XML(xml)
322 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
323 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'),
324 self._writeElement(root))
325
326 root = XML(xml)
327 self.etree.strip_elements(root, 'c')
328 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
329 self._writeElement(root))
330
332 XML = self.etree.XML
333 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>')
334
335 root = XML(xml)
336 self.etree.strip_elements(root, 'a')
337 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>'),
338 self._writeElement(root))
339
340 root = XML(xml)
341 self.etree.strip_elements(root, '{urn:a}b', 'c')
342 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>'),
343 self._writeElement(root))
344
345 root = XML(xml)
346 self.etree.strip_elements(root, '{urn:a}*', 'c')
347 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
348 self._writeElement(root))
349
350 root = XML(xml)
351 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
352 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
353 self._writeElement(root))
354
373
399
426
453
472
485
496
502
504 XML = self.etree.XML
505 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
506 self.assertEqual(root[0].target, "mypi")
507 self.assertEqual(root[0].get('my'), "1")
508 self.assertEqual(root[0].get('test'), " abc ")
509 self.assertEqual(root[0].get('quotes'), "' '")
510 self.assertEqual(root[0].get('only'), None)
511 self.assertEqual(root[0].get('names'), None)
512 self.assertEqual(root[0].get('nope'), None)
513
515 XML = self.etree.XML
516 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
517 self.assertEqual(root[0].target, "mypi")
518 self.assertEqual(root[0].attrib['my'], "1")
519 self.assertEqual(root[0].attrib['test'], " abc ")
520 self.assertEqual(root[0].attrib['quotes'], "' '")
521 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
522 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
523 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
524
526
527 ProcessingInstruction = self.etree.ProcessingInstruction
528
529 a = ProcessingInstruction("PI", "ONE")
530 b = copy.deepcopy(a)
531 b.text = "ANOTHER"
532
533 self.assertEqual('ONE', a.text)
534 self.assertEqual('ANOTHER', b.text)
535
551
566
576
588
607
612
625
636
637 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
638 events = list(iterparse(f, events=('end', 'comment')))
639 root = events[-1][1]
640 self.assertEqual(6, len(events))
641 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'],
642 [ name(*item) for item in events ])
643 self.assertEqual(
644 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
645 tostring(root))
646
658
659 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
660 events = list(iterparse(f, events=('end', 'pi')))
661 root = events[-2][1]
662 self.assertEqual(8, len(events))
663 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
664 ('pid','d'), 'a', ('pie','e')],
665 [ name(*item) for item in events ])
666 self.assertEqual(
667 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
668 tostring(ElementTree(root)))
669
684
690
692 iterparse = self.etree.iterparse
693 f = BytesIO('<a><b><c/></a>')
694 it = iterparse(f, events=('start', 'end'), recover=True)
695 events = [(ev, el.tag) for ev, el in it]
696 root = it.root
697 self.assertTrue(root is not None)
698
699 self.assertEqual(1, events.count(('start', 'a')))
700 self.assertEqual(1, events.count(('end', 'a')))
701
702 self.assertEqual(1, events.count(('start', 'b')))
703 self.assertEqual(1, events.count(('end', 'b')))
704
705 self.assertEqual(1, events.count(('start', 'c')))
706 self.assertEqual(1, events.count(('end', 'c')))
707
709 iterparse = self.etree.iterparse
710 f = BytesIO('<a><b><c/></d><b><c/></a></b>')
711 it = iterparse(f, events=('start', 'end'), recover=True)
712 events = [(ev, el.tag) for ev, el in it]
713 root = it.root
714 self.assertTrue(root is not None)
715
716 self.assertEqual(1, events.count(('start', 'a')))
717 self.assertEqual(1, events.count(('end', 'a')))
718
719 self.assertEqual(2, events.count(('start', 'b')))
720 self.assertEqual(2, events.count(('end', 'b')))
721
722 self.assertEqual(2, events.count(('start', 'c')))
723 self.assertEqual(2, events.count(('end', 'c')))
724
726 iterparse = self.etree.iterparse
727 f = BytesIO("""
728 <a> \n \n <b> b test </b> \n
729
730 \n\t <c> \n </c> </a> \n """)
731 iterator = iterparse(f, remove_blank_text=True)
732 text = [ (element.text, element.tail)
733 for event, element in iterator ]
734 self.assertEqual(
735 [(" b test ", None), (" \n ", None), (None, None)],
736 text)
737
739 iterparse = self.etree.iterparse
740 f = BytesIO('<a><b><d/></b><c/></a>')
741
742 iterator = iterparse(f, tag="b", events=('start', 'end'))
743 events = list(iterator)
744 root = iterator.root
745 self.assertEqual(
746 [('start', root[0]), ('end', root[0])],
747 events)
748
750 iterparse = self.etree.iterparse
751 f = BytesIO('<a><b><d/></b><c/></a>')
752
753 iterator = iterparse(f, tag="*", events=('start', 'end'))
754 events = list(iterator)
755 self.assertEqual(
756 8,
757 len(events))
758
760 iterparse = self.etree.iterparse
761 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
762
763 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
764 events = list(iterator)
765 root = iterator.root
766 self.assertEqual(
767 [('start', root[0]), ('end', root[0])],
768 events)
769
771 iterparse = self.etree.iterparse
772 f = BytesIO('<a><b><d/></b><c/></a>')
773 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
774 events = list(iterator)
775 root = iterator.root
776 self.assertEqual(
777 [('start', root[0]), ('end', root[0])],
778 events)
779
780 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
781 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
782 events = list(iterator)
783 root = iterator.root
784 self.assertEqual([], events)
785
787 iterparse = self.etree.iterparse
788 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
789 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
790 events = list(iterator)
791 self.assertEqual(8, len(events))
792
794 iterparse = self.etree.iterparse
795 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
796 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
797 events = list(iterator)
798 self.assertEqual([], events)
799
800 f = BytesIO('<a><b><d/></b><c/></a>')
801 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
802 events = list(iterator)
803 self.assertEqual(8, len(events))
804
806 text = _str('Søk på nettet')
807 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
808 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
809 ).encode('iso-8859-1')
810
811 self.assertRaises(self.etree.ParseError,
812 list, self.etree.iterparse(BytesIO(xml_latin1)))
813
815 text = _str('Søk på nettet', encoding="UTF-8")
816 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
817 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
818 ).encode('iso-8859-1')
819
820 iterator = self.etree.iterparse(BytesIO(xml_latin1),
821 encoding="iso-8859-1")
822 self.assertEqual(1, len(list(iterator)))
823
824 a = iterator.root
825 self.assertEqual(a.text, text)
826
828 tostring = self.etree.tostring
829 f = BytesIO('<root><![CDATA[test]]></root>')
830 context = self.etree.iterparse(f, strip_cdata=False)
831 content = [ el.text for event,el in context ]
832
833 self.assertEqual(['test'], content)
834 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
835 tostring(context.root))
836
840
845
864
865
866
877 def end(self, tag):
878 events.append("end")
879 assertEqual("TAG", tag)
880 def close(self):
881 return "DONE"
882
883 parser = self.etree.XMLParser(target=Target())
884 tree = self.etree.ElementTree()
885
886 self.assertRaises(TypeError,
887 tree.parse, BytesIO("<TAG/>"), parser=parser)
888 self.assertEqual(["start", "end"], events)
889
891
892 events = []
893 class Target(object):
894 def start(self, tag, attrib):
895 events.append("start-" + tag)
896 def end(self, tag):
897 events.append("end-" + tag)
898 if tag == 'a':
899 raise ValueError("dead and gone")
900 def data(self, data):
901 events.append("data-" + data)
902 def close(self):
903 events.append("close")
904 return "DONE"
905
906 parser = self.etree.XMLParser(target=Target())
907
908 try:
909 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
910 done = parser.close()
911 self.fail("error expected, but parsing succeeded")
912 except ValueError:
913 done = 'value error received as expected'
914
915 self.assertEqual(["start-root", "data-A", "start-a",
916 "data-ca", "end-a", "close"],
917 events)
918
920
921 events = []
922 class Target(object):
923 def start(self, tag, attrib):
924 events.append("start-" + tag)
925 def end(self, tag):
926 events.append("end-" + tag)
927 if tag == 'a':
928 raise ValueError("dead and gone")
929 def data(self, data):
930 events.append("data-" + data)
931 def close(self):
932 events.append("close")
933 return "DONE"
934
935 parser = self.etree.XMLParser(target=Target())
936
937 try:
938 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
939 parser=parser)
940 self.fail("error expected, but parsing succeeded")
941 except ValueError:
942 done = 'value error received as expected'
943
944 self.assertEqual(["start-root", "data-A", "start-a",
945 "data-ca", "end-a", "close"],
946 events)
947
953 def end(self, tag):
954 events.append("end-" + tag)
955 def data(self, data):
956 events.append("data-" + data)
957 def comment(self, text):
958 events.append("comment-" + text)
959 def close(self):
960 return "DONE"
961
962 parser = self.etree.XMLParser(target=Target())
963
964 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
965 done = parser.close()
966
967 self.assertEqual("DONE", done)
968 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
969 "start-sub", "end-sub", "comment-c", "data-B",
970 "end-root", "comment-d"],
971 events)
972
974 events = []
975 class Target(object):
976 def start(self, tag, attrib):
977 events.append("start-" + tag)
978 def end(self, tag):
979 events.append("end-" + tag)
980 def data(self, data):
981 events.append("data-" + data)
982 def pi(self, target, data):
983 events.append("pi-" + target + "-" + data)
984 def close(self):
985 return "DONE"
986
987 parser = self.etree.XMLParser(target=Target())
988
989 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
990 done = parser.close()
991
992 self.assertEqual("DONE", done)
993 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b",
994 "data-B", "end-root", "pi-test-c"],
995 events)
996
998 events = []
999 class Target(object):
1000 def start(self, tag, attrib):
1001 events.append("start-" + tag)
1002 def end(self, tag):
1003 events.append("end-" + tag)
1004 def data(self, data):
1005 events.append("data-" + data)
1006 def close(self):
1007 return "DONE"
1008
1009 parser = self.etree.XMLParser(target=Target(),
1010 strip_cdata=False)
1011
1012 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
1013 done = parser.close()
1014
1015 self.assertEqual("DONE", done)
1016 self.assertEqual(["start-root", "data-A", "start-a",
1017 "data-ca", "end-a", "data-B", "end-root"],
1018 events)
1019
1021 events = []
1022 class Target(object):
1023 def start(self, tag, attrib):
1024 events.append("start-" + tag)
1025 def end(self, tag):
1026 events.append("end-" + tag)
1027 def data(self, data):
1028 events.append("data-" + data)
1029 def close(self):
1030 events.append("close")
1031 return "DONE"
1032
1033 parser = self.etree.XMLParser(target=Target(),
1034 recover=True)
1035
1036 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
1037 done = parser.close()
1038
1039 self.assertEqual("DONE", done)
1040 self.assertEqual(["start-root", "data-A", "start-a",
1041 "data-ca", "end-a", "data-B",
1042 "end-root", "close"],
1043 events)
1044
1054
1064
1073
1083
1085 iterwalk = self.etree.iterwalk
1086 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1087
1088 iterator = iterwalk(root, events=('start','end'))
1089 events = list(iterator)
1090 self.assertEqual(
1091 [('start', root), ('start', root[0]), ('end', root[0]),
1092 ('start', root[1]), ('end', root[1]), ('end', root)],
1093 events)
1094
1105
1107 iterwalk = self.etree.iterwalk
1108 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1109
1110 attr_name = '{testns}bla'
1111 events = []
1112 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1113 for event, elem in iterator:
1114 events.append(event)
1115 if event == 'start':
1116 if elem.tag != '{ns1}a':
1117 elem.set(attr_name, 'value')
1118
1119 self.assertEqual(
1120 ['start-ns', 'start', 'start', 'start-ns', 'start',
1121 'end', 'end-ns', 'end', 'end', 'end-ns'],
1122 events)
1123
1124 self.assertEqual(
1125 None,
1126 root.get(attr_name))
1127 self.assertEqual(
1128 'value',
1129 root[0].get(attr_name))
1130
1141
1143 parse = self.etree.parse
1144 parser = self.etree.XMLParser(dtd_validation=True)
1145 assertEqual = self.assertEqual
1146 test_url = _str("__nosuch.dtd")
1147
1148 class MyResolver(self.etree.Resolver):
1149 def resolve(self, url, id, context):
1150 assertEqual(url, test_url)
1151 return self.resolve_string(
1152 _str('''<!ENTITY myentity "%s">
1153 <!ELEMENT doc ANY>''') % url, context)
1154
1155 parser.resolvers.add(MyResolver())
1156
1157 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1158 tree = parse(StringIO(xml), parser)
1159 root = tree.getroot()
1160 self.assertEqual(root.text, test_url)
1161
1163 parse = self.etree.parse
1164 parser = self.etree.XMLParser(dtd_validation=True)
1165 assertEqual = self.assertEqual
1166 test_url = _str("__nosuch.dtd")
1167
1168 class MyResolver(self.etree.Resolver):
1169 def resolve(self, url, id, context):
1170 assertEqual(url, test_url)
1171 return self.resolve_string(
1172 (_str('''<!ENTITY myentity "%s">
1173 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1174 context)
1175
1176 parser.resolvers.add(MyResolver())
1177
1178 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1179 tree = parse(StringIO(xml), parser)
1180 root = tree.getroot()
1181 self.assertEqual(root.text, test_url)
1182
1184 parse = self.etree.parse
1185 parser = self.etree.XMLParser(dtd_validation=True)
1186 assertEqual = self.assertEqual
1187 test_url = _str("__nosuch.dtd")
1188
1189 class MyResolver(self.etree.Resolver):
1190 def resolve(self, url, id, context):
1191 assertEqual(url, test_url)
1192 return self.resolve_file(
1193 SillyFileLike(
1194 _str('''<!ENTITY myentity "%s">
1195 <!ELEMENT doc ANY>''') % url), context)
1196
1197 parser.resolvers.add(MyResolver())
1198
1199 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1200 tree = parse(StringIO(xml), parser)
1201 root = tree.getroot()
1202 self.assertEqual(root.text, test_url)
1203
1205 parse = self.etree.parse
1206 parser = self.etree.XMLParser(attribute_defaults=True)
1207 assertEqual = self.assertEqual
1208 test_url = _str("__nosuch.dtd")
1209
1210 class MyResolver(self.etree.Resolver):
1211 def resolve(self, url, id, context):
1212 assertEqual(url, test_url)
1213 return self.resolve_filename(
1214 fileInTestDir('test.dtd'), context)
1215
1216 parser.resolvers.add(MyResolver())
1217
1218 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1219 tree = parse(StringIO(xml), parser)
1220 root = tree.getroot()
1221 self.assertEqual(
1222 root.attrib, {'default': 'valueA'})
1223 self.assertEqual(
1224 root[0].attrib, {'default': 'valueB'})
1225
1237
1238 parser.resolvers.add(MyResolver())
1239
1240 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1241 tree = parse(StringIO(xml), parser,
1242 base_url=fileInTestDir('__test.xml'))
1243 root = tree.getroot()
1244 self.assertEqual(
1245 root.attrib, {'default': 'valueA'})
1246 self.assertEqual(
1247 root[0].attrib, {'default': 'valueB'})
1248
1250 parse = self.etree.parse
1251 parser = self.etree.XMLParser(attribute_defaults=True)
1252 assertEqual = self.assertEqual
1253 test_url = _str("__nosuch.dtd")
1254
1255 class MyResolver(self.etree.Resolver):
1256 def resolve(self, url, id, context):
1257 assertEqual(url, test_url)
1258 return self.resolve_file(
1259 open(fileInTestDir('test.dtd'), 'rb'), context)
1260
1261 parser.resolvers.add(MyResolver())
1262
1263 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1264 tree = parse(StringIO(xml), parser)
1265 root = tree.getroot()
1266 self.assertEqual(
1267 root.attrib, {'default': 'valueA'})
1268 self.assertEqual(
1269 root[0].attrib, {'default': 'valueB'})
1270
1272 parse = self.etree.parse
1273 parser = self.etree.XMLParser(load_dtd=True)
1274 assertEqual = self.assertEqual
1275 test_url = _str("__nosuch.dtd")
1276
1277 class check(object):
1278 resolved = False
1279
1280 class MyResolver(self.etree.Resolver):
1281 def resolve(self, url, id, context):
1282 assertEqual(url, test_url)
1283 check.resolved = True
1284 return self.resolve_empty(context)
1285
1286 parser.resolvers.add(MyResolver())
1287
1288 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1289 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1290 self.assertTrue(check.resolved)
1291
1298
1299 class MyResolver(self.etree.Resolver):
1300 def resolve(self, url, id, context):
1301 raise _LocalException
1302
1303 parser.resolvers.add(MyResolver())
1304
1305 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1306 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1307
1308 if etree.LIBXML_VERSION > (2,6,20):
1325
1327 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1328 <root>
1329 <child1/>
1330 <child2/>
1331 <child3> </child3>
1332 </root>''')
1333
1334 parser = self.etree.XMLParser(resolve_entities=False)
1335 root = etree.fromstring(xml, parser)
1336 self.assertEqual([ el.tag for el in root ],
1337 ['child1', 'child2', 'child3'])
1338
1339 root[0] = root[-1]
1340 self.assertEqual([ el.tag for el in root ],
1341 ['child3', 'child2'])
1342 self.assertEqual(root[0][0].text, ' ')
1343 self.assertEqual(root[0][0].name, 'nbsp')
1344
1360
1367
1369 Entity = self.etree.Entity
1370 self.assertRaises(ValueError, Entity, 'a b c')
1371 self.assertRaises(ValueError, Entity, 'a,b')
1372 self.assertRaises(ValueError, Entity, 'a\0b')
1373 self.assertRaises(ValueError, Entity, '#abc')
1374 self.assertRaises(ValueError, Entity, '#xxyz')
1375
1388
1401
1403 CDATA = self.etree.CDATA
1404 Element = self.etree.Element
1405
1406 root = Element("root")
1407 cdata = CDATA('test')
1408
1409 self.assertRaises(TypeError,
1410 setattr, root, 'tail', cdata)
1411 self.assertRaises(TypeError,
1412 root.set, 'attr', cdata)
1413 self.assertRaises(TypeError,
1414 operator.setitem, root.attrib, 'attr', cdata)
1415
1424
1433
1434
1444
1453
1455 Element = self.etree.Element
1456 SubElement = self.etree.SubElement
1457 root = Element('root')
1458 self.assertRaises(ValueError, root.append, root)
1459 child = SubElement(root, 'child')
1460 self.assertRaises(ValueError, child.append, root)
1461 child2 = SubElement(child, 'child2')
1462 self.assertRaises(ValueError, child2.append, root)
1463 self.assertRaises(ValueError, child2.append, child)
1464 self.assertEqual('child2', root[0][0].tag)
1465
1478
1491
1507
1523
1529
1544
1557
1572
1585
1600
1613
1628
1641
1642
1650
1651
1661
1662
1677
1678
1688
1689
1700
1701
1703 self.assertRaises(TypeError, self.etree.dump, None)
1704
1717
1730
1751
1760
1769
1778
1787
1796
1798 XML = self.etree.XML
1799
1800 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1801 result = []
1802 for el in root.iterchildren(tag=['two', 'three']):
1803 result.append(el.text)
1804 self.assertEqual(['Two', 'Bla', None], result)
1805
1807 XML = self.etree.XML
1808
1809 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1810 result = []
1811 for el in root.iterchildren('two', 'three'):
1812 result.append(el.text)
1813 self.assertEqual(['Two', 'Bla', None], result)
1814
1823
1844
1866
1868 Element = self.etree.Element
1869 SubElement = self.etree.SubElement
1870
1871 a = Element('a')
1872 b = SubElement(a, 'b')
1873 c = SubElement(a, 'c')
1874 d = SubElement(b, 'd')
1875 self.assertEqual(
1876 [b, a],
1877 list(d.iterancestors(tag=('a', 'b'))))
1878 self.assertEqual(
1879 [b, a],
1880 list(d.iterancestors('a', 'b')))
1881
1882 self.assertEqual(
1883 [],
1884 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
1885 self.assertEqual(
1886 [],
1887 list(d.iterancestors('w', 'x', 'y', 'z')))
1888
1889 self.assertEqual(
1890 [],
1891 list(d.iterancestors(tag=('d', 'x'))))
1892 self.assertEqual(
1893 [],
1894 list(d.iterancestors('d', 'x')))
1895
1896 self.assertEqual(
1897 [b, a],
1898 list(d.iterancestors(tag=('b', '*'))))
1899 self.assertEqual(
1900 [b, a],
1901 list(d.iterancestors('b', '*')))
1902
1903 self.assertEqual(
1904 [b],
1905 list(d.iterancestors(tag=('b', 'c'))))
1906 self.assertEqual(
1907 [b],
1908 list(d.iterancestors('b', 'c')))
1909
1926
1928 Element = self.etree.Element
1929 SubElement = self.etree.SubElement
1930
1931 a = Element('a')
1932 b = SubElement(a, 'b')
1933 c = SubElement(a, 'c')
1934 d = SubElement(b, 'd')
1935 e = SubElement(c, 'e')
1936
1937 self.assertEqual(
1938 [],
1939 list(a.iterdescendants('a')))
1940 self.assertEqual(
1941 [],
1942 list(a.iterdescendants(tag='a')))
1943
1944 a2 = SubElement(e, 'a')
1945 self.assertEqual(
1946 [a2],
1947 list(a.iterdescendants('a')))
1948
1949 self.assertEqual(
1950 [a2],
1951 list(c.iterdescendants('a')))
1952 self.assertEqual(
1953 [a2],
1954 list(c.iterdescendants(tag='a')))
1955
1957 Element = self.etree.Element
1958 SubElement = self.etree.SubElement
1959
1960 a = Element('a')
1961 b = SubElement(a, 'b')
1962 c = SubElement(a, 'c')
1963 d = SubElement(b, 'd')
1964 e = SubElement(c, 'e')
1965
1966 self.assertEqual(
1967 [b, e],
1968 list(a.iterdescendants(tag=('a', 'b', 'e'))))
1969 self.assertEqual(
1970 [b, e],
1971 list(a.iterdescendants('a', 'b', 'e')))
1972
1973 a2 = SubElement(e, 'a')
1974 self.assertEqual(
1975 [b, a2],
1976 list(a.iterdescendants(tag=('a', 'b'))))
1977 self.assertEqual(
1978 [b, a2],
1979 list(a.iterdescendants('a', 'b')))
1980
1981 self.assertEqual(
1982 [],
1983 list(c.iterdescendants(tag=('x', 'y', 'z'))))
1984 self.assertEqual(
1985 [],
1986 list(c.iterdescendants('x', 'y', 'z')))
1987
1988 self.assertEqual(
1989 [b, d, c, e, a2],
1990 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
1991 self.assertEqual(
1992 [b, d, c, e, a2],
1993 list(a.iterdescendants('x', 'y', 'z', '*')))
1994
2012
2029
2047
2071
2073 Element = self.etree.Element
2074 SubElement = self.etree.SubElement
2075
2076 a = Element('a')
2077 b = SubElement(a, 'b')
2078 c = SubElement(a, 'c')
2079 d = SubElement(b, 'd')
2080 self.assertEqual(
2081 [],
2082 list(a.itersiblings(tag='XXX')))
2083 self.assertEqual(
2084 [c],
2085 list(b.itersiblings(tag='c')))
2086 self.assertEqual(
2087 [c],
2088 list(b.itersiblings(tag='*')))
2089 self.assertEqual(
2090 [b],
2091 list(c.itersiblings(preceding=True, tag='b')))
2092 self.assertEqual(
2093 [],
2094 list(c.itersiblings(preceding=True, tag='c')))
2095
2097 Element = self.etree.Element
2098 SubElement = self.etree.SubElement
2099
2100 a = Element('a')
2101 b = SubElement(a, 'b')
2102 c = SubElement(a, 'c')
2103 d = SubElement(b, 'd')
2104 e = SubElement(a, 'e')
2105 self.assertEqual(
2106 [],
2107 list(a.itersiblings(tag=('XXX', 'YYY'))))
2108 self.assertEqual(
2109 [c, e],
2110 list(b.itersiblings(tag=('c', 'd', 'e'))))
2111 self.assertEqual(
2112 [b],
2113 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2114 self.assertEqual(
2115 [c, b],
2116 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2117
2119 parseid = self.etree.parseid
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 tree, dic = parseid(BytesIO(xml_text))
2139 root = tree.getroot()
2140 root2 = XML(xml_text)
2141 self.assertEqual(self._writeElement(root),
2142 self._writeElement(root2))
2143 expected = {
2144 "chapter1" : root[0],
2145 "xmlid" : root[3],
2146 "warn1" : root[4]
2147 }
2148 self.assertTrue("chapter1" in dic)
2149 self.assertTrue("warn1" in dic)
2150 self.assertTrue("xmlid" in dic)
2151 self._checkIDDict(dic, expected)
2152
2154 XMLDTDID = self.etree.XMLDTDID
2155 XML = self.etree.XML
2156 xml_text = _bytes('''
2157 <!DOCTYPE document [
2158 <!ELEMENT document (h1,p)*>
2159 <!ELEMENT h1 (#PCDATA)>
2160 <!ATTLIST h1 myid ID #REQUIRED>
2161 <!ELEMENT p (#PCDATA)>
2162 <!ATTLIST p someid ID #REQUIRED>
2163 ]>
2164 <document>
2165 <h1 myid="chapter1">...</h1>
2166 <p id="note1" class="note">...</p>
2167 <p>Regular paragraph.</p>
2168 <p xml:id="xmlid">XML:ID paragraph.</p>
2169 <p someid="warn1" class="warning">...</p>
2170 </document>
2171 ''')
2172
2173 root, dic = XMLDTDID(xml_text)
2174 root2 = XML(xml_text)
2175 self.assertEqual(self._writeElement(root),
2176 self._writeElement(root2))
2177 expected = {
2178 "chapter1" : root[0],
2179 "xmlid" : root[3],
2180 "warn1" : root[4]
2181 }
2182 self.assertTrue("chapter1" in dic)
2183 self.assertTrue("warn1" in dic)
2184 self.assertTrue("xmlid" in dic)
2185 self._checkIDDict(dic, expected)
2186
2188 XMLDTDID = self.etree.XMLDTDID
2189 XML = self.etree.XML
2190 xml_text = _bytes('''
2191 <document>
2192 <h1 myid="chapter1">...</h1>
2193 <p id="note1" class="note">...</p>
2194 <p>Regular paragraph.</p>
2195 <p someid="warn1" class="warning">...</p>
2196 </document>
2197 ''')
2198
2199 root, dic = XMLDTDID(xml_text)
2200 root2 = XML(xml_text)
2201 self.assertEqual(self._writeElement(root),
2202 self._writeElement(root2))
2203 expected = {}
2204 self._checkIDDict(dic, expected)
2205
2207 self.assertEqual(len(dic),
2208 len(expected))
2209 self.assertEqual(sorted(dic.items()),
2210 sorted(expected.items()))
2211 if sys.version_info < (3,):
2212 self.assertEqual(sorted(dic.iteritems()),
2213 sorted(expected.iteritems()))
2214 self.assertEqual(sorted(dic.keys()),
2215 sorted(expected.keys()))
2216 if sys.version_info < (3,):
2217 self.assertEqual(sorted(dic.iterkeys()),
2218 sorted(expected.iterkeys()))
2219 if sys.version_info < (3,):
2220 self.assertEqual(sorted(dic.values()),
2221 sorted(expected.values()))
2222 self.assertEqual(sorted(dic.itervalues()),
2223 sorted(expected.itervalues()))
2224
2226 etree = self.etree
2227
2228 r = {'foo': 'http://ns.infrae.com/foo'}
2229 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2230 self.assertEqual(
2231 'foo',
2232 e.prefix)
2233 self.assertEqual(
2234 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2235 self._writeElement(e))
2236
2238 etree = self.etree
2239
2240 r = {None: 'http://ns.infrae.com/foo'}
2241 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2242 self.assertEqual(
2243 None,
2244 e.prefix)
2245 self.assertEqual(
2246 '{http://ns.infrae.com/foo}bar',
2247 e.tag)
2248 self.assertEqual(
2249 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2250 self._writeElement(e))
2251
2253 etree = self.etree
2254
2255 r = {None: 'http://ns.infrae.com/foo',
2256 'hoi': 'http://ns.infrae.com/hoi'}
2257 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2258 e.set('{http://ns.infrae.com/hoi}test', 'value')
2259 self.assertEqual(
2260 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2261 self._writeElement(e))
2262
2264 etree = self.etree
2265
2266 root = etree.Element('{http://test/ns}root',
2267 nsmap={None: 'http://test/ns'})
2268 sub = etree.Element('{http://test/ns}sub',
2269 nsmap={'test': 'http://test/ns'})
2270
2271 sub.attrib['{http://test/ns}attr'] = 'value'
2272 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2273 self.assertEqual(
2274 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2275 etree.tostring(sub))
2276
2277 root.append(sub)
2278 self.assertEqual(
2279 _bytes('<root xmlns="http://test/ns">'
2280 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2281 '</root>'),
2282 etree.tostring(root))
2283
2285 etree = self.etree
2286
2287 root = etree.Element('root')
2288 sub = etree.Element('{http://test/ns}sub',
2289 nsmap={'test': 'http://test/ns'})
2290
2291 sub.attrib['{http://test/ns}attr'] = 'value'
2292 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2293 self.assertEqual(
2294 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2295 etree.tostring(sub))
2296
2297 root.append(sub)
2298 self.assertEqual(
2299 _bytes('<root>'
2300 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2301 '</root>'),
2302 etree.tostring(root))
2303
2305 etree = self.etree
2306
2307 root = etree.Element('root')
2308 sub = etree.Element('{http://test/ns}sub',
2309 nsmap={None: 'http://test/ns'})
2310
2311 sub.attrib['{http://test/ns}attr'] = 'value'
2312 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2313 self.assertEqual(
2314 _bytes('<sub xmlns="http://test/ns" '
2315 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2316 etree.tostring(sub))
2317
2318 root.append(sub)
2319 self.assertEqual(
2320 _bytes('<root>'
2321 '<sub xmlns="http://test/ns"'
2322 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2323 '</root>'),
2324 etree.tostring(root))
2325
2327 etree = self.etree
2328
2329 root = etree.Element('{http://test/ns}root',
2330 nsmap={'test': 'http://test/ns',
2331 None: 'http://test/ns'})
2332 sub = etree.Element('{http://test/ns}sub',
2333 nsmap={None: 'http://test/ns'})
2334
2335 sub.attrib['{http://test/ns}attr'] = 'value'
2336 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2337 self.assertEqual(
2338 _bytes('<sub xmlns="http://test/ns" '
2339 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2340 etree.tostring(sub))
2341
2342 root.append(sub)
2343 self.assertEqual(
2344 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2345 '<test:sub test:attr="value"/>'
2346 '</test:root>'),
2347 etree.tostring(root))
2348
2350 etree = self.etree
2351 r = {None: 'http://ns.infrae.com/foo',
2352 'hoi': 'http://ns.infrae.com/hoi'}
2353 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2354 tree = etree.ElementTree(element=e)
2355 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2356 self.assertEqual(
2357 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2358 self._writeElement(e))
2359
2361 etree = self.etree
2362
2363 r = {None: 'http://ns.infrae.com/foo'}
2364 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2365 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2366
2367 e1.append(e2)
2368
2369 self.assertEqual(
2370 None,
2371 e1.prefix)
2372 self.assertEqual(
2373 None,
2374 e1[0].prefix)
2375 self.assertEqual(
2376 '{http://ns.infrae.com/foo}bar',
2377 e1.tag)
2378 self.assertEqual(
2379 '{http://ns.infrae.com/foo}bar',
2380 e1[0].tag)
2381
2383 etree = self.etree
2384
2385 r = {None: 'http://ns.infrae.com/BAR'}
2386 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2387 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2388
2389 e1.append(e2)
2390
2391 self.assertEqual(
2392 None,
2393 e1.prefix)
2394 self.assertNotEqual(
2395 None,
2396 e2.prefix)
2397 self.assertEqual(
2398 '{http://ns.infrae.com/BAR}bar',
2399 e1.tag)
2400 self.assertEqual(
2401 '{http://ns.infrae.com/foo}bar',
2402 e2.tag)
2403
2405 ns_href = "http://a.b.c"
2406 one = self.etree.fromstring(
2407 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2408 baz = one[0][0]
2409
2410 two = self.etree.fromstring(
2411 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2412 two.append(baz)
2413 del one
2414
2415 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2416 self.assertEqual(
2417 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2418 self.etree.tostring(two))
2419
2429
2431 etree = self.etree
2432
2433 r = {None: 'http://ns.infrae.com/foo',
2434 'hoi': 'http://ns.infrae.com/hoi'}
2435 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2436 self.assertEqual(
2437 r,
2438 e.nsmap)
2439
2441 etree = self.etree
2442
2443 re = {None: 'http://ns.infrae.com/foo',
2444 'hoi': 'http://ns.infrae.com/hoi'}
2445 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2446
2447 rs = {None: 'http://ns.infrae.com/honk',
2448 'top': 'http://ns.infrae.com/top'}
2449 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2450
2451 r = re.copy()
2452 r.update(rs)
2453 self.assertEqual(re, e.nsmap)
2454 self.assertEqual(r, s.nsmap)
2455
2457 etree = self.etree
2458 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2459 self.assertEqual({'hha': None}, el.nsmap)
2460
2462 Element = self.etree.Element
2463 SubElement = self.etree.SubElement
2464
2465 a = Element('a')
2466 b = SubElement(a, 'b')
2467 c = SubElement(a, 'c')
2468 d = SubElement(b, 'd')
2469 e = SubElement(c, 'e')
2470 f = SubElement(c, 'f')
2471
2472 self.assertEqual(
2473 [a, b],
2474 list(a.getiterator('a', 'b')))
2475 self.assertEqual(
2476 [],
2477 list(a.getiterator('x', 'y')))
2478 self.assertEqual(
2479 [a, f],
2480 list(a.getiterator('f', 'a')))
2481 self.assertEqual(
2482 [c, e, f],
2483 list(c.getiterator('c', '*', 'a')))
2484 self.assertEqual(
2485 [],
2486 list(a.getiterator( (), () )))
2487
2489 Element = self.etree.Element
2490 SubElement = self.etree.SubElement
2491
2492 a = Element('a')
2493 b = SubElement(a, 'b')
2494 c = SubElement(a, 'c')
2495 d = SubElement(b, 'd')
2496 e = SubElement(c, 'e')
2497 f = SubElement(c, 'f')
2498
2499 self.assertEqual(
2500 [a, b],
2501 list(a.getiterator( ('a', 'b') )))
2502 self.assertEqual(
2503 [],
2504 list(a.getiterator( ('x', 'y') )))
2505 self.assertEqual(
2506 [a, f],
2507 list(a.getiterator( ('f', 'a') )))
2508 self.assertEqual(
2509 [c, e, f],
2510 list(c.getiterator( ('c', '*', 'a') )))
2511 self.assertEqual(
2512 [],
2513 list(a.getiterator( () )))
2514
2516 Element = self.etree.Element
2517 SubElement = self.etree.SubElement
2518
2519 a = Element('{a}a')
2520 b = SubElement(a, '{a}b')
2521 c = SubElement(a, '{a}c')
2522 d = SubElement(b, '{b}d')
2523 e = SubElement(c, '{a}e')
2524 f = SubElement(c, '{b}f')
2525 g = SubElement(c, 'g')
2526
2527 self.assertEqual(
2528 [a],
2529 list(a.getiterator('{a}a')))
2530 self.assertEqual(
2531 [],
2532 list(a.getiterator('{b}a')))
2533 self.assertEqual(
2534 [],
2535 list(a.getiterator('a')))
2536 self.assertEqual(
2537 [a,b,d,c,e,f,g],
2538 list(a.getiterator('*')))
2539 self.assertEqual(
2540 [f],
2541 list(c.getiterator('{b}*')))
2542 self.assertEqual(
2543 [d, f],
2544 list(a.getiterator('{b}*')))
2545 self.assertEqual(
2546 [g],
2547 list(a.getiterator('g')))
2548 self.assertEqual(
2549 [g],
2550 list(a.getiterator('{}g')))
2551 self.assertEqual(
2552 [g],
2553 list(a.getiterator('{}*')))
2554
2556 Element = self.etree.Element
2557 SubElement = self.etree.SubElement
2558
2559 a = Element('{a}a')
2560 b = SubElement(a, '{nsA}b')
2561 c = SubElement(b, '{nsB}b')
2562 d = SubElement(a, 'b')
2563 e = SubElement(a, '{nsA}e')
2564 f = SubElement(e, '{nsB}e')
2565 g = SubElement(e, 'e')
2566
2567 self.assertEqual(
2568 [b, c, d],
2569 list(a.getiterator('{*}b')))
2570 self.assertEqual(
2571 [e, f, g],
2572 list(a.getiterator('{*}e')))
2573 self.assertEqual(
2574 [a, b, c, d, e, f, g],
2575 list(a.getiterator('{*}*')))
2576
2601
2617
2634
2641
2648
2657
2659 XML = self.etree.XML
2660 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2661 self.assertEqual(len(root.findall(".//{X}b")), 2)
2662 self.assertEqual(len(root.findall(".//{X}*")), 2)
2663 self.assertEqual(len(root.findall(".//b")), 3)
2664
2666 XML = self.etree.XML
2667 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2668 nsmap = {'xx': 'X'}
2669 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2670 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2671 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2672 nsmap = {'xx': 'Y'}
2673 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2674 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2675 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2676
2678 XML = self.etree.XML
2679 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2680 nsmap = {'xx': 'X'}
2681 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2682 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2683 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2684 nsmap = {'xx': 'Y'}
2685 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2686 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2687 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2688
2695
2697 etree = self.etree
2698 e = etree.Element('foo')
2699 for i in range(10):
2700 etree.SubElement(e, 'a%s' % i)
2701 for i in range(10):
2702 self.assertEqual(
2703 i,
2704 e.index(e[i]))
2705 self.assertEqual(
2706 3, e.index(e[3], 3))
2707 self.assertRaises(
2708 ValueError, e.index, e[3], 4)
2709 self.assertRaises(
2710 ValueError, e.index, e[3], 0, 2)
2711 self.assertRaises(
2712 ValueError, e.index, e[8], 0, -3)
2713 self.assertRaises(
2714 ValueError, e.index, e[8], -5, -3)
2715 self.assertEqual(
2716 8, e.index(e[8], 0, -1))
2717 self.assertEqual(
2718 8, e.index(e[8], -12, -1))
2719 self.assertEqual(
2720 0, e.index(e[0], -12, -1))
2721
2723 etree = self.etree
2724 e = etree.Element('foo')
2725 for i in range(10):
2726 el = etree.SubElement(e, 'a%s' % i)
2727 el.text = "text%d" % i
2728 el.tail = "tail%d" % i
2729
2730 child0 = e[0]
2731 child1 = e[1]
2732 child2 = e[2]
2733
2734 e.replace(e[0], e[1])
2735 self.assertEqual(
2736 9, len(e))
2737 self.assertEqual(
2738 child1, e[0])
2739 self.assertEqual(
2740 child1.text, "text1")
2741 self.assertEqual(
2742 child1.tail, "tail1")
2743 self.assertEqual(
2744 child0.tail, "tail0")
2745 self.assertEqual(
2746 child2, e[1])
2747
2748 e.replace(e[-1], e[0])
2749 self.assertEqual(
2750 child1, e[-1])
2751 self.assertEqual(
2752 child1.text, "text1")
2753 self.assertEqual(
2754 child1.tail, "tail1")
2755 self.assertEqual(
2756 child2, e[0])
2757
2759 etree = self.etree
2760 e = etree.Element('foo')
2761 for i in range(10):
2762 etree.SubElement(e, 'a%s' % i)
2763
2764 new_element = etree.Element("test")
2765 new_element.text = "TESTTEXT"
2766 new_element.tail = "TESTTAIL"
2767 child1 = e[1]
2768 e.replace(e[0], new_element)
2769 self.assertEqual(
2770 new_element, e[0])
2771 self.assertEqual(
2772 "TESTTEXT",
2773 e[0].text)
2774 self.assertEqual(
2775 "TESTTAIL",
2776 e[0].tail)
2777 self.assertEqual(
2778 child1, e[1])
2779
2795
2813
2831
2849
2851 Element = self.etree.Element
2852 SubElement = self.etree.SubElement
2853 try:
2854 slice
2855 except NameError:
2856 print("slice() not found")
2857 return
2858
2859 a = Element('a')
2860 b = SubElement(a, 'b')
2861 c = SubElement(a, 'c')
2862 d = SubElement(a, 'd')
2863 e = SubElement(a, 'e')
2864
2865 x = Element('x')
2866 y = Element('y')
2867 z = Element('z')
2868
2869 self.assertRaises(
2870 ValueError,
2871 operator.setitem, a, slice(1,None,2), [x, y, z])
2872
2873 self.assertEqual(
2874 [b, c, d, e],
2875 list(a))
2876
2889
2897
2906
2916
2926
2932
2940
2946
2953
2959
2961 etree = self.etree
2962 xml_header = '<?xml version="1.0" encoding="ascii"?>'
2963 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2964 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2965 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
2966
2967 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2968
2969 tree = etree.parse(BytesIO(xml))
2970 docinfo = tree.docinfo
2971 self.assertEqual(docinfo.encoding, "ascii")
2972 self.assertEqual(docinfo.xml_version, "1.0")
2973 self.assertEqual(docinfo.public_id, pub_id)
2974 self.assertEqual(docinfo.system_url, sys_id)
2975 self.assertEqual(docinfo.root_name, 'html')
2976 self.assertEqual(docinfo.doctype, doctype_string)
2977
2993
3005
3017
3023
3025 etree = self.etree
3026 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3027 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3028 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
3029
3030 xml = _bytes('<!DOCTYPE root>\n<root/>')
3031 tree = etree.parse(BytesIO(xml))
3032 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
3033 etree.tostring(tree, doctype=doctype_string))
3034
3036 etree = self.etree
3037 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3038 self.assertEqual(root.base, "http://no/such/url")
3039 self.assertEqual(
3040 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3041 root.base = "https://secret/url"
3042 self.assertEqual(root.base, "https://secret/url")
3043 self.assertEqual(
3044 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3045 "https://secret/url")
3046
3048 etree = self.etree
3049 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3050 self.assertEqual(root.base, "http://no/such/url")
3051 self.assertEqual(
3052 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3053 root.set('{http://www.w3.org/XML/1998/namespace}base',
3054 "https://secret/url")
3055 self.assertEqual(root.base, "https://secret/url")
3056 self.assertEqual(
3057 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3058 "https://secret/url")
3059
3065
3070
3077
3091
3093 Element = self.etree.Element
3094
3095 a = Element('a')
3096 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3097 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3098
3099 self.assertRaises(ValueError, Element, 'ha\0ho')
3100
3102 Element = self.etree.Element
3103
3104 a = Element('a')
3105 self.assertRaises(ValueError, setattr, a, "text",
3106 _str('ha\0ho'))
3107 self.assertRaises(ValueError, setattr, a, "tail",
3108 _str('ha\0ho'))
3109
3110 self.assertRaises(ValueError, Element,
3111 _str('ha\0ho'))
3112
3114 Element = self.etree.Element
3115
3116 a = Element('a')
3117 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3118 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3119
3120 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3121 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3122
3123 self.assertRaises(ValueError, Element, 'ha\x07ho')
3124 self.assertRaises(ValueError, Element, 'ha\x02ho')
3125
3127 Element = self.etree.Element
3128
3129 a = Element('a')
3130 self.assertRaises(ValueError, setattr, a, "text",
3131 _str('ha\x07ho'))
3132 self.assertRaises(ValueError, setattr, a, "text",
3133 _str('ha\x02ho'))
3134
3135 self.assertRaises(ValueError, setattr, a, "tail",
3136 _str('ha\x07ho'))
3137 self.assertRaises(ValueError, setattr, a, "tail",
3138 _str('ha\x02ho'))
3139
3140 self.assertRaises(ValueError, Element,
3141 _str('ha\x07ho'))
3142 self.assertRaises(ValueError, Element,
3143 _str('ha\x02ho'))
3144
3146 Element = self.etree.Element
3147
3148 a = Element('a')
3149 self.assertRaises(ValueError, setattr, a, "text",
3150 _str('ha\u1234\x07ho'))
3151 self.assertRaises(ValueError, setattr, a, "text",
3152 _str('ha\u1234\x02ho'))
3153
3154 self.assertRaises(ValueError, setattr, a, "tail",
3155 _str('ha\u1234\x07ho'))
3156 self.assertRaises(ValueError, setattr, a, "tail",
3157 _str('ha\u1234\x02ho'))
3158
3159 self.assertRaises(ValueError, Element,
3160 _str('ha\u1234\x07ho'))
3161 self.assertRaises(ValueError, Element,
3162 _str('ha\u1234\x02ho'))
3163
3177
3182
3200
3220
3242
3244 tostring = self.etree.tostring
3245 XML = self.etree.XML
3246 ElementTree = self.etree.ElementTree
3247
3248 root = XML(_bytes("<root/>"))
3249
3250 tree = ElementTree(root)
3251 self.assertEqual(None, tree.docinfo.standalone)
3252
3253 result = tostring(root, xml_declaration=True, encoding="ASCII")
3254 self.assertEqual(result, _bytes(
3255 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3256
3257 result = tostring(root, xml_declaration=True, encoding="ASCII",
3258 standalone=True)
3259 self.assertEqual(result, _bytes(
3260 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3261
3262 tree = ElementTree(XML(result))
3263 self.assertEqual(True, tree.docinfo.standalone)
3264
3265 result = tostring(root, xml_declaration=True, encoding="ASCII",
3266 standalone=False)
3267 self.assertEqual(result, _bytes(
3268 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3269
3270 tree = ElementTree(XML(result))
3271 self.assertEqual(False, tree.docinfo.standalone)
3272
3292
3294 tostring = self.etree.tostring
3295 Element = self.etree.Element
3296 SubElement = self.etree.SubElement
3297
3298 a = Element('a')
3299 a.text = "A"
3300 a.tail = "tail"
3301 b = SubElement(a, 'b')
3302 b.text = "B"
3303 b.tail = _str("Søk på nettet")
3304 c = SubElement(a, 'c')
3305 c.text = "C"
3306
3307 result = tostring(a, method="text", encoding="UTF-16")
3308
3309 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3310 result)
3311
3313 tostring = self.etree.tostring
3314 Element = self.etree.Element
3315 SubElement = self.etree.SubElement
3316
3317 a = Element('a')
3318 a.text = _str('Søk på nettetA')
3319 a.tail = "tail"
3320 b = SubElement(a, 'b')
3321 b.text = "B"
3322 b.tail = _str('Søk på nettetB')
3323 c = SubElement(a, 'c')
3324 c.text = "C"
3325
3326 self.assertRaises(UnicodeEncodeError,
3327 tostring, a, method="text")
3328
3329 self.assertEqual(
3330 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3331 tostring(a, encoding="UTF-8", method="text"))
3332
3345
3361
3365
3380
3398
3411
3413 tostring = self.etree.tostring
3414 Element = self.etree.Element
3415 SubElement = self.etree.SubElement
3416
3417 a = Element('a')
3418 b = SubElement(a, 'b')
3419 c = SubElement(a, 'c')
3420 d = SubElement(c, 'd')
3421 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3422 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3423 self.assertEqual(_bytes('<b></b>'),
3424 canonicalize(tostring(b, encoding=_unicode)))
3425 self.assertEqual(_bytes('<c><d></d></c>'),
3426 canonicalize(tostring(c, encoding=_unicode)))
3427
3432
3447
3449 tostring = self.etree.tostring
3450 Element = self.etree.Element
3451 SubElement = self.etree.SubElement
3452
3453 a = Element('a')
3454 b = SubElement(a, 'b')
3455 c = SubElement(a, 'c')
3456
3457 result = tostring(a, encoding=_unicode)
3458 self.assertEqual(result, "<a><b/><c/></a>")
3459
3460 result = tostring(a, encoding=_unicode, pretty_print=False)
3461 self.assertEqual(result, "<a><b/><c/></a>")
3462
3463 result = tostring(a, encoding=_unicode, pretty_print=True)
3464 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3465
3477
3479 class SubEl(etree.ElementBase):
3480 pass
3481
3482 el1 = SubEl()
3483 el2 = SubEl()
3484 self.assertEqual('SubEl', el1.tag)
3485 self.assertEqual('SubEl', el2.tag)
3486 el1.other = el2
3487 el2.other = el1
3488
3489 del el1, el2
3490 gc.collect()
3491
3492
3493
3494
3495 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3506
3507
3510 filename = fileInTestDir('test_broken.xml')
3511 root = etree.XML(_bytes('''\
3512 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3513 <xi:include href="%s" parse="text"/>
3514 </doc>
3515 ''' % filename))
3516 old_text = root.text
3517 content = read_file(filename)
3518 old_tail = root[0].tail
3519
3520 self.include( etree.ElementTree(root) )
3521 self.assertEqual(old_text + content + old_tail,
3522 root.text)
3523
3535
3537 class res(etree.Resolver):
3538 include_text = read_file(fileInTestDir('test.xml'))
3539 called = {}
3540 def resolve(self, url, id, context):
3541 if url.endswith(".dtd"):
3542 self.called["dtd"] = True
3543 return self.resolve_filename(
3544 fileInTestDir('test.dtd'), context)
3545 elif url.endswith("test_xinclude.xml"):
3546 self.called["input"] = True
3547 return None
3548 else:
3549 self.called["include"] = True
3550 return self.resolve_string(self.include_text, context)
3551
3552 res_instance = res()
3553 parser = etree.XMLParser(load_dtd = True)
3554 parser.resolvers.add(res_instance)
3555
3556 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3557 parser = parser)
3558
3559 self.include(tree)
3560
3561 called = list(res_instance.called.items())
3562 called.sort()
3563 self.assertEqual(
3564 [("dtd", True), ("include", True), ("input", True)],
3565 called)
3566
3570
3571
3576
3577
3580 tree = self.parse(_bytes('<a><b/></a>'))
3581 f = BytesIO()
3582 tree.write_c14n(f)
3583 s = f.getvalue()
3584 self.assertEqual(_bytes('<a><b></b></a>'),
3585 s)
3586
3588 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3589 f = BytesIO()
3590 tree.write_c14n(f, compression=9)
3591 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3592 try:
3593 s = gzfile.read()
3594 finally:
3595 gzfile.close()
3596 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3597 s)
3598
3610
3626
3644
3656
3668
3670 tree = self.parse(_bytes(
3671 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3672 f = BytesIO()
3673 tree.write_c14n(f)
3674 s = f.getvalue()
3675 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3676 s)
3677 f = BytesIO()
3678 tree.write_c14n(f, exclusive=False)
3679 s = f.getvalue()
3680 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3681 s)
3682 f = BytesIO()
3683 tree.write_c14n(f, exclusive=True)
3684 s = f.getvalue()
3685 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3686 s)
3687
3688 f = BytesIO()
3689 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
3690 s = f.getvalue()
3691 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
3692 s)
3693
3695 tree = self.parse(_bytes(
3696 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3697 s = etree.tostring(tree, method='c14n')
3698 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3699 s)
3700 s = etree.tostring(tree, method='c14n', exclusive=False)
3701 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3702 s)
3703 s = etree.tostring(tree, method='c14n', exclusive=True)
3704 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3705 s)
3706
3707 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3708 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
3709 s)
3710
3712 tree = self.parse(_bytes(
3713 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3714 s = etree.tostring(tree.getroot(), method='c14n')
3715 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3716 s)
3717 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3718 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3719 s)
3720 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3721 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3722 s)
3723
3724 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3725 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3726 s)
3727 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3728 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3729 s)
3730
3731 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3732 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3733 s)
3734
3736 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
3737 tree = self.parse(_bytes(
3738 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3739
3740 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
3741 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3742 s)
3743
3744
3747 tree = self.parse(_bytes('<a><b/></a>'))
3748 f = BytesIO()
3749 tree.write(f)
3750 s = f.getvalue()
3751 self.assertEqual(_bytes('<a><b/></a>'),
3752 s)
3753
3755 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3756 f = BytesIO()
3757 tree.write(f, compression=9)
3758 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3759 try:
3760 s = gzfile.read()
3761 finally:
3762 gzfile.close()
3763 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3764 s)
3765
3767 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3768 f = BytesIO()
3769 tree.write(f, compression=0)
3770 s0 = f.getvalue()
3771
3772 f = BytesIO()
3773 tree.write(f)
3774 self.assertEqual(f.getvalue(), s0)
3775
3776 f = BytesIO()
3777 tree.write(f, compression=1)
3778 s = f.getvalue()
3779 self.assertTrue(len(s) <= len(s0))
3780 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3781 try:
3782 s1 = gzfile.read()
3783 finally:
3784 gzfile.close()
3785
3786 f = BytesIO()
3787 tree.write(f, compression=9)
3788 s = f.getvalue()
3789 self.assertTrue(len(s) <= len(s0))
3790 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3791 try:
3792 s9 = gzfile.read()
3793 finally:
3794 gzfile.close()
3795
3796 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3797 s0)
3798 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3799 s1)
3800 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3801 s9)
3802
3814
3830
3842
3855
3857 etree = etree
3858
3880
3882 """This can't really be tested as long as there isn't a way to
3883 reset the logging setup ...
3884 """
3885 parse = self.etree.parse
3886
3887 messages = []
3888 class Logger(self.etree.PyErrorLog):
3889 def log(self, entry, message, *args):
3890 messages.append(message)
3891
3892 self.etree.use_global_python_log(Logger())
3893 f = BytesIO('<a><b></c></b></a>')
3894 try:
3895 parse(f)
3896 except SyntaxError:
3897 pass
3898 f.close()
3899
3900 self.assertTrue([ message for message in messages
3901 if 'mismatch' in message ])
3902 self.assertTrue([ message for message in messages
3903 if ':PARSER:' in message])
3904 self.assertTrue([ message for message in messages
3905 if ':ERR_TAG_NAME_MISMATCH:' in message ])
3906 self.assertTrue([ message for message in messages
3907 if ':1:15:' in message ])
3908
3909
3911 etree = etree
3912
3916
3918 class Target(object):
3919 def start(self, tag, attrib):
3920 return 'start(%s)' % tag
3921 def end(self, tag):
3922 return 'end(%s)' % tag
3923 def close(self):
3924 return 'close()'
3925
3926 parser = self.etree.XMLPullParser(target=Target())
3927 events = parser.read_events()
3928
3929 parser.feed('<root><element>')
3930 self.assertFalse(list(events))
3931 self.assertFalse(list(events))
3932 parser.feed('</element><child>')
3933 self.assertEqual([('end', 'end(element)')], list(events))
3934 parser.feed('</child>')
3935 self.assertEqual([('end', 'end(child)')], list(events))
3936 parser.feed('</root>')
3937 self.assertEqual([('end', 'end(root)')], list(events))
3938 self.assertFalse(list(events))
3939 self.assertEqual('close()', parser.close())
3940
3942 class Target(object):
3943 def start(self, tag, attrib):
3944 return 'start(%s)' % tag
3945 def end(self, tag):
3946 return 'end(%s)' % tag
3947 def close(self):
3948 return 'close()'
3949
3950 parser = self.etree.XMLPullParser(
3951 ['start', 'end'], target=Target())
3952 events = parser.read_events()
3953
3954 parser.feed('<root><element>')
3955 self.assertEqual(
3956 [('start', 'start(root)'), ('start', 'start(element)')],
3957 list(events))
3958 self.assertFalse(list(events))
3959 parser.feed('</element><child>')
3960 self.assertEqual(
3961 [('end', 'end(element)'), ('start', 'start(child)')],
3962 list(events))
3963 parser.feed('</child>')
3964 self.assertEqual(
3965 [('end', 'end(child)')],
3966 list(events))
3967 parser.feed('</root>')
3968 self.assertEqual(
3969 [('end', 'end(root)')],
3970 list(events))
3971 self.assertFalse(list(events))
3972 self.assertEqual('close()', parser.close())
3973
3975 parser = self.etree.XMLPullParser(
3976 ['start', 'end'], target=etree.TreeBuilder())
3977 events = parser.read_events()
3978
3979 parser.feed('<root><element>')
3980 self.assert_event_tags(
3981 events, [('start', 'root'), ('start', 'element')])
3982 self.assertFalse(list(events))
3983 parser.feed('</element><child>')
3984 self.assert_event_tags(
3985 events, [('end', 'element'), ('start', 'child')])
3986 parser.feed('</child>')
3987 self.assert_event_tags(
3988 events, [('end', 'child')])
3989 parser.feed('</root>')
3990 self.assert_event_tags(
3991 events, [('end', 'root')])
3992 self.assertFalse(list(events))
3993 root = parser.close()
3994 self.assertEqual('root', root.tag)
3995
3997 class Target(etree.TreeBuilder):
3998 def end(self, tag):
3999 el = super(Target, self).end(tag)
4000 el.tag += '-huhu'
4001 return el
4002
4003 parser = self.etree.XMLPullParser(
4004 ['start', 'end'], target=Target())
4005 events = parser.read_events()
4006
4007 parser.feed('<root><element>')
4008 self.assert_event_tags(
4009 events, [('start', 'root'), ('start', 'element')])
4010 self.assertFalse(list(events))
4011 parser.feed('</element><child>')
4012 self.assert_event_tags(
4013 events, [('end', 'element-huhu'), ('start', 'child')])
4014 parser.feed('</child>')
4015 self.assert_event_tags(
4016 events, [('end', 'child-huhu')])
4017 parser.feed('</root>')
4018 self.assert_event_tags(
4019 events, [('end', 'root-huhu')])
4020 self.assertFalse(list(events))
4021 root = parser.close()
4022 self.assertEqual('root-huhu', root.tag)
4023
4024
4048
4049 if __name__ == '__main__':
4050 print('to test use test.py %s' % __file__)
4051