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
1508
1524
1530
1545
1558
1573
1586
1601
1614
1629
1642
1643
1651
1652
1662
1663
1678
1679
1689
1690
1701
1728
1729
1731 self.assertRaises(TypeError, self.etree.dump, None)
1732
1745
1758
1779
1788
1797
1806
1815
1824
1826 XML = self.etree.XML
1827
1828 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1829 result = []
1830 for el in root.iterchildren(tag=['two', 'three']):
1831 result.append(el.text)
1832 self.assertEqual(['Two', 'Bla', None], result)
1833
1835 XML = self.etree.XML
1836
1837 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1838 result = []
1839 for el in root.iterchildren('two', 'three'):
1840 result.append(el.text)
1841 self.assertEqual(['Two', 'Bla', None], result)
1842
1851
1872
1894
1896 Element = self.etree.Element
1897 SubElement = self.etree.SubElement
1898
1899 a = Element('a')
1900 b = SubElement(a, 'b')
1901 c = SubElement(a, 'c')
1902 d = SubElement(b, 'd')
1903 self.assertEqual(
1904 [b, a],
1905 list(d.iterancestors(tag=('a', 'b'))))
1906 self.assertEqual(
1907 [b, a],
1908 list(d.iterancestors('a', 'b')))
1909
1910 self.assertEqual(
1911 [],
1912 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
1913 self.assertEqual(
1914 [],
1915 list(d.iterancestors('w', 'x', 'y', 'z')))
1916
1917 self.assertEqual(
1918 [],
1919 list(d.iterancestors(tag=('d', 'x'))))
1920 self.assertEqual(
1921 [],
1922 list(d.iterancestors('d', 'x')))
1923
1924 self.assertEqual(
1925 [b, a],
1926 list(d.iterancestors(tag=('b', '*'))))
1927 self.assertEqual(
1928 [b, a],
1929 list(d.iterancestors('b', '*')))
1930
1931 self.assertEqual(
1932 [b],
1933 list(d.iterancestors(tag=('b', 'c'))))
1934 self.assertEqual(
1935 [b],
1936 list(d.iterancestors('b', 'c')))
1937
1954
1956 Element = self.etree.Element
1957 SubElement = self.etree.SubElement
1958
1959 a = Element('a')
1960 b = SubElement(a, 'b')
1961 c = SubElement(a, 'c')
1962 d = SubElement(b, 'd')
1963 e = SubElement(c, 'e')
1964
1965 self.assertEqual(
1966 [],
1967 list(a.iterdescendants('a')))
1968 self.assertEqual(
1969 [],
1970 list(a.iterdescendants(tag='a')))
1971
1972 a2 = SubElement(e, 'a')
1973 self.assertEqual(
1974 [a2],
1975 list(a.iterdescendants('a')))
1976
1977 self.assertEqual(
1978 [a2],
1979 list(c.iterdescendants('a')))
1980 self.assertEqual(
1981 [a2],
1982 list(c.iterdescendants(tag='a')))
1983
1985 Element = self.etree.Element
1986 SubElement = self.etree.SubElement
1987
1988 a = Element('a')
1989 b = SubElement(a, 'b')
1990 c = SubElement(a, 'c')
1991 d = SubElement(b, 'd')
1992 e = SubElement(c, 'e')
1993
1994 self.assertEqual(
1995 [b, e],
1996 list(a.iterdescendants(tag=('a', 'b', 'e'))))
1997 self.assertEqual(
1998 [b, e],
1999 list(a.iterdescendants('a', 'b', 'e')))
2000
2001 a2 = SubElement(e, 'a')
2002 self.assertEqual(
2003 [b, a2],
2004 list(a.iterdescendants(tag=('a', 'b'))))
2005 self.assertEqual(
2006 [b, a2],
2007 list(a.iterdescendants('a', 'b')))
2008
2009 self.assertEqual(
2010 [],
2011 list(c.iterdescendants(tag=('x', 'y', 'z'))))
2012 self.assertEqual(
2013 [],
2014 list(c.iterdescendants('x', 'y', 'z')))
2015
2016 self.assertEqual(
2017 [b, d, c, e, a2],
2018 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
2019 self.assertEqual(
2020 [b, d, c, e, a2],
2021 list(a.iterdescendants('x', 'y', 'z', '*')))
2022
2040
2057
2075
2099
2101 Element = self.etree.Element
2102 SubElement = self.etree.SubElement
2103
2104 a = Element('a')
2105 b = SubElement(a, 'b')
2106 c = SubElement(a, 'c')
2107 d = SubElement(b, 'd')
2108 self.assertEqual(
2109 [],
2110 list(a.itersiblings(tag='XXX')))
2111 self.assertEqual(
2112 [c],
2113 list(b.itersiblings(tag='c')))
2114 self.assertEqual(
2115 [c],
2116 list(b.itersiblings(tag='*')))
2117 self.assertEqual(
2118 [b],
2119 list(c.itersiblings(preceding=True, tag='b')))
2120 self.assertEqual(
2121 [],
2122 list(c.itersiblings(preceding=True, tag='c')))
2123
2125 Element = self.etree.Element
2126 SubElement = self.etree.SubElement
2127
2128 a = Element('a')
2129 b = SubElement(a, 'b')
2130 c = SubElement(a, 'c')
2131 d = SubElement(b, 'd')
2132 e = SubElement(a, 'e')
2133 self.assertEqual(
2134 [],
2135 list(a.itersiblings(tag=('XXX', 'YYY'))))
2136 self.assertEqual(
2137 [c, e],
2138 list(b.itersiblings(tag=('c', 'd', 'e'))))
2139 self.assertEqual(
2140 [b],
2141 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2142 self.assertEqual(
2143 [c, b],
2144 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2145
2147 parseid = self.etree.parseid
2148 XML = self.etree.XML
2149 xml_text = _bytes('''
2150 <!DOCTYPE document [
2151 <!ELEMENT document (h1,p)*>
2152 <!ELEMENT h1 (#PCDATA)>
2153 <!ATTLIST h1 myid ID #REQUIRED>
2154 <!ELEMENT p (#PCDATA)>
2155 <!ATTLIST p someid ID #REQUIRED>
2156 ]>
2157 <document>
2158 <h1 myid="chapter1">...</h1>
2159 <p id="note1" class="note">...</p>
2160 <p>Regular paragraph.</p>
2161 <p xml:id="xmlid">XML:ID paragraph.</p>
2162 <p someid="warn1" class="warning">...</p>
2163 </document>
2164 ''')
2165
2166 tree, dic = parseid(BytesIO(xml_text))
2167 root = tree.getroot()
2168 root2 = XML(xml_text)
2169 self.assertEqual(self._writeElement(root),
2170 self._writeElement(root2))
2171 expected = {
2172 "chapter1" : root[0],
2173 "xmlid" : root[3],
2174 "warn1" : root[4]
2175 }
2176 self.assertTrue("chapter1" in dic)
2177 self.assertTrue("warn1" in dic)
2178 self.assertTrue("xmlid" in dic)
2179 self._checkIDDict(dic, expected)
2180
2182 XMLDTDID = self.etree.XMLDTDID
2183 XML = self.etree.XML
2184 xml_text = _bytes('''
2185 <!DOCTYPE document [
2186 <!ELEMENT document (h1,p)*>
2187 <!ELEMENT h1 (#PCDATA)>
2188 <!ATTLIST h1 myid ID #REQUIRED>
2189 <!ELEMENT p (#PCDATA)>
2190 <!ATTLIST p someid ID #REQUIRED>
2191 ]>
2192 <document>
2193 <h1 myid="chapter1">...</h1>
2194 <p id="note1" class="note">...</p>
2195 <p>Regular paragraph.</p>
2196 <p xml:id="xmlid">XML:ID paragraph.</p>
2197 <p someid="warn1" class="warning">...</p>
2198 </document>
2199 ''')
2200
2201 root, dic = XMLDTDID(xml_text)
2202 root2 = XML(xml_text)
2203 self.assertEqual(self._writeElement(root),
2204 self._writeElement(root2))
2205 expected = {
2206 "chapter1" : root[0],
2207 "xmlid" : root[3],
2208 "warn1" : root[4]
2209 }
2210 self.assertTrue("chapter1" in dic)
2211 self.assertTrue("warn1" in dic)
2212 self.assertTrue("xmlid" in dic)
2213 self._checkIDDict(dic, expected)
2214
2216 XMLDTDID = self.etree.XMLDTDID
2217 XML = self.etree.XML
2218 xml_text = _bytes('''
2219 <document>
2220 <h1 myid="chapter1">...</h1>
2221 <p id="note1" class="note">...</p>
2222 <p>Regular paragraph.</p>
2223 <p someid="warn1" class="warning">...</p>
2224 </document>
2225 ''')
2226
2227 root, dic = XMLDTDID(xml_text)
2228 root2 = XML(xml_text)
2229 self.assertEqual(self._writeElement(root),
2230 self._writeElement(root2))
2231 expected = {}
2232 self._checkIDDict(dic, expected)
2233
2235 self.assertEqual(len(dic),
2236 len(expected))
2237 self.assertEqual(sorted(dic.items()),
2238 sorted(expected.items()))
2239 if sys.version_info < (3,):
2240 self.assertEqual(sorted(dic.iteritems()),
2241 sorted(expected.iteritems()))
2242 self.assertEqual(sorted(dic.keys()),
2243 sorted(expected.keys()))
2244 if sys.version_info < (3,):
2245 self.assertEqual(sorted(dic.iterkeys()),
2246 sorted(expected.iterkeys()))
2247 if sys.version_info < (3,):
2248 self.assertEqual(sorted(dic.values()),
2249 sorted(expected.values()))
2250 self.assertEqual(sorted(dic.itervalues()),
2251 sorted(expected.itervalues()))
2252
2254 etree = self.etree
2255
2256 r = {'foo': 'http://ns.infrae.com/foo'}
2257 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2258 self.assertEqual(
2259 'foo',
2260 e.prefix)
2261 self.assertEqual(
2262 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2263 self._writeElement(e))
2264
2266 etree = self.etree
2267
2268 r = {None: 'http://ns.infrae.com/foo'}
2269 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2270 self.assertEqual(
2271 None,
2272 e.prefix)
2273 self.assertEqual(
2274 '{http://ns.infrae.com/foo}bar',
2275 e.tag)
2276 self.assertEqual(
2277 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2278 self._writeElement(e))
2279
2281 etree = self.etree
2282
2283 r = {None: 'http://ns.infrae.com/foo',
2284 'hoi': 'http://ns.infrae.com/hoi'}
2285 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2286 e.set('{http://ns.infrae.com/hoi}test', 'value')
2287 self.assertEqual(
2288 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2289 self._writeElement(e))
2290
2292 etree = self.etree
2293
2294 root = etree.Element('{http://test/ns}root',
2295 nsmap={None: 'http://test/ns'})
2296 sub = etree.Element('{http://test/ns}sub',
2297 nsmap={'test': 'http://test/ns'})
2298
2299 sub.attrib['{http://test/ns}attr'] = 'value'
2300 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2301 self.assertEqual(
2302 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2303 etree.tostring(sub))
2304
2305 root.append(sub)
2306 self.assertEqual(
2307 _bytes('<root xmlns="http://test/ns">'
2308 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2309 '</root>'),
2310 etree.tostring(root))
2311
2313 etree = self.etree
2314
2315 root = etree.Element('root')
2316 sub = etree.Element('{http://test/ns}sub',
2317 nsmap={'test': 'http://test/ns'})
2318
2319 sub.attrib['{http://test/ns}attr'] = 'value'
2320 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2321 self.assertEqual(
2322 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2323 etree.tostring(sub))
2324
2325 root.append(sub)
2326 self.assertEqual(
2327 _bytes('<root>'
2328 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2329 '</root>'),
2330 etree.tostring(root))
2331
2333 etree = self.etree
2334
2335 root = etree.Element('root')
2336 sub = etree.Element('{http://test/ns}sub',
2337 nsmap={None: 'http://test/ns'})
2338
2339 sub.attrib['{http://test/ns}attr'] = 'value'
2340 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2341 self.assertEqual(
2342 _bytes('<sub xmlns="http://test/ns" '
2343 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2344 etree.tostring(sub))
2345
2346 root.append(sub)
2347 self.assertEqual(
2348 _bytes('<root>'
2349 '<sub xmlns="http://test/ns"'
2350 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2351 '</root>'),
2352 etree.tostring(root))
2353
2355 etree = self.etree
2356
2357 root = etree.Element('{http://test/ns}root',
2358 nsmap={'test': 'http://test/ns',
2359 None: 'http://test/ns'})
2360 sub = etree.Element('{http://test/ns}sub',
2361 nsmap={None: 'http://test/ns'})
2362
2363 sub.attrib['{http://test/ns}attr'] = 'value'
2364 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2365 self.assertEqual(
2366 _bytes('<sub xmlns="http://test/ns" '
2367 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2368 etree.tostring(sub))
2369
2370 root.append(sub)
2371 self.assertEqual(
2372 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2373 '<test:sub test:attr="value"/>'
2374 '</test:root>'),
2375 etree.tostring(root))
2376
2378 etree = self.etree
2379 r = {None: 'http://ns.infrae.com/foo',
2380 'hoi': 'http://ns.infrae.com/hoi'}
2381 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2382 tree = etree.ElementTree(element=e)
2383 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2384 self.assertEqual(
2385 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2386 self._writeElement(e))
2387
2389 etree = self.etree
2390
2391 r = {None: 'http://ns.infrae.com/foo'}
2392 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2393 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2394
2395 e1.append(e2)
2396
2397 self.assertEqual(
2398 None,
2399 e1.prefix)
2400 self.assertEqual(
2401 None,
2402 e1[0].prefix)
2403 self.assertEqual(
2404 '{http://ns.infrae.com/foo}bar',
2405 e1.tag)
2406 self.assertEqual(
2407 '{http://ns.infrae.com/foo}bar',
2408 e1[0].tag)
2409
2411 etree = self.etree
2412
2413 r = {None: 'http://ns.infrae.com/BAR'}
2414 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2415 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2416
2417 e1.append(e2)
2418
2419 self.assertEqual(
2420 None,
2421 e1.prefix)
2422 self.assertNotEqual(
2423 None,
2424 e2.prefix)
2425 self.assertEqual(
2426 '{http://ns.infrae.com/BAR}bar',
2427 e1.tag)
2428 self.assertEqual(
2429 '{http://ns.infrae.com/foo}bar',
2430 e2.tag)
2431
2433 ns_href = "http://a.b.c"
2434 one = self.etree.fromstring(
2435 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2436 baz = one[0][0]
2437
2438 two = self.etree.fromstring(
2439 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2440 two.append(baz)
2441 del one
2442
2443 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2444 self.assertEqual(
2445 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2446 self.etree.tostring(two))
2447
2457
2459 etree = self.etree
2460
2461 r = {None: 'http://ns.infrae.com/foo',
2462 'hoi': 'http://ns.infrae.com/hoi'}
2463 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2464 self.assertEqual(
2465 r,
2466 e.nsmap)
2467
2469 etree = self.etree
2470
2471 re = {None: 'http://ns.infrae.com/foo',
2472 'hoi': 'http://ns.infrae.com/hoi'}
2473 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2474
2475 rs = {None: 'http://ns.infrae.com/honk',
2476 'top': 'http://ns.infrae.com/top'}
2477 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2478
2479 r = re.copy()
2480 r.update(rs)
2481 self.assertEqual(re, e.nsmap)
2482 self.assertEqual(r, s.nsmap)
2483
2485 etree = self.etree
2486 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2487 self.assertEqual({'hha': None}, el.nsmap)
2488
2490 Element = self.etree.Element
2491 SubElement = self.etree.SubElement
2492
2493 a = Element('a')
2494 b = SubElement(a, 'b')
2495 c = SubElement(a, 'c')
2496 d = SubElement(b, 'd')
2497 e = SubElement(c, 'e')
2498 f = SubElement(c, 'f')
2499
2500 self.assertEqual(
2501 [a, b],
2502 list(a.getiterator('a', 'b')))
2503 self.assertEqual(
2504 [],
2505 list(a.getiterator('x', 'y')))
2506 self.assertEqual(
2507 [a, f],
2508 list(a.getiterator('f', 'a')))
2509 self.assertEqual(
2510 [c, e, f],
2511 list(c.getiterator('c', '*', 'a')))
2512 self.assertEqual(
2513 [],
2514 list(a.getiterator( (), () )))
2515
2517 Element = self.etree.Element
2518 SubElement = self.etree.SubElement
2519
2520 a = Element('a')
2521 b = SubElement(a, 'b')
2522 c = SubElement(a, 'c')
2523 d = SubElement(b, 'd')
2524 e = SubElement(c, 'e')
2525 f = SubElement(c, 'f')
2526
2527 self.assertEqual(
2528 [a, b],
2529 list(a.getiterator( ('a', 'b') )))
2530 self.assertEqual(
2531 [],
2532 list(a.getiterator( ('x', 'y') )))
2533 self.assertEqual(
2534 [a, f],
2535 list(a.getiterator( ('f', 'a') )))
2536 self.assertEqual(
2537 [c, e, f],
2538 list(c.getiterator( ('c', '*', 'a') )))
2539 self.assertEqual(
2540 [],
2541 list(a.getiterator( () )))
2542
2544 Element = self.etree.Element
2545 SubElement = self.etree.SubElement
2546
2547 a = Element('{a}a')
2548 b = SubElement(a, '{a}b')
2549 c = SubElement(a, '{a}c')
2550 d = SubElement(b, '{b}d')
2551 e = SubElement(c, '{a}e')
2552 f = SubElement(c, '{b}f')
2553 g = SubElement(c, 'g')
2554
2555 self.assertEqual(
2556 [a],
2557 list(a.getiterator('{a}a')))
2558 self.assertEqual(
2559 [],
2560 list(a.getiterator('{b}a')))
2561 self.assertEqual(
2562 [],
2563 list(a.getiterator('a')))
2564 self.assertEqual(
2565 [a,b,d,c,e,f,g],
2566 list(a.getiterator('*')))
2567 self.assertEqual(
2568 [f],
2569 list(c.getiterator('{b}*')))
2570 self.assertEqual(
2571 [d, f],
2572 list(a.getiterator('{b}*')))
2573 self.assertEqual(
2574 [g],
2575 list(a.getiterator('g')))
2576 self.assertEqual(
2577 [g],
2578 list(a.getiterator('{}g')))
2579 self.assertEqual(
2580 [g],
2581 list(a.getiterator('{}*')))
2582
2584 Element = self.etree.Element
2585 SubElement = self.etree.SubElement
2586
2587 a = Element('{a}a')
2588 b = SubElement(a, '{nsA}b')
2589 c = SubElement(b, '{nsB}b')
2590 d = SubElement(a, 'b')
2591 e = SubElement(a, '{nsA}e')
2592 f = SubElement(e, '{nsB}e')
2593 g = SubElement(e, 'e')
2594
2595 self.assertEqual(
2596 [b, c, d],
2597 list(a.getiterator('{*}b')))
2598 self.assertEqual(
2599 [e, f, g],
2600 list(a.getiterator('{*}e')))
2601 self.assertEqual(
2602 [a, b, c, d, e, f, g],
2603 list(a.getiterator('{*}*')))
2604
2629
2645
2662
2669
2676
2685
2687 XML = self.etree.XML
2688 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2689 self.assertEqual(len(root.findall(".//{X}b")), 2)
2690 self.assertEqual(len(root.findall(".//{X}*")), 2)
2691 self.assertEqual(len(root.findall(".//b")), 3)
2692
2694 XML = self.etree.XML
2695 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2696 nsmap = {'xx': 'X'}
2697 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2698 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2699 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2700 nsmap = {'xx': 'Y'}
2701 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2702 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2703 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2704
2706 XML = self.etree.XML
2707 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2708 nsmap = {'xx': 'X'}
2709 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2710 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2711 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2712 nsmap = {'xx': 'Y'}
2713 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2714 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2715 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2716
2723
2725 etree = self.etree
2726 e = etree.Element('foo')
2727 for i in range(10):
2728 etree.SubElement(e, 'a%s' % i)
2729 for i in range(10):
2730 self.assertEqual(
2731 i,
2732 e.index(e[i]))
2733 self.assertEqual(
2734 3, e.index(e[3], 3))
2735 self.assertRaises(
2736 ValueError, e.index, e[3], 4)
2737 self.assertRaises(
2738 ValueError, e.index, e[3], 0, 2)
2739 self.assertRaises(
2740 ValueError, e.index, e[8], 0, -3)
2741 self.assertRaises(
2742 ValueError, e.index, e[8], -5, -3)
2743 self.assertEqual(
2744 8, e.index(e[8], 0, -1))
2745 self.assertEqual(
2746 8, e.index(e[8], -12, -1))
2747 self.assertEqual(
2748 0, e.index(e[0], -12, -1))
2749
2751 etree = self.etree
2752 e = etree.Element('foo')
2753 for i in range(10):
2754 el = etree.SubElement(e, 'a%s' % i)
2755 el.text = "text%d" % i
2756 el.tail = "tail%d" % i
2757
2758 child0 = e[0]
2759 child1 = e[1]
2760 child2 = e[2]
2761
2762 e.replace(e[0], e[1])
2763 self.assertEqual(
2764 9, len(e))
2765 self.assertEqual(
2766 child1, e[0])
2767 self.assertEqual(
2768 child1.text, "text1")
2769 self.assertEqual(
2770 child1.tail, "tail1")
2771 self.assertEqual(
2772 child0.tail, "tail0")
2773 self.assertEqual(
2774 child2, e[1])
2775
2776 e.replace(e[-1], e[0])
2777 self.assertEqual(
2778 child1, e[-1])
2779 self.assertEqual(
2780 child1.text, "text1")
2781 self.assertEqual(
2782 child1.tail, "tail1")
2783 self.assertEqual(
2784 child2, e[0])
2785
2787 etree = self.etree
2788 e = etree.Element('foo')
2789 for i in range(10):
2790 etree.SubElement(e, 'a%s' % i)
2791
2792 new_element = etree.Element("test")
2793 new_element.text = "TESTTEXT"
2794 new_element.tail = "TESTTAIL"
2795 child1 = e[1]
2796 e.replace(e[0], new_element)
2797 self.assertEqual(
2798 new_element, e[0])
2799 self.assertEqual(
2800 "TESTTEXT",
2801 e[0].text)
2802 self.assertEqual(
2803 "TESTTAIL",
2804 e[0].tail)
2805 self.assertEqual(
2806 child1, e[1])
2807
2823
2841
2859
2877
2879 Element = self.etree.Element
2880 SubElement = self.etree.SubElement
2881 try:
2882 slice
2883 except NameError:
2884 print("slice() not found")
2885 return
2886
2887 a = Element('a')
2888 b = SubElement(a, 'b')
2889 c = SubElement(a, 'c')
2890 d = SubElement(a, 'd')
2891 e = SubElement(a, 'e')
2892
2893 x = Element('x')
2894 y = Element('y')
2895 z = Element('z')
2896
2897 self.assertRaises(
2898 ValueError,
2899 operator.setitem, a, slice(1,None,2), [x, y, z])
2900
2901 self.assertEqual(
2902 [b, c, d, e],
2903 list(a))
2904
2917
2919 XML = self.etree.XML
2920 root = XML(_bytes(
2921 '<?xml version="1.0"?>\n'
2922 '<root>' + '\n' * 65536 +
2923 '<p>' + '\n' * 65536 + '</p>\n' +
2924 '<br/>\n'
2925 '</root>'))
2926
2927 if self.etree.LIBXML_VERSION >= (2, 9):
2928 expected = [2, 131074, 131076]
2929 else:
2930 expected = [2, 65535, 65535]
2931
2932 self.assertEqual(expected, [el.sourceline for el in root.iter()])
2933
2941
2950
2960
2970
2976
2984
2990
2997
3003
3005 etree = self.etree
3006 xml_header = '<?xml version="1.0" encoding="ascii"?>'
3007 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3008 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3009 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
3010
3011 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3012
3013 tree = etree.parse(BytesIO(xml))
3014 docinfo = tree.docinfo
3015 self.assertEqual(docinfo.encoding, "ascii")
3016 self.assertEqual(docinfo.xml_version, "1.0")
3017 self.assertEqual(docinfo.public_id, pub_id)
3018 self.assertEqual(docinfo.system_url, sys_id)
3019 self.assertEqual(docinfo.root_name, 'html')
3020 self.assertEqual(docinfo.doctype, doctype_string)
3021
3037
3049
3061
3067
3069 etree = self.etree
3070 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3071 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3072 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
3073
3074 xml = _bytes('<!DOCTYPE root>\n<root/>')
3075 tree = etree.parse(BytesIO(xml))
3076 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
3077 etree.tostring(tree, doctype=doctype_string))
3078
3080 etree = self.etree
3081 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3082 self.assertEqual(root.base, "http://no/such/url")
3083 self.assertEqual(
3084 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3085 root.base = "https://secret/url"
3086 self.assertEqual(root.base, "https://secret/url")
3087 self.assertEqual(
3088 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3089 "https://secret/url")
3090
3092 etree = self.etree
3093 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3094 self.assertEqual(root.base, "http://no/such/url")
3095 self.assertEqual(
3096 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3097 root.set('{http://www.w3.org/XML/1998/namespace}base',
3098 "https://secret/url")
3099 self.assertEqual(root.base, "https://secret/url")
3100 self.assertEqual(
3101 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3102 "https://secret/url")
3103
3109
3114
3121
3135
3137 Element = self.etree.Element
3138
3139 a = Element('a')
3140 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3141 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3142
3143 self.assertRaises(ValueError, Element, 'ha\0ho')
3144
3146 Element = self.etree.Element
3147
3148 a = Element('a')
3149 self.assertRaises(ValueError, setattr, a, "text",
3150 _str('ha\0ho'))
3151 self.assertRaises(ValueError, setattr, a, "tail",
3152 _str('ha\0ho'))
3153
3154 self.assertRaises(ValueError, Element,
3155 _str('ha\0ho'))
3156
3158 Element = self.etree.Element
3159
3160 a = Element('a')
3161 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3162 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3163
3164 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3165 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3166
3167 self.assertRaises(ValueError, Element, 'ha\x07ho')
3168 self.assertRaises(ValueError, Element, 'ha\x02ho')
3169
3171 Element = self.etree.Element
3172
3173 a = Element('a')
3174 self.assertRaises(ValueError, setattr, a, "text",
3175 _str('ha\x07ho'))
3176 self.assertRaises(ValueError, setattr, a, "text",
3177 _str('ha\x02ho'))
3178
3179 self.assertRaises(ValueError, setattr, a, "tail",
3180 _str('ha\x07ho'))
3181 self.assertRaises(ValueError, setattr, a, "tail",
3182 _str('ha\x02ho'))
3183
3184 self.assertRaises(ValueError, Element,
3185 _str('ha\x07ho'))
3186 self.assertRaises(ValueError, Element,
3187 _str('ha\x02ho'))
3188
3190 Element = self.etree.Element
3191
3192 a = Element('a')
3193 self.assertRaises(ValueError, setattr, a, "text",
3194 _str('ha\u1234\x07ho'))
3195 self.assertRaises(ValueError, setattr, a, "text",
3196 _str('ha\u1234\x02ho'))
3197
3198 self.assertRaises(ValueError, setattr, a, "tail",
3199 _str('ha\u1234\x07ho'))
3200 self.assertRaises(ValueError, setattr, a, "tail",
3201 _str('ha\u1234\x02ho'))
3202
3203 self.assertRaises(ValueError, Element,
3204 _str('ha\u1234\x07ho'))
3205 self.assertRaises(ValueError, Element,
3206 _str('ha\u1234\x02ho'))
3207
3221
3226
3244
3264
3266 tostring = self.etree.tostring
3267 html = self.etree.fromstring(
3268 '<html><body>'
3269 '<div><p>Some text<i>\r\n</i></p></div>\r\n'
3270 '</body></html>',
3271 parser=self.etree.HTMLParser())
3272 self.assertEqual(html.tag, 'html')
3273 div = html.find('.//div')
3274 self.assertEqual(div.tail, '\r\n')
3275 result = tostring(div, method='html')
3276 self.assertEqual(
3277 result,
3278 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3279 result = tostring(div, method='html', with_tail=True)
3280 self.assertEqual(
3281 result,
3282 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3283 result = tostring(div, method='html', with_tail=False)
3284 self.assertEqual(
3285 result,
3286 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3287
3309
3311 tostring = self.etree.tostring
3312 XML = self.etree.XML
3313 ElementTree = self.etree.ElementTree
3314
3315 root = XML(_bytes("<root/>"))
3316
3317 tree = ElementTree(root)
3318 self.assertEqual(None, tree.docinfo.standalone)
3319
3320 result = tostring(root, xml_declaration=True, encoding="ASCII")
3321 self.assertEqual(result, _bytes(
3322 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3323
3324 result = tostring(root, xml_declaration=True, encoding="ASCII",
3325 standalone=True)
3326 self.assertEqual(result, _bytes(
3327 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3328
3329 tree = ElementTree(XML(result))
3330 self.assertEqual(True, tree.docinfo.standalone)
3331
3332 result = tostring(root, xml_declaration=True, encoding="ASCII",
3333 standalone=False)
3334 self.assertEqual(result, _bytes(
3335 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3336
3337 tree = ElementTree(XML(result))
3338 self.assertEqual(False, tree.docinfo.standalone)
3339
3359
3361 tostring = self.etree.tostring
3362 Element = self.etree.Element
3363 SubElement = self.etree.SubElement
3364
3365 a = Element('a')
3366 a.text = "A"
3367 a.tail = "tail"
3368 b = SubElement(a, 'b')
3369 b.text = "B"
3370 b.tail = _str("Søk på nettet")
3371 c = SubElement(a, 'c')
3372 c.text = "C"
3373
3374 result = tostring(a, method="text", encoding="UTF-16")
3375
3376 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3377 result)
3378
3380 tostring = self.etree.tostring
3381 Element = self.etree.Element
3382 SubElement = self.etree.SubElement
3383
3384 a = Element('a')
3385 a.text = _str('Søk på nettetA')
3386 a.tail = "tail"
3387 b = SubElement(a, 'b')
3388 b.text = "B"
3389 b.tail = _str('Søk på nettetB')
3390 c = SubElement(a, 'c')
3391 c.text = "C"
3392
3393 self.assertRaises(UnicodeEncodeError,
3394 tostring, a, method="text")
3395
3396 self.assertEqual(
3397 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3398 tostring(a, encoding="UTF-8", method="text"))
3399
3412
3428
3432
3447
3465
3478
3480 tostring = self.etree.tostring
3481 Element = self.etree.Element
3482 SubElement = self.etree.SubElement
3483
3484 a = Element('a')
3485 b = SubElement(a, 'b')
3486 c = SubElement(a, 'c')
3487 d = SubElement(c, 'd')
3488 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3489 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3490 self.assertEqual(_bytes('<b></b>'),
3491 canonicalize(tostring(b, encoding=_unicode)))
3492 self.assertEqual(_bytes('<c><d></d></c>'),
3493 canonicalize(tostring(c, encoding=_unicode)))
3494
3499
3514
3516 tostring = self.etree.tostring
3517 Element = self.etree.Element
3518 SubElement = self.etree.SubElement
3519
3520 a = Element('a')
3521 b = SubElement(a, 'b')
3522 c = SubElement(a, 'c')
3523
3524 result = tostring(a, encoding=_unicode)
3525 self.assertEqual(result, "<a><b/><c/></a>")
3526
3527 result = tostring(a, encoding=_unicode, pretty_print=False)
3528 self.assertEqual(result, "<a><b/><c/></a>")
3529
3530 result = tostring(a, encoding=_unicode, pretty_print=True)
3531 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3532
3544
3546 class SubEl(etree.ElementBase):
3547 pass
3548
3549 el1 = SubEl()
3550 el2 = SubEl()
3551 self.assertEqual('SubEl', el1.tag)
3552 self.assertEqual('SubEl', el2.tag)
3553 el1.other = el2
3554 el2.other = el1
3555
3556 del el1, el2
3557 gc.collect()
3558
3559
3560
3561
3562 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3573
3574
3618
3619 res_instance = res()
3620 parser = etree.XMLParser(load_dtd = True)
3621 parser.resolvers.add(res_instance)
3622
3623 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3624 parser = parser)
3625
3626 self.include(tree)
3627
3628 called = list(res_instance.called.items())
3629 called.sort()
3630 self.assertEqual(
3631 [("dtd", True), ("include", True), ("input", True)],
3632 called)
3633
3634
3638
3639
3644
3645
3648 tree = self.parse(_bytes('<a><b/></a>'))
3649 f = BytesIO()
3650 tree.write_c14n(f)
3651 s = f.getvalue()
3652 self.assertEqual(_bytes('<a><b></b></a>'),
3653 s)
3654
3656 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3657 f = BytesIO()
3658 tree.write_c14n(f, compression=9)
3659 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3660 try:
3661 s = gzfile.read()
3662 finally:
3663 gzfile.close()
3664 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3665 s)
3666
3678
3694
3712
3724
3736
3738 tree = self.parse(_bytes(
3739 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3740 f = BytesIO()
3741 tree.write_c14n(f)
3742 s = f.getvalue()
3743 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3744 s)
3745 f = BytesIO()
3746 tree.write_c14n(f, exclusive=False)
3747 s = f.getvalue()
3748 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3749 s)
3750 f = BytesIO()
3751 tree.write_c14n(f, exclusive=True)
3752 s = f.getvalue()
3753 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3754 s)
3755
3756 f = BytesIO()
3757 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
3758 s = f.getvalue()
3759 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
3760 s)
3761
3763 tree = self.parse(_bytes(
3764 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3765 s = etree.tostring(tree, method='c14n')
3766 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3767 s)
3768 s = etree.tostring(tree, method='c14n', exclusive=False)
3769 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3770 s)
3771 s = etree.tostring(tree, method='c14n', exclusive=True)
3772 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3773 s)
3774
3775 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3776 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
3777 s)
3778
3780 tree = self.parse(_bytes(
3781 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3782 s = etree.tostring(tree.getroot(), method='c14n')
3783 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3784 s)
3785 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3786 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3787 s)
3788 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3789 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3790 s)
3791
3792 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3793 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3794 s)
3795 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3796 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3797 s)
3798
3799 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3800 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3801 s)
3802
3804 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
3805 tree = self.parse(_bytes(
3806 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3807
3808 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
3809 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3810 s)
3811
3812
3815 tree = self.parse(_bytes('<a><b/></a>'))
3816 f = BytesIO()
3817 tree.write(f)
3818 s = f.getvalue()
3819 self.assertEqual(_bytes('<a><b/></a>'),
3820 s)
3821
3823 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3824 f = BytesIO()
3825 tree.write(f, compression=9)
3826 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3827 try:
3828 s = gzfile.read()
3829 finally:
3830 gzfile.close()
3831 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3832 s)
3833
3835 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3836 f = BytesIO()
3837 tree.write(f, compression=0)
3838 s0 = f.getvalue()
3839
3840 f = BytesIO()
3841 tree.write(f)
3842 self.assertEqual(f.getvalue(), s0)
3843
3844 f = BytesIO()
3845 tree.write(f, compression=1)
3846 s = f.getvalue()
3847 self.assertTrue(len(s) <= len(s0))
3848 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3849 try:
3850 s1 = gzfile.read()
3851 finally:
3852 gzfile.close()
3853
3854 f = BytesIO()
3855 tree.write(f, compression=9)
3856 s = f.getvalue()
3857 self.assertTrue(len(s) <= len(s0))
3858 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3859 try:
3860 s9 = gzfile.read()
3861 finally:
3862 gzfile.close()
3863
3864 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3865 s0)
3866 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3867 s1)
3868 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3869 s9)
3870
3882
3898
3910
3923
3925 etree = etree
3926
3948
3950 """This can't really be tested as long as there isn't a way to
3951 reset the logging setup ...
3952 """
3953 parse = self.etree.parse
3954
3955 messages = []
3956 class Logger(self.etree.PyErrorLog):
3957 def log(self, entry, message, *args):
3958 messages.append(message)
3959
3960 self.etree.use_global_python_log(Logger())
3961 f = BytesIO('<a><b></c></b></a>')
3962 try:
3963 parse(f)
3964 except SyntaxError:
3965 pass
3966 f.close()
3967
3968 self.assertTrue([ message for message in messages
3969 if 'mismatch' in message ])
3970 self.assertTrue([ message for message in messages
3971 if ':PARSER:' in message])
3972 self.assertTrue([ message for message in messages
3973 if ':ERR_TAG_NAME_MISMATCH:' in message ])
3974 self.assertTrue([ message for message in messages
3975 if ':1:15:' in message ])
3976
3977
3979 etree = etree
3980
3984
3986 class Target(object):
3987 def start(self, tag, attrib):
3988 return 'start(%s)' % tag
3989 def end(self, tag):
3990 return 'end(%s)' % tag
3991 def close(self):
3992 return 'close()'
3993
3994 parser = self.etree.XMLPullParser(target=Target())
3995 events = parser.read_events()
3996
3997 parser.feed('<root><element>')
3998 self.assertFalse(list(events))
3999 self.assertFalse(list(events))
4000 parser.feed('</element><child>')
4001 self.assertEqual([('end', 'end(element)')], list(events))
4002 parser.feed('</child>')
4003 self.assertEqual([('end', 'end(child)')], list(events))
4004 parser.feed('</root>')
4005 self.assertEqual([('end', 'end(root)')], list(events))
4006 self.assertFalse(list(events))
4007 self.assertEqual('close()', parser.close())
4008
4010 class Target(object):
4011 def start(self, tag, attrib):
4012 return 'start(%s)' % tag
4013 def end(self, tag):
4014 return 'end(%s)' % tag
4015 def close(self):
4016 return 'close()'
4017
4018 parser = self.etree.XMLPullParser(
4019 ['start', 'end'], target=Target())
4020 events = parser.read_events()
4021
4022 parser.feed('<root><element>')
4023 self.assertEqual(
4024 [('start', 'start(root)'), ('start', 'start(element)')],
4025 list(events))
4026 self.assertFalse(list(events))
4027 parser.feed('</element><child>')
4028 self.assertEqual(
4029 [('end', 'end(element)'), ('start', 'start(child)')],
4030 list(events))
4031 parser.feed('</child>')
4032 self.assertEqual(
4033 [('end', 'end(child)')],
4034 list(events))
4035 parser.feed('</root>')
4036 self.assertEqual(
4037 [('end', 'end(root)')],
4038 list(events))
4039 self.assertFalse(list(events))
4040 self.assertEqual('close()', parser.close())
4041
4043 parser = self.etree.XMLPullParser(
4044 ['start', 'end'], target=etree.TreeBuilder())
4045 events = parser.read_events()
4046
4047 parser.feed('<root><element>')
4048 self.assert_event_tags(
4049 events, [('start', 'root'), ('start', 'element')])
4050 self.assertFalse(list(events))
4051 parser.feed('</element><child>')
4052 self.assert_event_tags(
4053 events, [('end', 'element'), ('start', 'child')])
4054 parser.feed('</child>')
4055 self.assert_event_tags(
4056 events, [('end', 'child')])
4057 parser.feed('</root>')
4058 self.assert_event_tags(
4059 events, [('end', 'root')])
4060 self.assertFalse(list(events))
4061 root = parser.close()
4062 self.assertEqual('root', root.tag)
4063
4065 class Target(etree.TreeBuilder):
4066 def end(self, tag):
4067 el = super(Target, self).end(tag)
4068 el.tag += '-huhu'
4069 return el
4070
4071 parser = self.etree.XMLPullParser(
4072 ['start', 'end'], target=Target())
4073 events = parser.read_events()
4074
4075 parser.feed('<root><element>')
4076 self.assert_event_tags(
4077 events, [('start', 'root'), ('start', 'element')])
4078 self.assertFalse(list(events))
4079 parser.feed('</element><child>')
4080 self.assert_event_tags(
4081 events, [('end', 'element-huhu'), ('start', 'child')])
4082 parser.feed('</child>')
4083 self.assert_event_tags(
4084 events, [('end', 'child-huhu')])
4085 parser.feed('</root>')
4086 self.assert_event_tags(
4087 events, [('end', 'root-huhu')])
4088 self.assertFalse(list(events))
4089 root = parser.close()
4090 self.assertEqual('root-huhu', root.tag)
4091
4092
4116
4117 if __name__ == '__main__':
4118 print('to test use test.py %s' % __file__)
4119