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
26 from common_imports import fileInTestDir, fileUrlInTestDir, read_file, path2url
27 from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest
28 from common_imports import canonicalize, sorted, _str, _bytes
29
30 print("")
31 print("TESTED VERSION: %s" % etree.__version__)
32 print(" Python: " + repr(sys.version_info))
33 print(" lxml.etree: " + repr(etree.LXML_VERSION))
34 print(" libxml used: " + repr(etree.LIBXML_VERSION))
35 print(" libxml compiled: " + repr(etree.LIBXML_COMPILED_VERSION))
36 print(" libxslt used: " + repr(etree.LIBXSLT_VERSION))
37 print(" libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION))
38 print("")
39
40 try:
41 _unicode = unicode
42 except NameError:
43
44 _unicode = str
45
47 """Tests only for etree, not ElementTree"""
48 etree = etree
49
60
69
76
78 Element = self.etree.Element
79 el = Element('name')
80 self.assertRaises(ValueError, Element, '{}')
81 self.assertRaises(ValueError, setattr, el, 'tag', '{}')
82
83 self.assertRaises(ValueError, Element, '{test}')
84 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
85
93
95 Element = self.etree.Element
96 self.assertRaises(ValueError, Element, "p'name")
97 self.assertRaises(ValueError, Element, 'p"name')
98
99 self.assertRaises(ValueError, Element, "{test}p'name")
100 self.assertRaises(ValueError, Element, '{test}p"name')
101
102 el = Element('name')
103 self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
104 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
105
107 Element = self.etree.Element
108 self.assertRaises(ValueError, Element, ' name ')
109 self.assertRaises(ValueError, Element, 'na me')
110 self.assertRaises(ValueError, Element, '{test} name')
111
112 el = Element('name')
113 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
114
122
130
132 Element = self.etree.Element
133 SubElement = self.etree.SubElement
134
135 el = Element('name')
136 self.assertRaises(ValueError, SubElement, el, "p'name")
137 self.assertRaises(ValueError, SubElement, el, "{test}p'name")
138
139 self.assertRaises(ValueError, SubElement, el, 'p"name')
140 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
141
150
159
161 QName = self.etree.QName
162 self.assertRaises(ValueError, QName, '')
163 self.assertRaises(ValueError, QName, 'test', '')
164
166 QName = self.etree.QName
167 self.assertRaises(ValueError, QName, 'p:name')
168 self.assertRaises(ValueError, QName, 'test', 'p:name')
169
171 QName = self.etree.QName
172 self.assertRaises(ValueError, QName, ' name ')
173 self.assertRaises(ValueError, QName, 'na me')
174 self.assertRaises(ValueError, QName, 'test', ' name')
175
183
185
186 QName = self.etree.QName
187 qname1 = QName('http://myns', 'a')
188 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
189
190 qname2 = QName(a)
191 self.assertEqual(a.tag, qname1.text)
192 self.assertEqual(qname1.text, qname2.text)
193 self.assertEqual(qname1, qname2)
194
196
197 etree = self.etree
198 qname = etree.QName('http://myns', 'a')
199 a = etree.Element(qname, nsmap={'p' : 'http://myns'})
200 a.text = qname
201
202 self.assertEqual("p:a", a.text)
203
212
227
233
245
247 Element = self.etree.Element
248
249 keys = ["attr%d" % i for i in range(10)]
250 values = ["TEST-%d" % i for i in range(10)]
251 items = list(zip(keys, values))
252
253 root = Element("root")
254 for key, value in items:
255 root.set(key, value)
256 self.assertEqual(keys, root.attrib.keys())
257 self.assertEqual(values, root.attrib.values())
258
259 root2 = Element("root2", root.attrib,
260 attr_99='TOAST-1', attr_98='TOAST-2')
261 self.assertEqual(['attr_98', 'attr_99'] + keys,
262 root2.attrib.keys())
263 self.assertEqual(['TOAST-2', 'TOAST-1'] + values,
264 root2.attrib.values())
265
266 self.assertEqual(keys, root.attrib.keys())
267 self.assertEqual(values, root.attrib.values())
268
276
290
312
314 XML = self.etree.XML
315 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
316
317 root = XML(xml)
318 self.etree.strip_elements(root, 'a')
319 self.assertEqual(_bytes('<test><x></x></test>'),
320 self._writeElement(root))
321
322 root = XML(xml)
323 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
324 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'),
325 self._writeElement(root))
326
327 root = XML(xml)
328 self.etree.strip_elements(root, 'c')
329 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
330 self._writeElement(root))
331
333 XML = self.etree.XML
334 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>')
335
336 root = XML(xml)
337 self.etree.strip_elements(root, 'a')
338 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>'),
339 self._writeElement(root))
340
341 root = XML(xml)
342 self.etree.strip_elements(root, '{urn:a}b', 'c')
343 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>'),
344 self._writeElement(root))
345
346 root = XML(xml)
347 self.etree.strip_elements(root, '{urn:a}*', 'c')
348 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
349 self._writeElement(root))
350
351 root = XML(xml)
352 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
353 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
354 self._writeElement(root))
355
374
400
427
454
473
486
497
503
505 XML = self.etree.XML
506 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
507 self.assertEqual(root[0].target, "mypi")
508 self.assertEqual(root[0].get('my'), "1")
509 self.assertEqual(root[0].get('test'), " abc ")
510 self.assertEqual(root[0].get('quotes'), "' '")
511 self.assertEqual(root[0].get('only'), None)
512 self.assertEqual(root[0].get('names'), None)
513 self.assertEqual(root[0].get('nope'), None)
514
516 XML = self.etree.XML
517 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
518 self.assertEqual(root[0].target, "mypi")
519 self.assertEqual(root[0].attrib['my'], "1")
520 self.assertEqual(root[0].attrib['test'], " abc ")
521 self.assertEqual(root[0].attrib['quotes'], "' '")
522 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
523 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
524 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
525
527
528 ProcessingInstruction = self.etree.ProcessingInstruction
529
530 a = ProcessingInstruction("PI", "ONE")
531 b = copy.deepcopy(a)
532 b.text = "ANOTHER"
533
534 self.assertEqual('ONE', a.text)
535 self.assertEqual('ANOTHER', b.text)
536
552
567
577
589
608
613
626
637
638 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
639 events = list(iterparse(f, events=('end', 'comment')))
640 root = events[-1][1]
641 self.assertEqual(6, len(events))
642 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'],
643 [ name(*item) for item in events ])
644 self.assertEqual(
645 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
646 tostring(root))
647
659
660 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
661 events = list(iterparse(f, events=('end', 'pi')))
662 root = events[-2][1]
663 self.assertEqual(8, len(events))
664 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
665 ('pid','d'), 'a', ('pie','e')],
666 [ name(*item) for item in events ])
667 self.assertEqual(
668 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
669 tostring(ElementTree(root)))
670
685
691
693 iterparse = self.etree.iterparse
694 f = BytesIO('<a><b><c/></a>')
695 it = iterparse(f, events=('start', 'end'), recover=True)
696 events = [(ev, el.tag) for ev, el in it]
697 root = it.root
698 self.assertTrue(root is not None)
699
700 self.assertEqual(1, events.count(('start', 'a')))
701 self.assertEqual(1, events.count(('end', 'a')))
702
703 self.assertEqual(1, events.count(('start', 'b')))
704 self.assertEqual(1, events.count(('end', 'b')))
705
706 self.assertEqual(1, events.count(('start', 'c')))
707 self.assertEqual(1, events.count(('end', 'c')))
708
710 iterparse = self.etree.iterparse
711 f = BytesIO('<a><b><c/></d><b><c/></a></b>')
712 it = iterparse(f, events=('start', 'end'), recover=True)
713 events = [(ev, el.tag) for ev, el in it]
714 root = it.root
715 self.assertTrue(root is not None)
716
717 self.assertEqual(1, events.count(('start', 'a')))
718 self.assertEqual(1, events.count(('end', 'a')))
719
720 self.assertEqual(2, events.count(('start', 'b')))
721 self.assertEqual(2, events.count(('end', 'b')))
722
723 self.assertEqual(2, events.count(('start', 'c')))
724 self.assertEqual(2, events.count(('end', 'c')))
725
727 iterparse = self.etree.iterparse
728 f = BytesIO("""
729 <a> \n \n <b> b test </b> \n
730
731 \n\t <c> \n </c> </a> \n """)
732 iterator = iterparse(f, remove_blank_text=True)
733 text = [ (element.text, element.tail)
734 for event, element in iterator ]
735 self.assertEqual(
736 [(" b test ", None), (" \n ", None), (None, None)],
737 text)
738
740 iterparse = self.etree.iterparse
741 f = BytesIO('<a><b><d/></b><c/></a>')
742
743 iterator = iterparse(f, tag="b", events=('start', 'end'))
744 events = list(iterator)
745 root = iterator.root
746 self.assertEqual(
747 [('start', root[0]), ('end', root[0])],
748 events)
749
751 iterparse = self.etree.iterparse
752 f = BytesIO('<a><b><d/></b><c/></a>')
753
754 iterator = iterparse(f, tag="*", events=('start', 'end'))
755 events = list(iterator)
756 self.assertEqual(
757 8,
758 len(events))
759
761 iterparse = self.etree.iterparse
762 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
763
764 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
765 events = list(iterator)
766 root = iterator.root
767 self.assertEqual(
768 [('start', root[0]), ('end', root[0])],
769 events)
770
772 iterparse = self.etree.iterparse
773 f = BytesIO('<a><b><d/></b><c/></a>')
774 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
775 events = list(iterator)
776 root = iterator.root
777 self.assertEqual(
778 [('start', root[0]), ('end', root[0])],
779 events)
780
781 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
782 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
783 events = list(iterator)
784 root = iterator.root
785 self.assertEqual([], events)
786
788 iterparse = self.etree.iterparse
789 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
790 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
791 events = list(iterator)
792 self.assertEqual(8, len(events))
793
795 iterparse = self.etree.iterparse
796 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
797 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
798 events = list(iterator)
799 self.assertEqual([], events)
800
801 f = BytesIO('<a><b><d/></b><c/></a>')
802 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
803 events = list(iterator)
804 self.assertEqual(8, len(events))
805
807 text = _str('Søk på nettet')
808 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
809 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
810 ).encode('iso-8859-1')
811
812 self.assertRaises(self.etree.ParseError,
813 list, self.etree.iterparse(BytesIO(xml_latin1)))
814
816 text = _str('Søk på nettet', encoding="UTF-8")
817 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
818 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
819 ).encode('iso-8859-1')
820
821 iterator = self.etree.iterparse(BytesIO(xml_latin1),
822 encoding="iso-8859-1")
823 self.assertEqual(1, len(list(iterator)))
824
825 a = iterator.root
826 self.assertEqual(a.text, text)
827
829 tostring = self.etree.tostring
830 f = BytesIO('<root><![CDATA[test]]></root>')
831 context = self.etree.iterparse(f, strip_cdata=False)
832 content = [ el.text for event,el in context ]
833
834 self.assertEqual(['test'], content)
835 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
836 tostring(context.root))
837
841
846
865
866
867
878 def end(self, tag):
879 events.append("end")
880 assertEqual("TAG", tag)
881 def close(self):
882 return "DONE"
883
884 parser = self.etree.XMLParser(target=Target())
885 tree = self.etree.ElementTree()
886
887 self.assertRaises(TypeError,
888 tree.parse, BytesIO("<TAG/>"), parser=parser)
889 self.assertEqual(["start", "end"], events)
890
892
893 events = []
894 class Target(object):
895 def start(self, tag, attrib):
896 events.append("start-" + tag)
897 def end(self, tag):
898 events.append("end-" + tag)
899 if tag == 'a':
900 raise ValueError("dead and gone")
901 def data(self, data):
902 events.append("data-" + data)
903 def close(self):
904 events.append("close")
905 return "DONE"
906
907 parser = self.etree.XMLParser(target=Target())
908
909 try:
910 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
911 done = parser.close()
912 self.fail("error expected, but parsing succeeded")
913 except ValueError:
914 done = 'value error received as expected'
915
916 self.assertEqual(["start-root", "data-A", "start-a",
917 "data-ca", "end-a", "close"],
918 events)
919
921
922 events = []
923 class Target(object):
924 def start(self, tag, attrib):
925 events.append("start-" + tag)
926 def end(self, tag):
927 events.append("end-" + tag)
928 if tag == 'a':
929 raise ValueError("dead and gone")
930 def data(self, data):
931 events.append("data-" + data)
932 def close(self):
933 events.append("close")
934 return "DONE"
935
936 parser = self.etree.XMLParser(target=Target())
937
938 try:
939 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
940 parser=parser)
941 self.fail("error expected, but parsing succeeded")
942 except ValueError:
943 done = 'value error received as expected'
944
945 self.assertEqual(["start-root", "data-A", "start-a",
946 "data-ca", "end-a", "close"],
947 events)
948
954 def end(self, tag):
955 events.append("end-" + tag)
956 def data(self, data):
957 events.append("data-" + data)
958 def comment(self, text):
959 events.append("comment-" + text)
960 def close(self):
961 return "DONE"
962
963 parser = self.etree.XMLParser(target=Target())
964
965 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
966 done = parser.close()
967
968 self.assertEqual("DONE", done)
969 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
970 "start-sub", "end-sub", "comment-c", "data-B",
971 "end-root", "comment-d"],
972 events)
973
975 events = []
976 class Target(object):
977 def start(self, tag, attrib):
978 events.append("start-" + tag)
979 def end(self, tag):
980 events.append("end-" + tag)
981 def data(self, data):
982 events.append("data-" + data)
983 def pi(self, target, data):
984 events.append("pi-" + target + "-" + data)
985 def close(self):
986 return "DONE"
987
988 parser = self.etree.XMLParser(target=Target())
989
990 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
991 done = parser.close()
992
993 self.assertEqual("DONE", done)
994 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b",
995 "data-B", "end-root", "pi-test-c"],
996 events)
997
999 events = []
1000 class Target(object):
1001 def start(self, tag, attrib):
1002 events.append("start-" + tag)
1003 def end(self, tag):
1004 events.append("end-" + tag)
1005 def data(self, data):
1006 events.append("data-" + data)
1007 def close(self):
1008 return "DONE"
1009
1010 parser = self.etree.XMLParser(target=Target(),
1011 strip_cdata=False)
1012
1013 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
1014 done = parser.close()
1015
1016 self.assertEqual("DONE", done)
1017 self.assertEqual(["start-root", "data-A", "start-a",
1018 "data-ca", "end-a", "data-B", "end-root"],
1019 events)
1020
1022 events = []
1023 class Target(object):
1024 def start(self, tag, attrib):
1025 events.append("start-" + tag)
1026 def end(self, tag):
1027 events.append("end-" + tag)
1028 def data(self, data):
1029 events.append("data-" + data)
1030 def close(self):
1031 events.append("close")
1032 return "DONE"
1033
1034 parser = self.etree.XMLParser(target=Target(),
1035 recover=True)
1036
1037 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
1038 done = parser.close()
1039
1040 self.assertEqual("DONE", done)
1041 self.assertEqual(["start-root", "data-A", "start-a",
1042 "data-ca", "end-a", "data-B",
1043 "end-root", "close"],
1044 events)
1045
1055
1065
1074
1084
1086 iterwalk = self.etree.iterwalk
1087 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1088
1089 iterator = iterwalk(root, events=('start','end'))
1090 events = list(iterator)
1091 self.assertEqual(
1092 [('start', root), ('start', root[0]), ('end', root[0]),
1093 ('start', root[1]), ('end', root[1]), ('end', root)],
1094 events)
1095
1106
1108 iterwalk = self.etree.iterwalk
1109 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1110
1111 attr_name = '{testns}bla'
1112 events = []
1113 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1114 for event, elem in iterator:
1115 events.append(event)
1116 if event == 'start':
1117 if elem.tag != '{ns1}a':
1118 elem.set(attr_name, 'value')
1119
1120 self.assertEqual(
1121 ['start-ns', 'start', 'start', 'start-ns', 'start',
1122 'end', 'end-ns', 'end', 'end', 'end-ns'],
1123 events)
1124
1125 self.assertEqual(
1126 None,
1127 root.get(attr_name))
1128 self.assertEqual(
1129 'value',
1130 root[0].get(attr_name))
1131
1142
1144 parse = self.etree.parse
1145 parser = self.etree.XMLParser(dtd_validation=True)
1146 assertEqual = self.assertEqual
1147 test_url = _str("__nosuch.dtd")
1148
1149 class MyResolver(self.etree.Resolver):
1150 def resolve(self, url, id, context):
1151 assertEqual(url, test_url)
1152 return self.resolve_string(
1153 _str('''<!ENTITY myentity "%s">
1154 <!ELEMENT doc ANY>''') % url, context)
1155
1156 parser.resolvers.add(MyResolver())
1157
1158 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1159 tree = parse(StringIO(xml), parser)
1160 root = tree.getroot()
1161 self.assertEqual(root.text, test_url)
1162
1164 parse = self.etree.parse
1165 parser = self.etree.XMLParser(dtd_validation=True)
1166 assertEqual = self.assertEqual
1167 test_url = _str("__nosuch.dtd")
1168
1169 class MyResolver(self.etree.Resolver):
1170 def resolve(self, url, id, context):
1171 assertEqual(url, test_url)
1172 return self.resolve_string(
1173 (_str('''<!ENTITY myentity "%s">
1174 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1175 context)
1176
1177 parser.resolvers.add(MyResolver())
1178
1179 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1180 tree = parse(StringIO(xml), parser)
1181 root = tree.getroot()
1182 self.assertEqual(root.text, test_url)
1183
1185 parse = self.etree.parse
1186 parser = self.etree.XMLParser(dtd_validation=True)
1187 assertEqual = self.assertEqual
1188 test_url = _str("__nosuch.dtd")
1189
1190 class MyResolver(self.etree.Resolver):
1191 def resolve(self, url, id, context):
1192 assertEqual(url, test_url)
1193 return self.resolve_file(
1194 SillyFileLike(
1195 _str('''<!ENTITY myentity "%s">
1196 <!ELEMENT doc ANY>''') % url), context)
1197
1198 parser.resolvers.add(MyResolver())
1199
1200 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1201 tree = parse(StringIO(xml), parser)
1202 root = tree.getroot()
1203 self.assertEqual(root.text, test_url)
1204
1206 parse = self.etree.parse
1207 parser = self.etree.XMLParser(attribute_defaults=True)
1208 assertEqual = self.assertEqual
1209 test_url = _str("__nosuch.dtd")
1210
1211 class MyResolver(self.etree.Resolver):
1212 def resolve(self, url, id, context):
1213 assertEqual(url, test_url)
1214 return self.resolve_filename(
1215 fileInTestDir('test.dtd'), context)
1216
1217 parser.resolvers.add(MyResolver())
1218
1219 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1220 tree = parse(StringIO(xml), parser)
1221 root = tree.getroot()
1222 self.assertEqual(
1223 root.attrib, {'default': 'valueA'})
1224 self.assertEqual(
1225 root[0].attrib, {'default': 'valueB'})
1226
1238
1239 parser.resolvers.add(MyResolver())
1240
1241 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1242 tree = parse(StringIO(xml), parser,
1243 base_url=fileUrlInTestDir('__test.xml'))
1244 root = tree.getroot()
1245 self.assertEqual(
1246 root.attrib, {'default': 'valueA'})
1247 self.assertEqual(
1248 root[0].attrib, {'default': 'valueB'})
1249
1251 parse = self.etree.parse
1252 parser = self.etree.XMLParser(attribute_defaults=True)
1253 assertEqual = self.assertEqual
1254 test_url = _str("__nosuch.dtd")
1255
1256 class MyResolver(self.etree.Resolver):
1257 def resolve(self, url, id, context):
1258 assertEqual(url, test_url)
1259 return self.resolve_file(
1260 open(fileInTestDir('test.dtd'), 'rb'), context)
1261
1262 parser.resolvers.add(MyResolver())
1263
1264 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1265 tree = parse(StringIO(xml), parser)
1266 root = tree.getroot()
1267 self.assertEqual(
1268 root.attrib, {'default': 'valueA'})
1269 self.assertEqual(
1270 root[0].attrib, {'default': 'valueB'})
1271
1273 parse = self.etree.parse
1274 parser = self.etree.XMLParser(load_dtd=True)
1275 assertEqual = self.assertEqual
1276 test_url = _str("__nosuch.dtd")
1277
1278 class check(object):
1279 resolved = False
1280
1281 class MyResolver(self.etree.Resolver):
1282 def resolve(self, url, id, context):
1283 assertEqual(url, test_url)
1284 check.resolved = True
1285 return self.resolve_empty(context)
1286
1287 parser.resolvers.add(MyResolver())
1288
1289 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1290 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1291 self.assertTrue(check.resolved)
1292
1299
1300 class MyResolver(self.etree.Resolver):
1301 def resolve(self, url, id, context):
1302 raise _LocalException
1303
1304 parser.resolvers.add(MyResolver())
1305
1306 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1307 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1308
1309 if etree.LIBXML_VERSION > (2,6,20):
1326
1328 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1329 <root>
1330 <child1/>
1331 <child2/>
1332 <child3> </child3>
1333 </root>''')
1334
1335 parser = self.etree.XMLParser(resolve_entities=False)
1336 root = etree.fromstring(xml, parser)
1337 self.assertEqual([ el.tag for el in root ],
1338 ['child1', 'child2', 'child3'])
1339
1340 root[0] = root[-1]
1341 self.assertEqual([ el.tag for el in root ],
1342 ['child3', 'child2'])
1343 self.assertEqual(root[0][0].text, ' ')
1344 self.assertEqual(root[0][0].name, 'nbsp')
1345
1361
1368
1370 Entity = self.etree.Entity
1371 self.assertRaises(ValueError, Entity, 'a b c')
1372 self.assertRaises(ValueError, Entity, 'a,b')
1373 self.assertRaises(ValueError, Entity, 'a\0b')
1374 self.assertRaises(ValueError, Entity, '#abc')
1375 self.assertRaises(ValueError, Entity, '#xxyz')
1376
1389
1402
1404 CDATA = self.etree.CDATA
1405 Element = self.etree.Element
1406
1407 root = Element("root")
1408 cdata = CDATA('test')
1409
1410 self.assertRaises(TypeError,
1411 setattr, root, 'tail', cdata)
1412 self.assertRaises(TypeError,
1413 root.set, 'attr', cdata)
1414 self.assertRaises(TypeError,
1415 operator.setitem, root.attrib, 'attr', cdata)
1416
1425
1434
1435
1445
1454
1456 Element = self.etree.Element
1457 SubElement = self.etree.SubElement
1458 root = Element('root')
1459 self.assertRaises(ValueError, root.append, root)
1460 child = SubElement(root, 'child')
1461 self.assertRaises(ValueError, child.append, root)
1462 child2 = SubElement(child, 'child2')
1463 self.assertRaises(ValueError, child2.append, root)
1464 self.assertRaises(ValueError, child2.append, child)
1465 self.assertEqual('child2', root[0][0].tag)
1466
1479
1492
1503
1514
1524
1534
1550
1566
1572
1587
1600
1615
1628
1643
1656
1671
1684
1685
1693
1694
1704
1705
1720
1721
1731
1732
1743
1770
1771
1773 self.assertRaises(TypeError, self.etree.dump, None)
1774
1787
1800
1821
1830
1839
1848
1857
1866
1868 XML = self.etree.XML
1869
1870 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1871 result = []
1872 for el in root.iterchildren(tag=['two', 'three']):
1873 result.append(el.text)
1874 self.assertEqual(['Two', 'Bla', None], result)
1875
1877 XML = self.etree.XML
1878
1879 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1880 result = []
1881 for el in root.iterchildren('two', 'three'):
1882 result.append(el.text)
1883 self.assertEqual(['Two', 'Bla', None], result)
1884
1893
1914
1936
1938 Element = self.etree.Element
1939 SubElement = self.etree.SubElement
1940
1941 a = Element('a')
1942 b = SubElement(a, 'b')
1943 c = SubElement(a, 'c')
1944 d = SubElement(b, 'd')
1945 self.assertEqual(
1946 [b, a],
1947 list(d.iterancestors(tag=('a', 'b'))))
1948 self.assertEqual(
1949 [b, a],
1950 list(d.iterancestors('a', 'b')))
1951
1952 self.assertEqual(
1953 [],
1954 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
1955 self.assertEqual(
1956 [],
1957 list(d.iterancestors('w', 'x', 'y', 'z')))
1958
1959 self.assertEqual(
1960 [],
1961 list(d.iterancestors(tag=('d', 'x'))))
1962 self.assertEqual(
1963 [],
1964 list(d.iterancestors('d', 'x')))
1965
1966 self.assertEqual(
1967 [b, a],
1968 list(d.iterancestors(tag=('b', '*'))))
1969 self.assertEqual(
1970 [b, a],
1971 list(d.iterancestors('b', '*')))
1972
1973 self.assertEqual(
1974 [b],
1975 list(d.iterancestors(tag=('b', 'c'))))
1976 self.assertEqual(
1977 [b],
1978 list(d.iterancestors('b', 'c')))
1979
1996
1998 Element = self.etree.Element
1999 SubElement = self.etree.SubElement
2000
2001 a = Element('a')
2002 b = SubElement(a, 'b')
2003 c = SubElement(a, 'c')
2004 d = SubElement(b, 'd')
2005 e = SubElement(c, 'e')
2006
2007 self.assertEqual(
2008 [],
2009 list(a.iterdescendants('a')))
2010 self.assertEqual(
2011 [],
2012 list(a.iterdescendants(tag='a')))
2013
2014 a2 = SubElement(e, 'a')
2015 self.assertEqual(
2016 [a2],
2017 list(a.iterdescendants('a')))
2018
2019 self.assertEqual(
2020 [a2],
2021 list(c.iterdescendants('a')))
2022 self.assertEqual(
2023 [a2],
2024 list(c.iterdescendants(tag='a')))
2025
2027 Element = self.etree.Element
2028 SubElement = self.etree.SubElement
2029
2030 a = Element('a')
2031 b = SubElement(a, 'b')
2032 c = SubElement(a, 'c')
2033 d = SubElement(b, 'd')
2034 e = SubElement(c, 'e')
2035
2036 self.assertEqual(
2037 [b, e],
2038 list(a.iterdescendants(tag=('a', 'b', 'e'))))
2039 self.assertEqual(
2040 [b, e],
2041 list(a.iterdescendants('a', 'b', 'e')))
2042
2043 a2 = SubElement(e, 'a')
2044 self.assertEqual(
2045 [b, a2],
2046 list(a.iterdescendants(tag=('a', 'b'))))
2047 self.assertEqual(
2048 [b, a2],
2049 list(a.iterdescendants('a', 'b')))
2050
2051 self.assertEqual(
2052 [],
2053 list(c.iterdescendants(tag=('x', 'y', 'z'))))
2054 self.assertEqual(
2055 [],
2056 list(c.iterdescendants('x', 'y', 'z')))
2057
2058 self.assertEqual(
2059 [b, d, c, e, a2],
2060 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
2061 self.assertEqual(
2062 [b, d, c, e, a2],
2063 list(a.iterdescendants('x', 'y', 'z', '*')))
2064
2082
2099
2117
2141
2143 Element = self.etree.Element
2144 SubElement = self.etree.SubElement
2145
2146 a = Element('a')
2147 b = SubElement(a, 'b')
2148 c = SubElement(a, 'c')
2149 d = SubElement(b, 'd')
2150 self.assertEqual(
2151 [],
2152 list(a.itersiblings(tag='XXX')))
2153 self.assertEqual(
2154 [c],
2155 list(b.itersiblings(tag='c')))
2156 self.assertEqual(
2157 [c],
2158 list(b.itersiblings(tag='*')))
2159 self.assertEqual(
2160 [b],
2161 list(c.itersiblings(preceding=True, tag='b')))
2162 self.assertEqual(
2163 [],
2164 list(c.itersiblings(preceding=True, tag='c')))
2165
2167 Element = self.etree.Element
2168 SubElement = self.etree.SubElement
2169
2170 a = Element('a')
2171 b = SubElement(a, 'b')
2172 c = SubElement(a, 'c')
2173 d = SubElement(b, 'd')
2174 e = SubElement(a, 'e')
2175 self.assertEqual(
2176 [],
2177 list(a.itersiblings(tag=('XXX', 'YYY'))))
2178 self.assertEqual(
2179 [c, e],
2180 list(b.itersiblings(tag=('c', 'd', 'e'))))
2181 self.assertEqual(
2182 [b],
2183 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2184 self.assertEqual(
2185 [c, b],
2186 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2187
2189 parseid = self.etree.parseid
2190 XML = self.etree.XML
2191 xml_text = _bytes('''
2192 <!DOCTYPE document [
2193 <!ELEMENT document (h1,p)*>
2194 <!ELEMENT h1 (#PCDATA)>
2195 <!ATTLIST h1 myid ID #REQUIRED>
2196 <!ELEMENT p (#PCDATA)>
2197 <!ATTLIST p someid ID #REQUIRED>
2198 ]>
2199 <document>
2200 <h1 myid="chapter1">...</h1>
2201 <p id="note1" class="note">...</p>
2202 <p>Regular paragraph.</p>
2203 <p xml:id="xmlid">XML:ID paragraph.</p>
2204 <p someid="warn1" class="warning">...</p>
2205 </document>
2206 ''')
2207
2208 tree, dic = parseid(BytesIO(xml_text))
2209 root = tree.getroot()
2210 root2 = XML(xml_text)
2211 self.assertEqual(self._writeElement(root),
2212 self._writeElement(root2))
2213 expected = {
2214 "chapter1" : root[0],
2215 "xmlid" : root[3],
2216 "warn1" : root[4]
2217 }
2218 self.assertTrue("chapter1" in dic)
2219 self.assertTrue("warn1" in dic)
2220 self.assertTrue("xmlid" in dic)
2221 self._checkIDDict(dic, expected)
2222
2224 XMLDTDID = self.etree.XMLDTDID
2225 XML = self.etree.XML
2226 xml_text = _bytes('''
2227 <!DOCTYPE document [
2228 <!ELEMENT document (h1,p)*>
2229 <!ELEMENT h1 (#PCDATA)>
2230 <!ATTLIST h1 myid ID #REQUIRED>
2231 <!ELEMENT p (#PCDATA)>
2232 <!ATTLIST p someid ID #REQUIRED>
2233 ]>
2234 <document>
2235 <h1 myid="chapter1">...</h1>
2236 <p id="note1" class="note">...</p>
2237 <p>Regular paragraph.</p>
2238 <p xml:id="xmlid">XML:ID paragraph.</p>
2239 <p someid="warn1" class="warning">...</p>
2240 </document>
2241 ''')
2242
2243 root, dic = XMLDTDID(xml_text)
2244 root2 = XML(xml_text)
2245 self.assertEqual(self._writeElement(root),
2246 self._writeElement(root2))
2247 expected = {
2248 "chapter1" : root[0],
2249 "xmlid" : root[3],
2250 "warn1" : root[4]
2251 }
2252 self.assertTrue("chapter1" in dic)
2253 self.assertTrue("warn1" in dic)
2254 self.assertTrue("xmlid" in dic)
2255 self._checkIDDict(dic, expected)
2256
2258 XMLDTDID = self.etree.XMLDTDID
2259 XML = self.etree.XML
2260 xml_text = _bytes('''
2261 <document>
2262 <h1 myid="chapter1">...</h1>
2263 <p id="note1" class="note">...</p>
2264 <p>Regular paragraph.</p>
2265 <p someid="warn1" class="warning">...</p>
2266 </document>
2267 ''')
2268
2269 root, dic = XMLDTDID(xml_text)
2270 root2 = XML(xml_text)
2271 self.assertEqual(self._writeElement(root),
2272 self._writeElement(root2))
2273 expected = {}
2274 self._checkIDDict(dic, expected)
2275
2277 self.assertEqual(len(dic),
2278 len(expected))
2279 self.assertEqual(sorted(dic.items()),
2280 sorted(expected.items()))
2281 if sys.version_info < (3,):
2282 self.assertEqual(sorted(dic.iteritems()),
2283 sorted(expected.iteritems()))
2284 self.assertEqual(sorted(dic.keys()),
2285 sorted(expected.keys()))
2286 if sys.version_info < (3,):
2287 self.assertEqual(sorted(dic.iterkeys()),
2288 sorted(expected.iterkeys()))
2289 if sys.version_info < (3,):
2290 self.assertEqual(sorted(dic.values()),
2291 sorted(expected.values()))
2292 self.assertEqual(sorted(dic.itervalues()),
2293 sorted(expected.itervalues()))
2294
2296 etree = self.etree
2297
2298 r = {'foo': 'http://ns.infrae.com/foo'}
2299 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2300 self.assertEqual(
2301 'foo',
2302 e.prefix)
2303 self.assertEqual(
2304 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2305 self._writeElement(e))
2306
2308 etree = self.etree
2309
2310 r = {None: 'http://ns.infrae.com/foo'}
2311 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2312 self.assertEqual(
2313 None,
2314 e.prefix)
2315 self.assertEqual(
2316 '{http://ns.infrae.com/foo}bar',
2317 e.tag)
2318 self.assertEqual(
2319 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2320 self._writeElement(e))
2321
2323 etree = self.etree
2324
2325 r = {None: 'http://ns.infrae.com/foo',
2326 'hoi': 'http://ns.infrae.com/hoi'}
2327 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2328 e.set('{http://ns.infrae.com/hoi}test', 'value')
2329 self.assertEqual(
2330 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2331 self._writeElement(e))
2332
2334 etree = self.etree
2335
2336 root = etree.Element('{http://test/ns}root',
2337 nsmap={None: 'http://test/ns'})
2338 sub = etree.Element('{http://test/ns}sub',
2339 nsmap={'test': 'http://test/ns'})
2340
2341 sub.attrib['{http://test/ns}attr'] = 'value'
2342 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2343 self.assertEqual(
2344 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2345 etree.tostring(sub))
2346
2347 root.append(sub)
2348 self.assertEqual(
2349 _bytes('<root xmlns="http://test/ns">'
2350 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2351 '</root>'),
2352 etree.tostring(root))
2353
2355 etree = self.etree
2356
2357 root = etree.Element('root')
2358 sub = etree.Element('{http://test/ns}sub',
2359 nsmap={'test': 'http://test/ns'})
2360
2361 sub.attrib['{http://test/ns}attr'] = 'value'
2362 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2363 self.assertEqual(
2364 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2365 etree.tostring(sub))
2366
2367 root.append(sub)
2368 self.assertEqual(
2369 _bytes('<root>'
2370 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2371 '</root>'),
2372 etree.tostring(root))
2373
2375 etree = self.etree
2376
2377 root = etree.Element('root')
2378 sub = etree.Element('{http://test/ns}sub',
2379 nsmap={None: 'http://test/ns'})
2380
2381 sub.attrib['{http://test/ns}attr'] = 'value'
2382 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2383 self.assertEqual(
2384 _bytes('<sub xmlns="http://test/ns" '
2385 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2386 etree.tostring(sub))
2387
2388 root.append(sub)
2389 self.assertEqual(
2390 _bytes('<root>'
2391 '<sub xmlns="http://test/ns"'
2392 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2393 '</root>'),
2394 etree.tostring(root))
2395
2397 etree = self.etree
2398
2399 root = etree.Element('{http://test/ns}root',
2400 nsmap={'test': 'http://test/ns',
2401 None: 'http://test/ns'})
2402 sub = etree.Element('{http://test/ns}sub',
2403 nsmap={None: 'http://test/ns'})
2404
2405 sub.attrib['{http://test/ns}attr'] = 'value'
2406 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2407 self.assertEqual(
2408 _bytes('<sub xmlns="http://test/ns" '
2409 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2410 etree.tostring(sub))
2411
2412 root.append(sub)
2413 self.assertEqual(
2414 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2415 '<test:sub test:attr="value"/>'
2416 '</test:root>'),
2417 etree.tostring(root))
2418
2420 etree = self.etree
2421 r = {None: 'http://ns.infrae.com/foo',
2422 'hoi': 'http://ns.infrae.com/hoi'}
2423 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2424 tree = etree.ElementTree(element=e)
2425 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2426 self.assertEqual(
2427 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2428 self._writeElement(e))
2429
2431 etree = self.etree
2432
2433 r = {None: 'http://ns.infrae.com/foo'}
2434 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2435 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2436
2437 e1.append(e2)
2438
2439 self.assertEqual(
2440 None,
2441 e1.prefix)
2442 self.assertEqual(
2443 None,
2444 e1[0].prefix)
2445 self.assertEqual(
2446 '{http://ns.infrae.com/foo}bar',
2447 e1.tag)
2448 self.assertEqual(
2449 '{http://ns.infrae.com/foo}bar',
2450 e1[0].tag)
2451
2453 etree = self.etree
2454
2455 r = {None: 'http://ns.infrae.com/BAR'}
2456 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2457 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2458
2459 e1.append(e2)
2460
2461 self.assertEqual(
2462 None,
2463 e1.prefix)
2464 self.assertNotEqual(
2465 None,
2466 e2.prefix)
2467 self.assertEqual(
2468 '{http://ns.infrae.com/BAR}bar',
2469 e1.tag)
2470 self.assertEqual(
2471 '{http://ns.infrae.com/foo}bar',
2472 e2.tag)
2473
2475 ns_href = "http://a.b.c"
2476 one = self.etree.fromstring(
2477 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2478 baz = one[0][0]
2479
2480 two = self.etree.fromstring(
2481 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2482 two.append(baz)
2483 del one
2484
2485 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2486 self.assertEqual(
2487 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2488 self.etree.tostring(two))
2489
2499
2501 etree = self.etree
2502
2503 r = {None: 'http://ns.infrae.com/foo',
2504 'hoi': 'http://ns.infrae.com/hoi'}
2505 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2506 self.assertEqual(
2507 r,
2508 e.nsmap)
2509
2511 etree = self.etree
2512
2513 re = {None: 'http://ns.infrae.com/foo',
2514 'hoi': 'http://ns.infrae.com/hoi'}
2515 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2516
2517 rs = {None: 'http://ns.infrae.com/honk',
2518 'top': 'http://ns.infrae.com/top'}
2519 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2520
2521 r = re.copy()
2522 r.update(rs)
2523 self.assertEqual(re, e.nsmap)
2524 self.assertEqual(r, s.nsmap)
2525
2527 etree = self.etree
2528 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2529 self.assertEqual({'hha': None}, el.nsmap)
2530
2532 Element = self.etree.Element
2533 SubElement = self.etree.SubElement
2534
2535 a = Element('a')
2536 b = SubElement(a, 'b')
2537 c = SubElement(a, 'c')
2538 d = SubElement(b, 'd')
2539 e = SubElement(c, 'e')
2540 f = SubElement(c, 'f')
2541
2542 self.assertEqual(
2543 [a, b],
2544 list(a.getiterator('a', 'b')))
2545 self.assertEqual(
2546 [],
2547 list(a.getiterator('x', 'y')))
2548 self.assertEqual(
2549 [a, f],
2550 list(a.getiterator('f', 'a')))
2551 self.assertEqual(
2552 [c, e, f],
2553 list(c.getiterator('c', '*', 'a')))
2554 self.assertEqual(
2555 [],
2556 list(a.getiterator( (), () )))
2557
2559 Element = self.etree.Element
2560 SubElement = self.etree.SubElement
2561
2562 a = Element('a')
2563 b = SubElement(a, 'b')
2564 c = SubElement(a, 'c')
2565 d = SubElement(b, 'd')
2566 e = SubElement(c, 'e')
2567 f = SubElement(c, 'f')
2568
2569 self.assertEqual(
2570 [a, b],
2571 list(a.getiterator( ('a', 'b') )))
2572 self.assertEqual(
2573 [],
2574 list(a.getiterator( ('x', 'y') )))
2575 self.assertEqual(
2576 [a, f],
2577 list(a.getiterator( ('f', 'a') )))
2578 self.assertEqual(
2579 [c, e, f],
2580 list(c.getiterator( ('c', '*', 'a') )))
2581 self.assertEqual(
2582 [],
2583 list(a.getiterator( () )))
2584
2586 Element = self.etree.Element
2587 SubElement = self.etree.SubElement
2588
2589 a = Element('{a}a')
2590 b = SubElement(a, '{a}b')
2591 c = SubElement(a, '{a}c')
2592 d = SubElement(b, '{b}d')
2593 e = SubElement(c, '{a}e')
2594 f = SubElement(c, '{b}f')
2595 g = SubElement(c, 'g')
2596
2597 self.assertEqual(
2598 [a],
2599 list(a.getiterator('{a}a')))
2600 self.assertEqual(
2601 [],
2602 list(a.getiterator('{b}a')))
2603 self.assertEqual(
2604 [],
2605 list(a.getiterator('a')))
2606 self.assertEqual(
2607 [a,b,d,c,e,f,g],
2608 list(a.getiterator('*')))
2609 self.assertEqual(
2610 [f],
2611 list(c.getiterator('{b}*')))
2612 self.assertEqual(
2613 [d, f],
2614 list(a.getiterator('{b}*')))
2615 self.assertEqual(
2616 [g],
2617 list(a.getiterator('g')))
2618 self.assertEqual(
2619 [g],
2620 list(a.getiterator('{}g')))
2621 self.assertEqual(
2622 [g],
2623 list(a.getiterator('{}*')))
2624
2626 Element = self.etree.Element
2627 SubElement = self.etree.SubElement
2628
2629 a = Element('{a}a')
2630 b = SubElement(a, '{nsA}b')
2631 c = SubElement(b, '{nsB}b')
2632 d = SubElement(a, 'b')
2633 e = SubElement(a, '{nsA}e')
2634 f = SubElement(e, '{nsB}e')
2635 g = SubElement(e, 'e')
2636
2637 self.assertEqual(
2638 [b, c, d],
2639 list(a.getiterator('{*}b')))
2640 self.assertEqual(
2641 [e, f, g],
2642 list(a.getiterator('{*}e')))
2643 self.assertEqual(
2644 [a, b, c, d, e, f, g],
2645 list(a.getiterator('{*}*')))
2646
2671
2687
2704
2711
2718
2727
2729 XML = self.etree.XML
2730 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2731 self.assertEqual(len(root.findall(".//{X}b")), 2)
2732 self.assertEqual(len(root.findall(".//{X}*")), 2)
2733 self.assertEqual(len(root.findall(".//b")), 3)
2734
2736 XML = self.etree.XML
2737 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2738 nsmap = {'xx': 'X'}
2739 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2740 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2741 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2742 nsmap = {'xx': 'Y'}
2743 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2744 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2745 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2746
2748 XML = self.etree.XML
2749 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2750 nsmap = {'xx': 'X'}
2751 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2752 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2753 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2754 nsmap = {'xx': 'Y'}
2755 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2756 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2757 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2758
2765
2767 etree = self.etree
2768 e = etree.Element('foo')
2769 for i in range(10):
2770 etree.SubElement(e, 'a%s' % i)
2771 for i in range(10):
2772 self.assertEqual(
2773 i,
2774 e.index(e[i]))
2775 self.assertEqual(
2776 3, e.index(e[3], 3))
2777 self.assertRaises(
2778 ValueError, e.index, e[3], 4)
2779 self.assertRaises(
2780 ValueError, e.index, e[3], 0, 2)
2781 self.assertRaises(
2782 ValueError, e.index, e[8], 0, -3)
2783 self.assertRaises(
2784 ValueError, e.index, e[8], -5, -3)
2785 self.assertEqual(
2786 8, e.index(e[8], 0, -1))
2787 self.assertEqual(
2788 8, e.index(e[8], -12, -1))
2789 self.assertEqual(
2790 0, e.index(e[0], -12, -1))
2791
2793 etree = self.etree
2794 e = etree.Element('foo')
2795 for i in range(10):
2796 el = etree.SubElement(e, 'a%s' % i)
2797 el.text = "text%d" % i
2798 el.tail = "tail%d" % i
2799
2800 child0 = e[0]
2801 child1 = e[1]
2802 child2 = e[2]
2803
2804 e.replace(e[0], e[1])
2805 self.assertEqual(
2806 9, len(e))
2807 self.assertEqual(
2808 child1, e[0])
2809 self.assertEqual(
2810 child1.text, "text1")
2811 self.assertEqual(
2812 child1.tail, "tail1")
2813 self.assertEqual(
2814 child0.tail, "tail0")
2815 self.assertEqual(
2816 child2, e[1])
2817
2818 e.replace(e[-1], e[0])
2819 self.assertEqual(
2820 child1, e[-1])
2821 self.assertEqual(
2822 child1.text, "text1")
2823 self.assertEqual(
2824 child1.tail, "tail1")
2825 self.assertEqual(
2826 child2, e[0])
2827
2829 etree = self.etree
2830 e = etree.Element('foo')
2831 for i in range(10):
2832 etree.SubElement(e, 'a%s' % i)
2833
2834 new_element = etree.Element("test")
2835 new_element.text = "TESTTEXT"
2836 new_element.tail = "TESTTAIL"
2837 child1 = e[1]
2838 e.replace(e[0], new_element)
2839 self.assertEqual(
2840 new_element, e[0])
2841 self.assertEqual(
2842 "TESTTEXT",
2843 e[0].text)
2844 self.assertEqual(
2845 "TESTTAIL",
2846 e[0].tail)
2847 self.assertEqual(
2848 child1, e[1])
2849
2865
2883
2901
2919
2921 Element = self.etree.Element
2922 SubElement = self.etree.SubElement
2923 try:
2924 slice
2925 except NameError:
2926 print("slice() not found")
2927 return
2928
2929 a = Element('a')
2930 b = SubElement(a, 'b')
2931 c = SubElement(a, 'c')
2932 d = SubElement(a, 'd')
2933 e = SubElement(a, 'e')
2934
2935 x = Element('x')
2936 y = Element('y')
2937 z = Element('z')
2938
2939 self.assertRaises(
2940 ValueError,
2941 operator.setitem, a, slice(1,None,2), [x, y, z])
2942
2943 self.assertEqual(
2944 [b, c, d, e],
2945 list(a))
2946
2959
2961 XML = self.etree.XML
2962 root = XML(_bytes(
2963 '<?xml version="1.0"?>\n'
2964 '<root>' + '\n' * 65536 +
2965 '<p>' + '\n' * 65536 + '</p>\n' +
2966 '<br/>\n'
2967 '</root>'))
2968
2969 if self.etree.LIBXML_VERSION >= (2, 9):
2970 expected = [2, 131074, 131076]
2971 else:
2972 expected = [2, 65535, 65535]
2973
2974 self.assertEqual(expected, [el.sourceline for el in root.iter()])
2975
2983
2992
3002
3012
3018
3026
3032
3039
3045
3047 etree = self.etree
3048 xml_header = '<?xml version="1.0" encoding="ascii"?>'
3049 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3050 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3051 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
3052
3053 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3054
3055 tree = etree.parse(BytesIO(xml))
3056 docinfo = tree.docinfo
3057 self.assertEqual(docinfo.encoding, "ascii")
3058 self.assertEqual(docinfo.xml_version, "1.0")
3059 self.assertEqual(docinfo.public_id, pub_id)
3060 self.assertEqual(docinfo.system_url, sys_id)
3061 self.assertEqual(docinfo.root_name, 'html')
3062 self.assertEqual(docinfo.doctype, doctype_string)
3063
3079
3091
3103
3109
3111 etree = self.etree
3112 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3113 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3114 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
3115
3116 xml = _bytes('<!DOCTYPE root>\n<root/>')
3117 tree = etree.parse(BytesIO(xml))
3118 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
3119 etree.tostring(tree, doctype=doctype_string))
3120
3122 etree = self.etree
3123 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3124 self.assertEqual(root.base, "http://no/such/url")
3125 self.assertEqual(
3126 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3127 root.base = "https://secret/url"
3128 self.assertEqual(root.base, "https://secret/url")
3129 self.assertEqual(
3130 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3131 "https://secret/url")
3132
3134 etree = self.etree
3135 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3136 self.assertEqual(root.base, "http://no/such/url")
3137 self.assertEqual(
3138 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3139 root.set('{http://www.w3.org/XML/1998/namespace}base',
3140 "https://secret/url")
3141 self.assertEqual(root.base, "https://secret/url")
3142 self.assertEqual(
3143 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3144 "https://secret/url")
3145
3151
3156
3163
3177
3179 Element = self.etree.Element
3180
3181 a = Element('a')
3182 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3183 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3184
3185 self.assertRaises(ValueError, Element, 'ha\0ho')
3186
3188 Element = self.etree.Element
3189
3190 a = Element('a')
3191 self.assertRaises(ValueError, setattr, a, "text",
3192 _str('ha\0ho'))
3193 self.assertRaises(ValueError, setattr, a, "tail",
3194 _str('ha\0ho'))
3195
3196 self.assertRaises(ValueError, Element,
3197 _str('ha\0ho'))
3198
3200 Element = self.etree.Element
3201
3202 a = Element('a')
3203 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3204 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3205
3206 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3207 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3208
3209 self.assertRaises(ValueError, Element, 'ha\x07ho')
3210 self.assertRaises(ValueError, Element, 'ha\x02ho')
3211
3213 Element = self.etree.Element
3214
3215 a = Element('a')
3216 self.assertRaises(ValueError, setattr, a, "text",
3217 _str('ha\x07ho'))
3218 self.assertRaises(ValueError, setattr, a, "text",
3219 _str('ha\x02ho'))
3220
3221 self.assertRaises(ValueError, setattr, a, "tail",
3222 _str('ha\x07ho'))
3223 self.assertRaises(ValueError, setattr, a, "tail",
3224 _str('ha\x02ho'))
3225
3226 self.assertRaises(ValueError, Element,
3227 _str('ha\x07ho'))
3228 self.assertRaises(ValueError, Element,
3229 _str('ha\x02ho'))
3230
3232 Element = self.etree.Element
3233
3234 a = Element('a')
3235 self.assertRaises(ValueError, setattr, a, "text",
3236 _str('ha\u1234\x07ho'))
3237 self.assertRaises(ValueError, setattr, a, "text",
3238 _str('ha\u1234\x02ho'))
3239
3240 self.assertRaises(ValueError, setattr, a, "tail",
3241 _str('ha\u1234\x07ho'))
3242 self.assertRaises(ValueError, setattr, a, "tail",
3243 _str('ha\u1234\x02ho'))
3244
3245 self.assertRaises(ValueError, Element,
3246 _str('ha\u1234\x07ho'))
3247 self.assertRaises(ValueError, Element,
3248 _str('ha\u1234\x02ho'))
3249
3263
3268
3286
3306
3308 tostring = self.etree.tostring
3309 html = self.etree.fromstring(
3310 '<html><body>'
3311 '<div><p>Some text<i>\r\n</i></p></div>\r\n'
3312 '</body></html>',
3313 parser=self.etree.HTMLParser())
3314 self.assertEqual(html.tag, 'html')
3315 div = html.find('.//div')
3316 self.assertEqual(div.tail, '\r\n')
3317 result = tostring(div, method='html')
3318 self.assertEqual(
3319 result,
3320 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3321 result = tostring(div, method='html', with_tail=True)
3322 self.assertEqual(
3323 result,
3324 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3325 result = tostring(div, method='html', with_tail=False)
3326 self.assertEqual(
3327 result,
3328 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3329
3351
3353 tostring = self.etree.tostring
3354 XML = self.etree.XML
3355 ElementTree = self.etree.ElementTree
3356
3357 root = XML(_bytes("<root/>"))
3358
3359 tree = ElementTree(root)
3360 self.assertEqual(None, tree.docinfo.standalone)
3361
3362 result = tostring(root, xml_declaration=True, encoding="ASCII")
3363 self.assertEqual(result, _bytes(
3364 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3365
3366 result = tostring(root, xml_declaration=True, encoding="ASCII",
3367 standalone=True)
3368 self.assertEqual(result, _bytes(
3369 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3370
3371 tree = ElementTree(XML(result))
3372 self.assertEqual(True, tree.docinfo.standalone)
3373
3374 result = tostring(root, xml_declaration=True, encoding="ASCII",
3375 standalone=False)
3376 self.assertEqual(result, _bytes(
3377 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3378
3379 tree = ElementTree(XML(result))
3380 self.assertEqual(False, tree.docinfo.standalone)
3381
3401
3403 tostring = self.etree.tostring
3404 Element = self.etree.Element
3405 SubElement = self.etree.SubElement
3406
3407 a = Element('a')
3408 a.text = "A"
3409 a.tail = "tail"
3410 b = SubElement(a, 'b')
3411 b.text = "B"
3412 b.tail = _str("Søk på nettet")
3413 c = SubElement(a, 'c')
3414 c.text = "C"
3415
3416 result = tostring(a, method="text", encoding="UTF-16")
3417
3418 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3419 result)
3420
3422 tostring = self.etree.tostring
3423 Element = self.etree.Element
3424 SubElement = self.etree.SubElement
3425
3426 a = Element('a')
3427 a.text = _str('Søk på nettetA')
3428 a.tail = "tail"
3429 b = SubElement(a, 'b')
3430 b.text = "B"
3431 b.tail = _str('Søk på nettetB')
3432 c = SubElement(a, 'c')
3433 c.text = "C"
3434
3435 self.assertRaises(UnicodeEncodeError,
3436 tostring, a, method="text")
3437
3438 self.assertEqual(
3439 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3440 tostring(a, encoding="UTF-8", method="text"))
3441
3454
3470
3474
3489
3507
3520
3522 tostring = self.etree.tostring
3523 Element = self.etree.Element
3524 SubElement = self.etree.SubElement
3525
3526 a = Element('a')
3527 b = SubElement(a, 'b')
3528 c = SubElement(a, 'c')
3529 d = SubElement(c, 'd')
3530 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3531 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3532 self.assertEqual(_bytes('<b></b>'),
3533 canonicalize(tostring(b, encoding=_unicode)))
3534 self.assertEqual(_bytes('<c><d></d></c>'),
3535 canonicalize(tostring(c, encoding=_unicode)))
3536
3541
3556
3558 tostring = self.etree.tostring
3559 Element = self.etree.Element
3560 SubElement = self.etree.SubElement
3561
3562 a = Element('a')
3563 b = SubElement(a, 'b')
3564 c = SubElement(a, 'c')
3565
3566 result = tostring(a, encoding=_unicode)
3567 self.assertEqual(result, "<a><b/><c/></a>")
3568
3569 result = tostring(a, encoding=_unicode, pretty_print=False)
3570 self.assertEqual(result, "<a><b/><c/></a>")
3571
3572 result = tostring(a, encoding=_unicode, pretty_print=True)
3573 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3574
3586
3588 class SubEl(etree.ElementBase):
3589 pass
3590
3591 el1 = SubEl()
3592 el2 = SubEl()
3593 self.assertEqual('SubEl', el1.tag)
3594 self.assertEqual('SubEl', el2.tag)
3595 el1.other = el2
3596 el2.other = el1
3597
3598 del el1, el2
3599 gc.collect()
3600
3601
3615
3617 root = etree.Element('parent')
3618 c1 = etree.SubElement(root, 'child1')
3619 c2 = etree.SubElement(root, 'child2')
3620
3621 root.remove(c1)
3622 root.remove(c2)
3623 c1.addnext(c2)
3624 c1.tail = 'abc'
3625 c2.tail = 'xyz'
3626 del c1
3627
3628 c2.getprevious()
3629
3630 self.assertEqual('child1', c2.getprevious().tag)
3631 self.assertEqual('abc', c2.getprevious().tail)
3632
3633
3634
3635 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3646
3647
3691
3692 res_instance = res()
3693 parser = etree.XMLParser(load_dtd = True)
3694 parser.resolvers.add(res_instance)
3695
3696 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3697 parser = parser)
3698
3699 self.include(tree)
3700
3701 called = list(res_instance.called.items())
3702 called.sort()
3703 self.assertEqual(
3704 [("dtd", True), ("include", True), ("input", True)],
3705 called)
3706
3707
3711
3712
3717
3718
3721 tree = self.parse(_bytes('<a><b/></a>'))
3722 f = BytesIO()
3723 tree.write_c14n(f)
3724 s = f.getvalue()
3725 self.assertEqual(_bytes('<a><b></b></a>'),
3726 s)
3727
3729 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3730 f = BytesIO()
3731 tree.write_c14n(f, compression=9)
3732 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3733 try:
3734 s = gzfile.read()
3735 finally:
3736 gzfile.close()
3737 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3738 s)
3739
3751
3767
3785
3797
3809
3811 tree = self.parse(_bytes(
3812 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3813 f = BytesIO()
3814 tree.write_c14n(f)
3815 s = f.getvalue()
3816 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3817 s)
3818 f = BytesIO()
3819 tree.write_c14n(f, exclusive=False)
3820 s = f.getvalue()
3821 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3822 s)
3823 f = BytesIO()
3824 tree.write_c14n(f, exclusive=True)
3825 s = f.getvalue()
3826 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3827 s)
3828
3829 f = BytesIO()
3830 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
3831 s = f.getvalue()
3832 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
3833 s)
3834
3836 tree = self.parse(_bytes(
3837 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3838 s = etree.tostring(tree, method='c14n')
3839 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3840 s)
3841 s = etree.tostring(tree, method='c14n', exclusive=False)
3842 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3843 s)
3844 s = etree.tostring(tree, method='c14n', exclusive=True)
3845 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3846 s)
3847
3848 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3849 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
3850 s)
3851
3853 tree = self.parse(_bytes(
3854 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3855 s = etree.tostring(tree.getroot(), method='c14n')
3856 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3857 s)
3858 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3859 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3860 s)
3861 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3862 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3863 s)
3864
3865 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3866 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3867 s)
3868 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3869 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3870 s)
3871
3872 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3873 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3874 s)
3875
3877 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
3878 tree = self.parse(_bytes(
3879 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3880
3881 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
3882 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3883 s)
3884
3885
3888 tree = self.parse(_bytes('<a><b/></a>'))
3889 f = BytesIO()
3890 tree.write(f)
3891 s = f.getvalue()
3892 self.assertEqual(_bytes('<a><b/></a>'),
3893 s)
3894
3896 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3897 f = BytesIO()
3898 tree.write(f, compression=9)
3899 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3900 try:
3901 s = gzfile.read()
3902 finally:
3903 gzfile.close()
3904 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3905 s)
3906
3908 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3909 f = BytesIO()
3910 tree.write(f, compression=0)
3911 s0 = f.getvalue()
3912
3913 f = BytesIO()
3914 tree.write(f)
3915 self.assertEqual(f.getvalue(), s0)
3916
3917 f = BytesIO()
3918 tree.write(f, compression=1)
3919 s = f.getvalue()
3920 self.assertTrue(len(s) <= len(s0))
3921 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3922 try:
3923 s1 = gzfile.read()
3924 finally:
3925 gzfile.close()
3926
3927 f = BytesIO()
3928 tree.write(f, compression=9)
3929 s = f.getvalue()
3930 self.assertTrue(len(s) <= len(s0))
3931 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3932 try:
3933 s9 = gzfile.read()
3934 finally:
3935 gzfile.close()
3936
3937 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3938 s0)
3939 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3940 s1)
3941 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3942 s9)
3943
3955
3971
3983
3996
3998 etree = etree
3999
4021
4023 """This can't really be tested as long as there isn't a way to
4024 reset the logging setup ...
4025 """
4026 parse = self.etree.parse
4027
4028 messages = []
4029 class Logger(self.etree.PyErrorLog):
4030 def log(self, entry, message, *args):
4031 messages.append(message)
4032
4033 self.etree.use_global_python_log(Logger())
4034 f = BytesIO('<a><b></c></b></a>')
4035 try:
4036 parse(f)
4037 except SyntaxError:
4038 pass
4039 f.close()
4040
4041 self.assertTrue([ message for message in messages
4042 if 'mismatch' in message ])
4043 self.assertTrue([ message for message in messages
4044 if ':PARSER:' in message])
4045 self.assertTrue([ message for message in messages
4046 if ':ERR_TAG_NAME_MISMATCH:' in message ])
4047 self.assertTrue([ message for message in messages
4048 if ':1:15:' in message ])
4049
4050
4052 etree = etree
4053
4057
4059 class Target(object):
4060 def start(self, tag, attrib):
4061 return 'start(%s)' % tag
4062 def end(self, tag):
4063 return 'end(%s)' % tag
4064 def close(self):
4065 return 'close()'
4066
4067 parser = self.etree.XMLPullParser(target=Target())
4068 events = parser.read_events()
4069
4070 parser.feed('<root><element>')
4071 self.assertFalse(list(events))
4072 self.assertFalse(list(events))
4073 parser.feed('</element><child>')
4074 self.assertEqual([('end', 'end(element)')], list(events))
4075 parser.feed('</child>')
4076 self.assertEqual([('end', 'end(child)')], list(events))
4077 parser.feed('</root>')
4078 self.assertEqual([('end', 'end(root)')], list(events))
4079 self.assertFalse(list(events))
4080 self.assertEqual('close()', parser.close())
4081
4083 class Target(object):
4084 def start(self, tag, attrib):
4085 return 'start(%s)' % tag
4086 def end(self, tag):
4087 return 'end(%s)' % tag
4088 def close(self):
4089 return 'close()'
4090
4091 parser = self.etree.XMLPullParser(
4092 ['start', 'end'], target=Target())
4093 events = parser.read_events()
4094
4095 parser.feed('<root><element>')
4096 self.assertEqual(
4097 [('start', 'start(root)'), ('start', 'start(element)')],
4098 list(events))
4099 self.assertFalse(list(events))
4100 parser.feed('</element><child>')
4101 self.assertEqual(
4102 [('end', 'end(element)'), ('start', 'start(child)')],
4103 list(events))
4104 parser.feed('</child>')
4105 self.assertEqual(
4106 [('end', 'end(child)')],
4107 list(events))
4108 parser.feed('</root>')
4109 self.assertEqual(
4110 [('end', 'end(root)')],
4111 list(events))
4112 self.assertFalse(list(events))
4113 self.assertEqual('close()', parser.close())
4114
4116 parser = self.etree.XMLPullParser(
4117 ['start', 'end'], target=etree.TreeBuilder())
4118 events = parser.read_events()
4119
4120 parser.feed('<root><element>')
4121 self.assert_event_tags(
4122 events, [('start', 'root'), ('start', 'element')])
4123 self.assertFalse(list(events))
4124 parser.feed('</element><child>')
4125 self.assert_event_tags(
4126 events, [('end', 'element'), ('start', 'child')])
4127 parser.feed('</child>')
4128 self.assert_event_tags(
4129 events, [('end', 'child')])
4130 parser.feed('</root>')
4131 self.assert_event_tags(
4132 events, [('end', 'root')])
4133 self.assertFalse(list(events))
4134 root = parser.close()
4135 self.assertEqual('root', root.tag)
4136
4138 class Target(etree.TreeBuilder):
4139 def end(self, tag):
4140 el = super(Target, self).end(tag)
4141 el.tag += '-huhu'
4142 return el
4143
4144 parser = self.etree.XMLPullParser(
4145 ['start', 'end'], target=Target())
4146 events = parser.read_events()
4147
4148 parser.feed('<root><element>')
4149 self.assert_event_tags(
4150 events, [('start', 'root'), ('start', 'element')])
4151 self.assertFalse(list(events))
4152 parser.feed('</element><child>')
4153 self.assert_event_tags(
4154 events, [('end', 'element-huhu'), ('start', 'child')])
4155 parser.feed('</child>')
4156 self.assert_event_tags(
4157 events, [('end', 'child-huhu')])
4158 parser.feed('</root>')
4159 self.assert_event_tags(
4160 events, [('end', 'root-huhu')])
4161 self.assertFalse(list(events))
4162 root = parser.close()
4163 self.assertEqual('root-huhu', root.tag)
4164
4165
4189
4190 if __name__ == '__main__':
4191 print('to test use test.py %s' % __file__)
4192