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 textwrap
19 import zlib
20 import gzip
21
22 this_dir = os.path.dirname(__file__)
23 if this_dir not in sys.path:
24 sys.path.insert(0, this_dir)
25
26 from common_imports import etree, StringIO, BytesIO, HelperTestCase
27 from common_imports import fileInTestDir, fileUrlInTestDir, read_file, path2url
28 from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest
29 from common_imports import canonicalize, sorted, _str, _bytes
30
31 print("")
32 print("TESTED VERSION: %s" % etree.__version__)
33 print(" Python: " + repr(sys.version_info))
34 print(" lxml.etree: " + repr(etree.LXML_VERSION))
35 print(" libxml used: " + repr(etree.LIBXML_VERSION))
36 print(" libxml compiled: " + repr(etree.LIBXML_COMPILED_VERSION))
37 print(" libxslt used: " + repr(etree.LIBXSLT_VERSION))
38 print(" libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION))
39 print("")
40
41 try:
42 _unicode = unicode
43 except NameError:
44
45 _unicode = str
46
48 """Tests only for etree, not ElementTree"""
49 etree = etree
50
61
70
77
79 Element = self.etree.Element
80 el = Element('name')
81 self.assertRaises(ValueError, Element, '{}')
82 self.assertRaises(ValueError, setattr, el, 'tag', '{}')
83
84 self.assertRaises(ValueError, Element, '{test}')
85 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
86
94
96 Element = self.etree.Element
97 self.assertRaises(ValueError, Element, "p'name")
98 self.assertRaises(ValueError, Element, 'p"name')
99
100 self.assertRaises(ValueError, Element, "{test}p'name")
101 self.assertRaises(ValueError, Element, '{test}p"name')
102
103 el = Element('name')
104 self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
105 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
106
108 Element = self.etree.Element
109 self.assertRaises(ValueError, Element, ' name ')
110 self.assertRaises(ValueError, Element, 'na me')
111 self.assertRaises(ValueError, Element, '{test} name')
112
113 el = Element('name')
114 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
115
123
131
133 Element = self.etree.Element
134 SubElement = self.etree.SubElement
135
136 el = Element('name')
137 self.assertRaises(ValueError, SubElement, el, "p'name")
138 self.assertRaises(ValueError, SubElement, el, "{test}p'name")
139
140 self.assertRaises(ValueError, SubElement, el, 'p"name')
141 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
142
151
160
162 QName = self.etree.QName
163 self.assertRaises(ValueError, QName, '')
164 self.assertRaises(ValueError, QName, 'test', '')
165
167 QName = self.etree.QName
168 self.assertRaises(ValueError, QName, 'p:name')
169 self.assertRaises(ValueError, QName, 'test', 'p:name')
170
172 QName = self.etree.QName
173 self.assertRaises(ValueError, QName, ' name ')
174 self.assertRaises(ValueError, QName, 'na me')
175 self.assertRaises(ValueError, QName, 'test', ' name')
176
184
186
187 QName = self.etree.QName
188 qname1 = QName('http://myns', 'a')
189 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
190
191 qname2 = QName(a)
192 self.assertEqual(a.tag, qname1.text)
193 self.assertEqual(qname1.text, qname2.text)
194 self.assertEqual(qname1, qname2)
195
197
198 etree = self.etree
199 qname = etree.QName('http://myns', 'a')
200 a = etree.Element(qname, nsmap={'p' : 'http://myns'})
201 a.text = qname
202
203 self.assertEqual("p:a", a.text)
204
213
228
234
246
248 Element = self.etree.Element
249
250 keys = ["attr%d" % i for i in range(10)]
251 values = ["TEST-%d" % i for i in range(10)]
252 items = list(zip(keys, values))
253
254 root = Element("root")
255 for key, value in items:
256 root.set(key, value)
257 self.assertEqual(keys, root.attrib.keys())
258 self.assertEqual(values, root.attrib.values())
259
260 root2 = Element("root2", root.attrib,
261 attr_99='TOAST-1', attr_98='TOAST-2')
262 self.assertEqual(['attr_98', 'attr_99'] + keys,
263 root2.attrib.keys())
264 self.assertEqual(['TOAST-2', 'TOAST-1'] + values,
265 root2.attrib.values())
266
267 self.assertEqual(keys, root.attrib.keys())
268 self.assertEqual(values, root.attrib.values())
269
277
291
313
315 XML = self.etree.XML
316 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
317
318 root = XML(xml)
319 self.etree.strip_elements(root, 'a')
320 self.assertEqual(_bytes('<test><x></x></test>'),
321 self._writeElement(root))
322
323 root = XML(xml)
324 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
325 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'),
326 self._writeElement(root))
327
328 root = XML(xml)
329 self.etree.strip_elements(root, 'c')
330 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
331 self._writeElement(root))
332
334 XML = self.etree.XML
335 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>')
336
337 root = XML(xml)
338 self.etree.strip_elements(root, 'a')
339 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>'),
340 self._writeElement(root))
341
342 root = XML(xml)
343 self.etree.strip_elements(root, '{urn:a}b', 'c')
344 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>'),
345 self._writeElement(root))
346
347 root = XML(xml)
348 self.etree.strip_elements(root, '{urn:a}*', 'c')
349 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
350 self._writeElement(root))
351
352 root = XML(xml)
353 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
354 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
355 self._writeElement(root))
356
375
401
428
455
474
487
498
504
506 XML = self.etree.XML
507 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
508 self.assertEqual(root[0].target, "mypi")
509 self.assertEqual(root[0].get('my'), "1")
510 self.assertEqual(root[0].get('test'), " abc ")
511 self.assertEqual(root[0].get('quotes'), "' '")
512 self.assertEqual(root[0].get('only'), None)
513 self.assertEqual(root[0].get('names'), None)
514 self.assertEqual(root[0].get('nope'), None)
515
517 XML = self.etree.XML
518 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
519 self.assertEqual(root[0].target, "mypi")
520 self.assertEqual(root[0].attrib['my'], "1")
521 self.assertEqual(root[0].attrib['test'], " abc ")
522 self.assertEqual(root[0].attrib['quotes'], "' '")
523 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
524 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
525 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
526
528
529 ProcessingInstruction = self.etree.ProcessingInstruction
530
531 a = ProcessingInstruction("PI", "ONE")
532 b = copy.deepcopy(a)
533 b.text = "ANOTHER"
534
535 self.assertEqual('ONE', a.text)
536 self.assertEqual('ANOTHER', b.text)
537
553
568
578
590
609
614
627
638
639 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
640 events = list(iterparse(f, events=('end', 'comment')))
641 root = events[-1][1]
642 self.assertEqual(6, len(events))
643 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'],
644 [ name(*item) for item in events ])
645 self.assertEqual(
646 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
647 tostring(root))
648
660
661 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
662 events = list(iterparse(f, events=('end', 'pi')))
663 root = events[-2][1]
664 self.assertEqual(8, len(events))
665 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
666 ('pid','d'), 'a', ('pie','e')],
667 [ name(*item) for item in events ])
668 self.assertEqual(
669 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
670 tostring(ElementTree(root)))
671
686
692
694 iterparse = self.etree.iterparse
695 f = BytesIO('<a><b><c/></a>')
696 it = iterparse(f, events=('start', 'end'), recover=True)
697 events = [(ev, el.tag) for ev, el in it]
698 root = it.root
699 self.assertTrue(root is not None)
700
701 self.assertEqual(1, events.count(('start', 'a')))
702 self.assertEqual(1, events.count(('end', 'a')))
703
704 self.assertEqual(1, events.count(('start', 'b')))
705 self.assertEqual(1, events.count(('end', 'b')))
706
707 self.assertEqual(1, events.count(('start', 'c')))
708 self.assertEqual(1, events.count(('end', 'c')))
709
711 iterparse = self.etree.iterparse
712 f = BytesIO('<a><b><c/></d><b><c/></a></b>')
713 it = iterparse(f, events=('start', 'end'), recover=True)
714 events = [(ev, el.tag) for ev, el in it]
715 root = it.root
716 self.assertTrue(root is not None)
717
718 self.assertEqual(1, events.count(('start', 'a')))
719 self.assertEqual(1, events.count(('end', 'a')))
720
721 self.assertEqual(2, events.count(('start', 'b')))
722 self.assertEqual(2, events.count(('end', 'b')))
723
724 self.assertEqual(2, events.count(('start', 'c')))
725 self.assertEqual(2, events.count(('end', 'c')))
726
728 iterparse = self.etree.iterparse
729 f = BytesIO("""
730 <a> \n \n <b> b test </b> \n
731
732 \n\t <c> \n </c> </a> \n """)
733 iterator = iterparse(f, remove_blank_text=True)
734 text = [ (element.text, element.tail)
735 for event, element in iterator ]
736 self.assertEqual(
737 [(" b test ", None), (" \n ", None), (None, None)],
738 text)
739
741 iterparse = self.etree.iterparse
742 f = BytesIO('<a><b><d/></b><c/></a>')
743
744 iterator = iterparse(f, tag="b", events=('start', 'end'))
745 events = list(iterator)
746 root = iterator.root
747 self.assertEqual(
748 [('start', root[0]), ('end', root[0])],
749 events)
750
752 iterparse = self.etree.iterparse
753 f = BytesIO('<a><b><d/></b><c/></a>')
754
755 iterator = iterparse(f, tag="*", events=('start', 'end'))
756 events = list(iterator)
757 self.assertEqual(
758 8,
759 len(events))
760
762 iterparse = self.etree.iterparse
763 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
764
765 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
766 events = list(iterator)
767 root = iterator.root
768 self.assertEqual(
769 [('start', root[0]), ('end', root[0])],
770 events)
771
773 iterparse = self.etree.iterparse
774 f = BytesIO('<a><b><d/></b><c/></a>')
775 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
776 events = list(iterator)
777 root = iterator.root
778 self.assertEqual(
779 [('start', root[0]), ('end', root[0])],
780 events)
781
782 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
783 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
784 events = list(iterator)
785 root = iterator.root
786 self.assertEqual([], events)
787
789 iterparse = self.etree.iterparse
790 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
791 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
792 events = list(iterator)
793 self.assertEqual(8, len(events))
794
796 iterparse = self.etree.iterparse
797 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
798 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
799 events = list(iterator)
800 self.assertEqual([], events)
801
802 f = BytesIO('<a><b><d/></b><c/></a>')
803 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
804 events = list(iterator)
805 self.assertEqual(8, len(events))
806
808 text = _str('Søk på nettet')
809 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
810 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
811 ).encode('iso-8859-1')
812
813 self.assertRaises(self.etree.ParseError,
814 list, self.etree.iterparse(BytesIO(xml_latin1)))
815
817 text = _str('Søk på nettet', encoding="UTF-8")
818 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
819 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
820 ).encode('iso-8859-1')
821
822 iterator = self.etree.iterparse(BytesIO(xml_latin1),
823 encoding="iso-8859-1")
824 self.assertEqual(1, len(list(iterator)))
825
826 a = iterator.root
827 self.assertEqual(a.text, text)
828
830 tostring = self.etree.tostring
831 f = BytesIO('<root><![CDATA[test]]></root>')
832 context = self.etree.iterparse(f, strip_cdata=False)
833 content = [ el.text for event,el in context ]
834
835 self.assertEqual(['test'], content)
836 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
837 tostring(context.root))
838
842
847
866
867
868
891
892
893
904 def end(self, tag):
905 events.append("end")
906 assertEqual("TAG", tag)
907 def close(self):
908 return "DONE"
909
910 parser = self.etree.XMLParser(target=Target())
911 tree = self.etree.ElementTree()
912
913 self.assertRaises(TypeError,
914 tree.parse, BytesIO("<TAG/>"), parser=parser)
915 self.assertEqual(["start", "end"], events)
916
918
919 events = []
920 class Target(object):
921 def start(self, tag, attrib):
922 events.append("start-" + tag)
923 def end(self, tag):
924 events.append("end-" + tag)
925 if tag == 'a':
926 raise ValueError("dead and gone")
927 def data(self, data):
928 events.append("data-" + data)
929 def close(self):
930 events.append("close")
931 return "DONE"
932
933 parser = self.etree.XMLParser(target=Target())
934
935 try:
936 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
937 done = parser.close()
938 self.fail("error expected, but parsing succeeded")
939 except ValueError:
940 done = 'value error received as expected'
941
942 self.assertEqual(["start-root", "data-A", "start-a",
943 "data-ca", "end-a", "close"],
944 events)
945
947
948 events = []
949 class Target(object):
950 def start(self, tag, attrib):
951 events.append("start-" + tag)
952 def end(self, tag):
953 events.append("end-" + tag)
954 if tag == 'a':
955 raise ValueError("dead and gone")
956 def data(self, data):
957 events.append("data-" + data)
958 def close(self):
959 events.append("close")
960 return "DONE"
961
962 parser = self.etree.XMLParser(target=Target())
963
964 try:
965 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
966 parser=parser)
967 self.fail("error expected, but parsing succeeded")
968 except ValueError:
969 done = 'value error received as expected'
970
971 self.assertEqual(["start-root", "data-A", "start-a",
972 "data-ca", "end-a", "close"],
973 events)
974
976
977 events = []
978 class Target(object):
979 def start(self, tag, attrib):
980 events.append("start-" + tag)
981 def end(self, tag):
982 events.append("end-" + tag)
983 def data(self, data):
984 events.append("data-" + data)
985 def comment(self, text):
986 events.append("comment-" + text)
987 def close(self):
988 return "DONE"
989
990 parser = self.etree.XMLParser(target=Target(), collect_ids=False)
991
992 parser.feed(_bytes('<!--a--><root xml:id="123">A<!--b-->'))
993 parser.feed(_bytes('<sub xml:id="321"/>B</root>'))
994 done = parser.close()
995
996 self.assertEqual("DONE", done)
997 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
998 "start-sub", "end-sub", "data-B", "end-root"],
999 events)
1000
1006 def end(self, tag):
1007 events.append("end-" + tag)
1008 def data(self, data):
1009 events.append("data-" + data)
1010 def comment(self, text):
1011 events.append("comment-" + text)
1012 def close(self):
1013 return "DONE"
1014
1015 parser = self.etree.XMLParser(target=Target())
1016
1017 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
1018 done = parser.close()
1019
1020 self.assertEqual("DONE", done)
1021 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
1022 "start-sub", "end-sub", "comment-c", "data-B",
1023 "end-root", "comment-d"],
1024 events)
1025
1027 events = []
1028 class Target(object):
1029 def start(self, tag, attrib):
1030 events.append("start-" + tag)
1031 def end(self, tag):
1032 events.append("end-" + tag)
1033 def data(self, data):
1034 events.append("data-" + data)
1035 def pi(self, target, data):
1036 events.append("pi-" + target + "-" + data)
1037 def close(self):
1038 return "DONE"
1039
1040 parser = self.etree.XMLParser(target=Target())
1041
1042 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
1043 done = parser.close()
1044
1045 self.assertEqual("DONE", done)
1046 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b",
1047 "data-B", "end-root", "pi-test-c"],
1048 events)
1049
1051 events = []
1052 class Target(object):
1053 def start(self, tag, attrib):
1054 events.append("start-" + tag)
1055 def end(self, tag):
1056 events.append("end-" + tag)
1057 def data(self, data):
1058 events.append("data-" + data)
1059 def close(self):
1060 return "DONE"
1061
1062 parser = self.etree.XMLParser(target=Target(),
1063 strip_cdata=False)
1064
1065 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
1066 done = parser.close()
1067
1068 self.assertEqual("DONE", done)
1069 self.assertEqual(["start-root", "data-A", "start-a",
1070 "data-ca", "end-a", "data-B", "end-root"],
1071 events)
1072
1074 events = []
1075 class Target(object):
1076 def start(self, tag, attrib):
1077 events.append("start-" + tag)
1078 def end(self, tag):
1079 events.append("end-" + tag)
1080 def data(self, data):
1081 events.append("data-" + data)
1082 def close(self):
1083 events.append("close")
1084 return "DONE"
1085
1086 parser = self.etree.XMLParser(target=Target(),
1087 recover=True)
1088
1089 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
1090 done = parser.close()
1091
1092 self.assertEqual("DONE", done)
1093 self.assertEqual(["start-root", "data-A", "start-a",
1094 "data-ca", "end-a", "data-B",
1095 "end-root", "close"],
1096 events)
1097
1107
1117
1126
1136
1138 iterwalk = self.etree.iterwalk
1139 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1140
1141 iterator = iterwalk(root, events=('start','end'))
1142 events = list(iterator)
1143 self.assertEqual(
1144 [('start', root), ('start', root[0]), ('end', root[0]),
1145 ('start', root[1]), ('end', root[1]), ('end', root)],
1146 events)
1147
1158
1160 iterwalk = self.etree.iterwalk
1161 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1162
1163 attr_name = '{testns}bla'
1164 events = []
1165 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1166 for event, elem in iterator:
1167 events.append(event)
1168 if event == 'start':
1169 if elem.tag != '{ns1}a':
1170 elem.set(attr_name, 'value')
1171
1172 self.assertEqual(
1173 ['start-ns', 'start', 'start', 'start-ns', 'start',
1174 'end', 'end-ns', 'end', 'end', 'end-ns'],
1175 events)
1176
1177 self.assertEqual(
1178 None,
1179 root.get(attr_name))
1180 self.assertEqual(
1181 'value',
1182 root[0].get(attr_name))
1183
1194
1196 parse = self.etree.parse
1197 parser = self.etree.XMLParser(dtd_validation=True)
1198 assertEqual = self.assertEqual
1199 test_url = _str("__nosuch.dtd")
1200
1201 class MyResolver(self.etree.Resolver):
1202 def resolve(self, url, id, context):
1203 assertEqual(url, test_url)
1204 return self.resolve_string(
1205 _str('''<!ENTITY myentity "%s">
1206 <!ELEMENT doc ANY>''') % url, context)
1207
1208 parser.resolvers.add(MyResolver())
1209
1210 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1211 tree = parse(StringIO(xml), parser)
1212 root = tree.getroot()
1213 self.assertEqual(root.text, test_url)
1214
1216 parse = self.etree.parse
1217 parser = self.etree.XMLParser(dtd_validation=True)
1218 assertEqual = self.assertEqual
1219 test_url = _str("__nosuch.dtd")
1220
1221 class MyResolver(self.etree.Resolver):
1222 def resolve(self, url, id, context):
1223 assertEqual(url, test_url)
1224 return self.resolve_string(
1225 (_str('''<!ENTITY myentity "%s">
1226 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1227 context)
1228
1229 parser.resolvers.add(MyResolver())
1230
1231 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1232 tree = parse(StringIO(xml), parser)
1233 root = tree.getroot()
1234 self.assertEqual(root.text, test_url)
1235
1237 parse = self.etree.parse
1238 parser = self.etree.XMLParser(dtd_validation=True)
1239 assertEqual = self.assertEqual
1240 test_url = _str("__nosuch.dtd")
1241
1242 class MyResolver(self.etree.Resolver):
1243 def resolve(self, url, id, context):
1244 assertEqual(url, test_url)
1245 return self.resolve_file(
1246 SillyFileLike(
1247 _str('''<!ENTITY myentity "%s">
1248 <!ELEMENT doc ANY>''') % url), context)
1249
1250 parser.resolvers.add(MyResolver())
1251
1252 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1253 tree = parse(StringIO(xml), parser)
1254 root = tree.getroot()
1255 self.assertEqual(root.text, test_url)
1256
1258 parse = self.etree.parse
1259 parser = self.etree.XMLParser(attribute_defaults=True)
1260 assertEqual = self.assertEqual
1261 test_url = _str("__nosuch.dtd")
1262
1263 class MyResolver(self.etree.Resolver):
1264 def resolve(self, url, id, context):
1265 assertEqual(url, test_url)
1266 return self.resolve_filename(
1267 fileInTestDir('test.dtd'), context)
1268
1269 parser.resolvers.add(MyResolver())
1270
1271 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1272 tree = parse(StringIO(xml), parser)
1273 root = tree.getroot()
1274 self.assertEqual(
1275 root.attrib, {'default': 'valueA'})
1276 self.assertEqual(
1277 root[0].attrib, {'default': 'valueB'})
1278
1290
1291 parser.resolvers.add(MyResolver())
1292
1293 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1294 tree = parse(StringIO(xml), parser,
1295 base_url=fileUrlInTestDir('__test.xml'))
1296 root = tree.getroot()
1297 self.assertEqual(
1298 root.attrib, {'default': 'valueA'})
1299 self.assertEqual(
1300 root[0].attrib, {'default': 'valueB'})
1301
1303 parse = self.etree.parse
1304 parser = self.etree.XMLParser(attribute_defaults=True)
1305 assertEqual = self.assertEqual
1306 test_url = _str("__nosuch.dtd")
1307
1308 class MyResolver(self.etree.Resolver):
1309 def resolve(self, url, id, context):
1310 assertEqual(url, test_url)
1311 return self.resolve_file(
1312 open(fileInTestDir('test.dtd'), 'rb'), context)
1313
1314 parser.resolvers.add(MyResolver())
1315
1316 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1317 tree = parse(StringIO(xml), parser)
1318 root = tree.getroot()
1319 self.assertEqual(
1320 root.attrib, {'default': 'valueA'})
1321 self.assertEqual(
1322 root[0].attrib, {'default': 'valueB'})
1323
1325 parse = self.etree.parse
1326 parser = self.etree.XMLParser(load_dtd=True)
1327 assertEqual = self.assertEqual
1328 test_url = _str("__nosuch.dtd")
1329
1330 class check(object):
1331 resolved = False
1332
1333 class MyResolver(self.etree.Resolver):
1334 def resolve(self, url, id, context):
1335 assertEqual(url, test_url)
1336 check.resolved = True
1337 return self.resolve_empty(context)
1338
1339 parser.resolvers.add(MyResolver())
1340
1341 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1342 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1343 self.assertTrue(check.resolved)
1344
1351
1352 class MyResolver(self.etree.Resolver):
1353 def resolve(self, url, id, context):
1354 raise _LocalException
1355
1356 parser.resolvers.add(MyResolver())
1357
1358 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1359 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1360
1361 if etree.LIBXML_VERSION > (2,6,20):
1378
1380 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1381 <root>
1382 <child1/>
1383 <child2/>
1384 <child3> </child3>
1385 </root>''')
1386
1387 parser = self.etree.XMLParser(resolve_entities=False)
1388 root = etree.fromstring(xml, parser)
1389 self.assertEqual([ el.tag for el in root ],
1390 ['child1', 'child2', 'child3'])
1391
1392 root[0] = root[-1]
1393 self.assertEqual([ el.tag for el in root ],
1394 ['child3', 'child2'])
1395 self.assertEqual(root[0][0].text, ' ')
1396 self.assertEqual(root[0][0].name, 'nbsp')
1397
1413
1420
1422 Entity = self.etree.Entity
1423 self.assertRaises(ValueError, Entity, 'a b c')
1424 self.assertRaises(ValueError, Entity, 'a,b')
1425 self.assertRaises(ValueError, Entity, 'a\0b')
1426 self.assertRaises(ValueError, Entity, '#abc')
1427 self.assertRaises(ValueError, Entity, '#xxyz')
1428
1441
1454
1456 CDATA = self.etree.CDATA
1457 Element = self.etree.Element
1458
1459 root = Element("root")
1460 cdata = CDATA('test')
1461
1462 self.assertRaises(TypeError,
1463 setattr, root, 'tail', cdata)
1464 self.assertRaises(TypeError,
1465 root.set, 'attr', cdata)
1466 self.assertRaises(TypeError,
1467 operator.setitem, root.attrib, 'attr', cdata)
1468
1477
1486
1487
1497
1506
1508 Element = self.etree.Element
1509 SubElement = self.etree.SubElement
1510 root = Element('root')
1511 self.assertRaises(ValueError, root.append, root)
1512 child = SubElement(root, 'child')
1513 self.assertRaises(ValueError, child.append, root)
1514 child2 = SubElement(child, 'child2')
1515 self.assertRaises(ValueError, child2.append, root)
1516 self.assertRaises(ValueError, child2.append, child)
1517 self.assertEqual('child2', root[0][0].tag)
1518
1531
1544
1555
1566
1576
1586
1602
1618
1624
1639
1652
1667
1680
1695
1708
1723
1736
1737
1745
1746
1756
1757
1772
1773
1783
1784
1795
1822
1823
1825 self.assertRaises(TypeError, self.etree.dump, None)
1826
1839
1852
1873
1882
1891
1900
1909
1918
1920 XML = self.etree.XML
1921
1922 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1923 result = []
1924 for el in root.iterchildren(tag=['two', 'three']):
1925 result.append(el.text)
1926 self.assertEqual(['Two', 'Bla', None], result)
1927
1929 XML = self.etree.XML
1930
1931 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1932 result = []
1933 for el in root.iterchildren('two', 'three'):
1934 result.append(el.text)
1935 self.assertEqual(['Two', 'Bla', None], result)
1936
1945
1966
1988
1990 Element = self.etree.Element
1991 SubElement = self.etree.SubElement
1992
1993 a = Element('a')
1994 b = SubElement(a, 'b')
1995 c = SubElement(a, 'c')
1996 d = SubElement(b, 'd')
1997 self.assertEqual(
1998 [b, a],
1999 list(d.iterancestors(tag=('a', 'b'))))
2000 self.assertEqual(
2001 [b, a],
2002 list(d.iterancestors('a', 'b')))
2003
2004 self.assertEqual(
2005 [],
2006 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
2007 self.assertEqual(
2008 [],
2009 list(d.iterancestors('w', 'x', 'y', 'z')))
2010
2011 self.assertEqual(
2012 [],
2013 list(d.iterancestors(tag=('d', 'x'))))
2014 self.assertEqual(
2015 [],
2016 list(d.iterancestors('d', 'x')))
2017
2018 self.assertEqual(
2019 [b, a],
2020 list(d.iterancestors(tag=('b', '*'))))
2021 self.assertEqual(
2022 [b, a],
2023 list(d.iterancestors('b', '*')))
2024
2025 self.assertEqual(
2026 [b],
2027 list(d.iterancestors(tag=('b', 'c'))))
2028 self.assertEqual(
2029 [b],
2030 list(d.iterancestors('b', 'c')))
2031
2048
2050 Element = self.etree.Element
2051 SubElement = self.etree.SubElement
2052
2053 a = Element('a')
2054 b = SubElement(a, 'b')
2055 c = SubElement(a, 'c')
2056 d = SubElement(b, 'd')
2057 e = SubElement(c, 'e')
2058
2059 self.assertEqual(
2060 [],
2061 list(a.iterdescendants('a')))
2062 self.assertEqual(
2063 [],
2064 list(a.iterdescendants(tag='a')))
2065
2066 a2 = SubElement(e, 'a')
2067 self.assertEqual(
2068 [a2],
2069 list(a.iterdescendants('a')))
2070
2071 self.assertEqual(
2072 [a2],
2073 list(c.iterdescendants('a')))
2074 self.assertEqual(
2075 [a2],
2076 list(c.iterdescendants(tag='a')))
2077
2079 Element = self.etree.Element
2080 SubElement = self.etree.SubElement
2081
2082 a = Element('a')
2083 b = SubElement(a, 'b')
2084 c = SubElement(a, 'c')
2085 d = SubElement(b, 'd')
2086 e = SubElement(c, 'e')
2087
2088 self.assertEqual(
2089 [b, e],
2090 list(a.iterdescendants(tag=('a', 'b', 'e'))))
2091 self.assertEqual(
2092 [b, e],
2093 list(a.iterdescendants('a', 'b', 'e')))
2094
2095 a2 = SubElement(e, 'a')
2096 self.assertEqual(
2097 [b, a2],
2098 list(a.iterdescendants(tag=('a', 'b'))))
2099 self.assertEqual(
2100 [b, a2],
2101 list(a.iterdescendants('a', 'b')))
2102
2103 self.assertEqual(
2104 [],
2105 list(c.iterdescendants(tag=('x', 'y', 'z'))))
2106 self.assertEqual(
2107 [],
2108 list(c.iterdescendants('x', 'y', 'z')))
2109
2110 self.assertEqual(
2111 [b, d, c, e, a2],
2112 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
2113 self.assertEqual(
2114 [b, d, c, e, a2],
2115 list(a.iterdescendants('x', 'y', 'z', '*')))
2116
2134
2151
2169
2193
2195 Element = self.etree.Element
2196 SubElement = self.etree.SubElement
2197
2198 a = Element('a')
2199 b = SubElement(a, 'b')
2200 c = SubElement(a, 'c')
2201 d = SubElement(b, 'd')
2202 self.assertEqual(
2203 [],
2204 list(a.itersiblings(tag='XXX')))
2205 self.assertEqual(
2206 [c],
2207 list(b.itersiblings(tag='c')))
2208 self.assertEqual(
2209 [c],
2210 list(b.itersiblings(tag='*')))
2211 self.assertEqual(
2212 [b],
2213 list(c.itersiblings(preceding=True, tag='b')))
2214 self.assertEqual(
2215 [],
2216 list(c.itersiblings(preceding=True, tag='c')))
2217
2219 Element = self.etree.Element
2220 SubElement = self.etree.SubElement
2221
2222 a = Element('a')
2223 b = SubElement(a, 'b')
2224 c = SubElement(a, 'c')
2225 d = SubElement(b, 'd')
2226 e = SubElement(a, 'e')
2227 self.assertEqual(
2228 [],
2229 list(a.itersiblings(tag=('XXX', 'YYY'))))
2230 self.assertEqual(
2231 [c, e],
2232 list(b.itersiblings(tag=('c', 'd', 'e'))))
2233 self.assertEqual(
2234 [b],
2235 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2236 self.assertEqual(
2237 [c, b],
2238 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2239
2241 parseid = self.etree.parseid
2242 XML = self.etree.XML
2243 xml_text = _bytes('''
2244 <!DOCTYPE document [
2245 <!ELEMENT document (h1,p)*>
2246 <!ELEMENT h1 (#PCDATA)>
2247 <!ATTLIST h1 myid ID #REQUIRED>
2248 <!ELEMENT p (#PCDATA)>
2249 <!ATTLIST p someid ID #REQUIRED>
2250 ]>
2251 <document>
2252 <h1 myid="chapter1">...</h1>
2253 <p id="note1" class="note">...</p>
2254 <p>Regular paragraph.</p>
2255 <p xml:id="xmlid">XML:ID paragraph.</p>
2256 <p someid="warn1" class="warning">...</p>
2257 </document>
2258 ''')
2259
2260 tree, dic = parseid(BytesIO(xml_text))
2261 root = tree.getroot()
2262 root2 = XML(xml_text)
2263 self.assertEqual(self._writeElement(root),
2264 self._writeElement(root2))
2265 expected = {
2266 "chapter1" : root[0],
2267 "xmlid" : root[3],
2268 "warn1" : root[4]
2269 }
2270 self.assertTrue("chapter1" in dic)
2271 self.assertTrue("warn1" in dic)
2272 self.assertTrue("xmlid" in dic)
2273 self._checkIDDict(dic, expected)
2274
2276 XMLDTDID = self.etree.XMLDTDID
2277 XML = self.etree.XML
2278 xml_text = _bytes('''
2279 <!DOCTYPE document [
2280 <!ELEMENT document (h1,p)*>
2281 <!ELEMENT h1 (#PCDATA)>
2282 <!ATTLIST h1 myid ID #REQUIRED>
2283 <!ELEMENT p (#PCDATA)>
2284 <!ATTLIST p someid ID #REQUIRED>
2285 ]>
2286 <document>
2287 <h1 myid="chapter1">...</h1>
2288 <p id="note1" class="note">...</p>
2289 <p>Regular paragraph.</p>
2290 <p xml:id="xmlid">XML:ID paragraph.</p>
2291 <p someid="warn1" class="warning">...</p>
2292 </document>
2293 ''')
2294
2295 root, dic = XMLDTDID(xml_text)
2296 root2 = XML(xml_text)
2297 self.assertEqual(self._writeElement(root),
2298 self._writeElement(root2))
2299 expected = {
2300 "chapter1" : root[0],
2301 "xmlid" : root[3],
2302 "warn1" : root[4]
2303 }
2304 self.assertTrue("chapter1" in dic)
2305 self.assertTrue("warn1" in dic)
2306 self.assertTrue("xmlid" in dic)
2307 self._checkIDDict(dic, expected)
2308
2310 XMLDTDID = self.etree.XMLDTDID
2311 XML = self.etree.XML
2312 xml_text = _bytes('''
2313 <document>
2314 <h1 myid="chapter1">...</h1>
2315 <p id="note1" class="note">...</p>
2316 <p>Regular paragraph.</p>
2317 <p someid="warn1" class="warning">...</p>
2318 </document>
2319 ''')
2320
2321 root, dic = XMLDTDID(xml_text)
2322 root2 = XML(xml_text)
2323 self.assertEqual(self._writeElement(root),
2324 self._writeElement(root2))
2325 expected = {}
2326 self._checkIDDict(dic, expected)
2327
2329 XMLDTDID = self.etree.XMLDTDID
2330 XML = self.etree.XML
2331 xml_text = _bytes('''
2332 <!DOCTYPE document [
2333 <!ELEMENT document (h1,p)*>
2334 <!ELEMENT h1 (#PCDATA)>
2335 <!ATTLIST h1 myid ID #REQUIRED>
2336 <!ELEMENT p (#PCDATA)>
2337 <!ATTLIST p someid ID #REQUIRED>
2338 ]>
2339 <document>
2340 <h1 myid="chapter1">...</h1>
2341 <p id="note1" class="note">...</p>
2342 <p>Regular paragraph.</p>
2343 <p xml:id="xmlid">XML:ID paragraph.</p>
2344 <p someid="warn1" class="warning">...</p>
2345 </document>
2346 ''')
2347
2348 parser = etree.XMLParser(collect_ids=False)
2349 root, dic = XMLDTDID(xml_text, parser=parser)
2350 root2 = XML(xml_text)
2351 self.assertEqual(self._writeElement(root),
2352 self._writeElement(root2))
2353 self.assertFalse(dic)
2354 self._checkIDDict(dic, {})
2355
2357 self.assertEqual(len(dic),
2358 len(expected))
2359 self.assertEqual(sorted(dic.items()),
2360 sorted(expected.items()))
2361 if sys.version_info < (3,):
2362 self.assertEqual(sorted(dic.iteritems()),
2363 sorted(expected.iteritems()))
2364 self.assertEqual(sorted(dic.keys()),
2365 sorted(expected.keys()))
2366 if sys.version_info < (3,):
2367 self.assertEqual(sorted(dic.iterkeys()),
2368 sorted(expected.iterkeys()))
2369 if sys.version_info < (3,):
2370 self.assertEqual(sorted(dic.values()),
2371 sorted(expected.values()))
2372 self.assertEqual(sorted(dic.itervalues()),
2373 sorted(expected.itervalues()))
2374
2376 etree = self.etree
2377
2378 r = {'foo': 'http://ns.infrae.com/foo'}
2379 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2380 self.assertEqual(
2381 'foo',
2382 e.prefix)
2383 self.assertEqual(
2384 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2385 self._writeElement(e))
2386
2388 etree = self.etree
2389
2390 r = {None: 'http://ns.infrae.com/foo'}
2391 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2392 self.assertEqual(
2393 None,
2394 e.prefix)
2395 self.assertEqual(
2396 '{http://ns.infrae.com/foo}bar',
2397 e.tag)
2398 self.assertEqual(
2399 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2400 self._writeElement(e))
2401
2403 etree = self.etree
2404
2405 r = {None: 'http://ns.infrae.com/foo',
2406 'hoi': 'http://ns.infrae.com/hoi'}
2407 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2408 e.set('{http://ns.infrae.com/hoi}test', 'value')
2409 self.assertEqual(
2410 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2411 self._writeElement(e))
2412
2414 etree = self.etree
2415
2416 root = etree.Element('{http://test/ns}root',
2417 nsmap={None: 'http://test/ns'})
2418 sub = etree.Element('{http://test/ns}sub',
2419 nsmap={'test': 'http://test/ns'})
2420
2421 sub.attrib['{http://test/ns}attr'] = 'value'
2422 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2423 self.assertEqual(
2424 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2425 etree.tostring(sub))
2426
2427 root.append(sub)
2428 self.assertEqual(
2429 _bytes('<root xmlns="http://test/ns">'
2430 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2431 '</root>'),
2432 etree.tostring(root))
2433
2435 etree = self.etree
2436
2437 root = etree.Element('root')
2438 sub = etree.Element('{http://test/ns}sub',
2439 nsmap={'test': 'http://test/ns'})
2440
2441 sub.attrib['{http://test/ns}attr'] = 'value'
2442 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2443 self.assertEqual(
2444 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2445 etree.tostring(sub))
2446
2447 root.append(sub)
2448 self.assertEqual(
2449 _bytes('<root>'
2450 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2451 '</root>'),
2452 etree.tostring(root))
2453
2455 etree = self.etree
2456
2457 root = etree.Element('root')
2458 sub = etree.Element('{http://test/ns}sub',
2459 nsmap={None: 'http://test/ns'})
2460
2461 sub.attrib['{http://test/ns}attr'] = 'value'
2462 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2463 self.assertEqual(
2464 _bytes('<sub xmlns="http://test/ns" '
2465 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2466 etree.tostring(sub))
2467
2468 root.append(sub)
2469 self.assertEqual(
2470 _bytes('<root>'
2471 '<sub xmlns="http://test/ns"'
2472 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2473 '</root>'),
2474 etree.tostring(root))
2475
2477 etree = self.etree
2478
2479 root = etree.Element('{http://test/ns}root',
2480 nsmap={'test': 'http://test/ns',
2481 None: 'http://test/ns'})
2482 sub = etree.Element('{http://test/ns}sub',
2483 nsmap={None: 'http://test/ns'})
2484
2485 sub.attrib['{http://test/ns}attr'] = 'value'
2486 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2487 self.assertEqual(
2488 _bytes('<sub xmlns="http://test/ns" '
2489 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2490 etree.tostring(sub))
2491
2492 root.append(sub)
2493 self.assertEqual(
2494 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2495 '<test:sub test:attr="value"/>'
2496 '</test:root>'),
2497 etree.tostring(root))
2498
2500 etree = self.etree
2501 r = {None: 'http://ns.infrae.com/foo',
2502 'hoi': 'http://ns.infrae.com/hoi'}
2503 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2504 tree = etree.ElementTree(element=e)
2505 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2506 self.assertEqual(
2507 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2508 self._writeElement(e))
2509
2511 etree = self.etree
2512
2513 r = {None: 'http://ns.infrae.com/foo'}
2514 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2515 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2516
2517 e1.append(e2)
2518
2519 self.assertEqual(
2520 None,
2521 e1.prefix)
2522 self.assertEqual(
2523 None,
2524 e1[0].prefix)
2525 self.assertEqual(
2526 '{http://ns.infrae.com/foo}bar',
2527 e1.tag)
2528 self.assertEqual(
2529 '{http://ns.infrae.com/foo}bar',
2530 e1[0].tag)
2531
2533 etree = self.etree
2534
2535 r = {None: 'http://ns.infrae.com/BAR'}
2536 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2537 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2538
2539 e1.append(e2)
2540
2541 self.assertEqual(
2542 None,
2543 e1.prefix)
2544 self.assertNotEqual(
2545 None,
2546 e2.prefix)
2547 self.assertEqual(
2548 '{http://ns.infrae.com/BAR}bar',
2549 e1.tag)
2550 self.assertEqual(
2551 '{http://ns.infrae.com/foo}bar',
2552 e2.tag)
2553
2555 ns_href = "http://a.b.c"
2556 one = self.etree.fromstring(
2557 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2558 baz = one[0][0]
2559
2560 two = self.etree.fromstring(
2561 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2562 two.append(baz)
2563 del one
2564
2565 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2566 self.assertEqual(
2567 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2568 self.etree.tostring(two))
2569
2579
2581 etree = self.etree
2582
2583 r = {None: 'http://ns.infrae.com/foo',
2584 'hoi': 'http://ns.infrae.com/hoi'}
2585 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2586 self.assertEqual(
2587 r,
2588 e.nsmap)
2589
2591 etree = self.etree
2592
2593 re = {None: 'http://ns.infrae.com/foo',
2594 'hoi': 'http://ns.infrae.com/hoi'}
2595 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2596
2597 rs = {None: 'http://ns.infrae.com/honk',
2598 'top': 'http://ns.infrae.com/top'}
2599 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2600
2601 r = re.copy()
2602 r.update(rs)
2603 self.assertEqual(re, e.nsmap)
2604 self.assertEqual(r, s.nsmap)
2605
2607 etree = self.etree
2608 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2609 self.assertEqual({'hha': None}, el.nsmap)
2610
2612 Element = self.etree.Element
2613 SubElement = self.etree.SubElement
2614
2615 a = Element('a')
2616 b = SubElement(a, 'b')
2617 c = SubElement(a, 'c')
2618 d = SubElement(b, 'd')
2619 e = SubElement(c, 'e')
2620 f = SubElement(c, 'f')
2621
2622 self.assertEqual(
2623 [a, b],
2624 list(a.getiterator('a', 'b')))
2625 self.assertEqual(
2626 [],
2627 list(a.getiterator('x', 'y')))
2628 self.assertEqual(
2629 [a, f],
2630 list(a.getiterator('f', 'a')))
2631 self.assertEqual(
2632 [c, e, f],
2633 list(c.getiterator('c', '*', 'a')))
2634 self.assertEqual(
2635 [],
2636 list(a.getiterator( (), () )))
2637
2639 Element = self.etree.Element
2640 SubElement = self.etree.SubElement
2641
2642 a = Element('a')
2643 b = SubElement(a, 'b')
2644 c = SubElement(a, 'c')
2645 d = SubElement(b, 'd')
2646 e = SubElement(c, 'e')
2647 f = SubElement(c, 'f')
2648
2649 self.assertEqual(
2650 [a, b],
2651 list(a.getiterator( ('a', 'b') )))
2652 self.assertEqual(
2653 [],
2654 list(a.getiterator( ('x', 'y') )))
2655 self.assertEqual(
2656 [a, f],
2657 list(a.getiterator( ('f', 'a') )))
2658 self.assertEqual(
2659 [c, e, f],
2660 list(c.getiterator( ('c', '*', 'a') )))
2661 self.assertEqual(
2662 [],
2663 list(a.getiterator( () )))
2664
2666 Element = self.etree.Element
2667 SubElement = self.etree.SubElement
2668
2669 a = Element('{a}a')
2670 b = SubElement(a, '{a}b')
2671 c = SubElement(a, '{a}c')
2672 d = SubElement(b, '{b}d')
2673 e = SubElement(c, '{a}e')
2674 f = SubElement(c, '{b}f')
2675 g = SubElement(c, 'g')
2676
2677 self.assertEqual(
2678 [a],
2679 list(a.getiterator('{a}a')))
2680 self.assertEqual(
2681 [],
2682 list(a.getiterator('{b}a')))
2683 self.assertEqual(
2684 [],
2685 list(a.getiterator('a')))
2686 self.assertEqual(
2687 [a,b,d,c,e,f,g],
2688 list(a.getiterator('*')))
2689 self.assertEqual(
2690 [f],
2691 list(c.getiterator('{b}*')))
2692 self.assertEqual(
2693 [d, f],
2694 list(a.getiterator('{b}*')))
2695 self.assertEqual(
2696 [g],
2697 list(a.getiterator('g')))
2698 self.assertEqual(
2699 [g],
2700 list(a.getiterator('{}g')))
2701 self.assertEqual(
2702 [g],
2703 list(a.getiterator('{}*')))
2704
2706 Element = self.etree.Element
2707 SubElement = self.etree.SubElement
2708
2709 a = Element('{a}a')
2710 b = SubElement(a, '{nsA}b')
2711 c = SubElement(b, '{nsB}b')
2712 d = SubElement(a, 'b')
2713 e = SubElement(a, '{nsA}e')
2714 f = SubElement(e, '{nsB}e')
2715 g = SubElement(e, 'e')
2716
2717 self.assertEqual(
2718 [b, c, d],
2719 list(a.getiterator('{*}b')))
2720 self.assertEqual(
2721 [e, f, g],
2722 list(a.getiterator('{*}e')))
2723 self.assertEqual(
2724 [a, b, c, d, e, f, g],
2725 list(a.getiterator('{*}*')))
2726
2751
2767
2784
2786 a = etree.Element("a")
2787 b = etree.SubElement(a, "b")
2788 c = etree.SubElement(a, "c")
2789 d1 = etree.SubElement(c, "d")
2790 d2 = etree.SubElement(c, "d")
2791 c.text = d1.text = 'TEXT'
2792
2793 tree = etree.ElementTree(a)
2794 self.assertEqual('.', tree.getelementpath(a))
2795 self.assertEqual('c/d[1]', tree.getelementpath(d1))
2796 self.assertEqual('c/d[2]', tree.getelementpath(d2))
2797
2798 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
2799 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
2800
2801 tree = etree.ElementTree(c)
2802 self.assertEqual('.', tree.getelementpath(c))
2803 self.assertEqual('d[2]', tree.getelementpath(d2))
2804 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
2805
2806 tree = etree.ElementTree(b)
2807 self.assertEqual('.', tree.getelementpath(b))
2808 self.assertRaises(ValueError, tree.getelementpath, a)
2809 self.assertRaises(ValueError, tree.getelementpath, c)
2810 self.assertRaises(ValueError, tree.getelementpath, d2)
2811
2813 a = etree.Element("{http://ns1/}a")
2814 b = etree.SubElement(a, "{http://ns1/}b")
2815 c = etree.SubElement(a, "{http://ns1/}c")
2816 d1 = etree.SubElement(c, "{http://ns1/}d")
2817 d2 = etree.SubElement(c, "{http://ns2/}d")
2818 d3 = etree.SubElement(c, "{http://ns1/}d")
2819
2820 tree = etree.ElementTree(a)
2821 self.assertEqual('.', tree.getelementpath(a))
2822 self.assertEqual('{http://ns1/}c/{http://ns1/}d[1]',
2823 tree.getelementpath(d1))
2824 self.assertEqual('{http://ns1/}c/{http://ns2/}d',
2825 tree.getelementpath(d2))
2826 self.assertEqual('{http://ns1/}c/{http://ns1/}d[2]',
2827 tree.getelementpath(d3))
2828
2829 self.assertEqual(a, tree.find(tree.getelementpath(a)))
2830 self.assertEqual(b, tree.find(tree.getelementpath(b)))
2831 self.assertEqual(c, tree.find(tree.getelementpath(c)))
2832 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
2833 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
2834 self.assertEqual(d3, tree.find(tree.getelementpath(d3)))
2835
2836 tree = etree.ElementTree(c)
2837 self.assertEqual('{http://ns1/}d[1]', tree.getelementpath(d1))
2838 self.assertEqual('{http://ns2/}d', tree.getelementpath(d2))
2839 self.assertEqual('{http://ns1/}d[2]', tree.getelementpath(d3))
2840 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
2841 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
2842 self.assertEqual(d3, tree.find(tree.getelementpath(d3)))
2843
2844 tree = etree.ElementTree(b)
2845 self.assertRaises(ValueError, tree.getelementpath, d1)
2846 self.assertRaises(ValueError, tree.getelementpath, d2)
2847
2854
2861
2870
2872 XML = self.etree.XML
2873 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2874 self.assertEqual(len(root.findall(".//{X}b")), 2)
2875 self.assertEqual(len(root.findall(".//{X}*")), 2)
2876 self.assertEqual(len(root.findall(".//b")), 3)
2877
2879 XML = self.etree.XML
2880 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2881 nsmap = {'xx': 'X'}
2882 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2883 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2884 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2885 nsmap = {'xx': 'Y'}
2886 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2887 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2888 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2889
2891 XML = self.etree.XML
2892 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2893 nsmap = {'xx': 'X'}
2894 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2895 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2896 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2897 nsmap = {'xx': 'Y'}
2898 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2899 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2900 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2901
2908
2910 etree = self.etree
2911 e = etree.Element('foo')
2912 for i in range(10):
2913 etree.SubElement(e, 'a%s' % i)
2914 for i in range(10):
2915 self.assertEqual(
2916 i,
2917 e.index(e[i]))
2918 self.assertEqual(
2919 3, e.index(e[3], 3))
2920 self.assertRaises(
2921 ValueError, e.index, e[3], 4)
2922 self.assertRaises(
2923 ValueError, e.index, e[3], 0, 2)
2924 self.assertRaises(
2925 ValueError, e.index, e[8], 0, -3)
2926 self.assertRaises(
2927 ValueError, e.index, e[8], -5, -3)
2928 self.assertEqual(
2929 8, e.index(e[8], 0, -1))
2930 self.assertEqual(
2931 8, e.index(e[8], -12, -1))
2932 self.assertEqual(
2933 0, e.index(e[0], -12, -1))
2934
2936 etree = self.etree
2937 e = etree.Element('foo')
2938 for i in range(10):
2939 el = etree.SubElement(e, 'a%s' % i)
2940 el.text = "text%d" % i
2941 el.tail = "tail%d" % i
2942
2943 child0 = e[0]
2944 child1 = e[1]
2945 child2 = e[2]
2946
2947 e.replace(e[0], e[1])
2948 self.assertEqual(
2949 9, len(e))
2950 self.assertEqual(
2951 child1, e[0])
2952 self.assertEqual(
2953 child1.text, "text1")
2954 self.assertEqual(
2955 child1.tail, "tail1")
2956 self.assertEqual(
2957 child0.tail, "tail0")
2958 self.assertEqual(
2959 child2, e[1])
2960
2961 e.replace(e[-1], e[0])
2962 self.assertEqual(
2963 child1, e[-1])
2964 self.assertEqual(
2965 child1.text, "text1")
2966 self.assertEqual(
2967 child1.tail, "tail1")
2968 self.assertEqual(
2969 child2, e[0])
2970
2972 etree = self.etree
2973 e = etree.Element('foo')
2974 for i in range(10):
2975 etree.SubElement(e, 'a%s' % i)
2976
2977 new_element = etree.Element("test")
2978 new_element.text = "TESTTEXT"
2979 new_element.tail = "TESTTAIL"
2980 child1 = e[1]
2981 e.replace(e[0], new_element)
2982 self.assertEqual(
2983 new_element, e[0])
2984 self.assertEqual(
2985 "TESTTEXT",
2986 e[0].text)
2987 self.assertEqual(
2988 "TESTTAIL",
2989 e[0].tail)
2990 self.assertEqual(
2991 child1, e[1])
2992
3008
3026
3044
3062
3064 Element = self.etree.Element
3065 SubElement = self.etree.SubElement
3066 try:
3067 slice
3068 except NameError:
3069 print("slice() not found")
3070 return
3071
3072 a = Element('a')
3073 b = SubElement(a, 'b')
3074 c = SubElement(a, 'c')
3075 d = SubElement(a, 'd')
3076 e = SubElement(a, 'e')
3077
3078 x = Element('x')
3079 y = Element('y')
3080 z = Element('z')
3081
3082 self.assertRaises(
3083 ValueError,
3084 operator.setitem, a, slice(1,None,2), [x, y, z])
3085
3086 self.assertEqual(
3087 [b, c, d, e],
3088 list(a))
3089
3102
3104 XML = self.etree.XML
3105 root = XML(_bytes(
3106 '<?xml version="1.0"?>\n'
3107 '<root>' + '\n' * 65536 +
3108 '<p>' + '\n' * 65536 + '</p>\n' +
3109 '<br/>\n'
3110 '</root>'))
3111
3112 if self.etree.LIBXML_VERSION >= (2, 9):
3113 expected = [2, 131074, 131076]
3114 else:
3115 expected = [2, 65535, 65535]
3116
3117 self.assertEqual(expected, [el.sourceline for el in root.iter()])
3118
3126
3135
3145
3155
3161
3169
3175
3182
3188
3190 etree = self.etree
3191 xml_header = '<?xml version="1.0" encoding="ascii"?>'
3192 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3193 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3194 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
3195
3196 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3197
3198 tree = etree.parse(BytesIO(xml))
3199 docinfo = tree.docinfo
3200 self.assertEqual(docinfo.encoding, "ascii")
3201 self.assertEqual(docinfo.xml_version, "1.0")
3202 self.assertEqual(docinfo.public_id, pub_id)
3203 self.assertEqual(docinfo.system_url, sys_id)
3204 self.assertEqual(docinfo.root_name, 'html')
3205 self.assertEqual(docinfo.doctype, doctype_string)
3206
3222
3234
3246
3252
3254 etree = self.etree
3255 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3256 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3257 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
3258
3259 xml = _bytes('<!DOCTYPE root>\n<root/>')
3260 tree = etree.parse(BytesIO(xml))
3261 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
3262 etree.tostring(tree, doctype=doctype_string))
3263
3265 etree = self.etree
3266 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3267 self.assertEqual(root.base, "http://no/such/url")
3268 self.assertEqual(
3269 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3270 root.base = "https://secret/url"
3271 self.assertEqual(root.base, "https://secret/url")
3272 self.assertEqual(
3273 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3274 "https://secret/url")
3275
3277 etree = self.etree
3278 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3279 self.assertEqual(root.base, "http://no/such/url")
3280 self.assertEqual(
3281 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3282 root.set('{http://www.w3.org/XML/1998/namespace}base',
3283 "https://secret/url")
3284 self.assertEqual(root.base, "https://secret/url")
3285 self.assertEqual(
3286 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3287 "https://secret/url")
3288
3294
3299
3306
3320
3322 Element = self.etree.Element
3323
3324 a = Element('a')
3325 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3326 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3327
3328 self.assertRaises(ValueError, Element, 'ha\0ho')
3329
3331 Element = self.etree.Element
3332
3333 a = Element('a')
3334 self.assertRaises(ValueError, setattr, a, "text",
3335 _str('ha\0ho'))
3336 self.assertRaises(ValueError, setattr, a, "tail",
3337 _str('ha\0ho'))
3338
3339 self.assertRaises(ValueError, Element,
3340 _str('ha\0ho'))
3341
3343 Element = self.etree.Element
3344
3345 a = Element('a')
3346 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3347 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3348
3349 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3350 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3351
3352 self.assertRaises(ValueError, Element, 'ha\x07ho')
3353 self.assertRaises(ValueError, Element, 'ha\x02ho')
3354
3356 Element = self.etree.Element
3357
3358 a = Element('a')
3359 self.assertRaises(ValueError, setattr, a, "text",
3360 _str('ha\x07ho'))
3361 self.assertRaises(ValueError, setattr, a, "text",
3362 _str('ha\x02ho'))
3363
3364 self.assertRaises(ValueError, setattr, a, "tail",
3365 _str('ha\x07ho'))
3366 self.assertRaises(ValueError, setattr, a, "tail",
3367 _str('ha\x02ho'))
3368
3369 self.assertRaises(ValueError, Element,
3370 _str('ha\x07ho'))
3371 self.assertRaises(ValueError, Element,
3372 _str('ha\x02ho'))
3373
3375 Element = self.etree.Element
3376
3377 a = Element('a')
3378 self.assertRaises(ValueError, setattr, a, "text",
3379 _str('ha\u1234\x07ho'))
3380 self.assertRaises(ValueError, setattr, a, "text",
3381 _str('ha\u1234\x02ho'))
3382
3383 self.assertRaises(ValueError, setattr, a, "tail",
3384 _str('ha\u1234\x07ho'))
3385 self.assertRaises(ValueError, setattr, a, "tail",
3386 _str('ha\u1234\x02ho'))
3387
3388 self.assertRaises(ValueError, Element,
3389 _str('ha\u1234\x07ho'))
3390 self.assertRaises(ValueError, Element,
3391 _str('ha\u1234\x02ho'))
3392
3406
3411
3429
3449
3451 tostring = self.etree.tostring
3452 html = self.etree.fromstring(
3453 '<html><body>'
3454 '<div><p>Some text<i>\r\n</i></p></div>\r\n'
3455 '</body></html>',
3456 parser=self.etree.HTMLParser())
3457 self.assertEqual(html.tag, 'html')
3458 div = html.find('.//div')
3459 self.assertEqual(div.tail, '\r\n')
3460 result = tostring(div, method='html')
3461 self.assertEqual(
3462 result,
3463 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3464 result = tostring(div, method='html', with_tail=True)
3465 self.assertEqual(
3466 result,
3467 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3468 result = tostring(div, method='html', with_tail=False)
3469 self.assertEqual(
3470 result,
3471 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3472
3494
3496 tostring = self.etree.tostring
3497 XML = self.etree.XML
3498 ElementTree = self.etree.ElementTree
3499
3500 root = XML(_bytes("<root/>"))
3501
3502 tree = ElementTree(root)
3503 self.assertEqual(None, tree.docinfo.standalone)
3504
3505 result = tostring(root, xml_declaration=True, encoding="ASCII")
3506 self.assertEqual(result, _bytes(
3507 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3508
3509 result = tostring(root, xml_declaration=True, encoding="ASCII",
3510 standalone=True)
3511 self.assertEqual(result, _bytes(
3512 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3513
3514 tree = ElementTree(XML(result))
3515 self.assertEqual(True, tree.docinfo.standalone)
3516
3517 result = tostring(root, xml_declaration=True, encoding="ASCII",
3518 standalone=False)
3519 self.assertEqual(result, _bytes(
3520 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3521
3522 tree = ElementTree(XML(result))
3523 self.assertEqual(False, tree.docinfo.standalone)
3524
3544
3546 tostring = self.etree.tostring
3547 Element = self.etree.Element
3548 SubElement = self.etree.SubElement
3549
3550 a = Element('a')
3551 a.text = "A"
3552 a.tail = "tail"
3553 b = SubElement(a, 'b')
3554 b.text = "B"
3555 b.tail = _str("Søk på nettet")
3556 c = SubElement(a, 'c')
3557 c.text = "C"
3558
3559 result = tostring(a, method="text", encoding="UTF-16")
3560
3561 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3562 result)
3563
3565 tostring = self.etree.tostring
3566 Element = self.etree.Element
3567 SubElement = self.etree.SubElement
3568
3569 a = Element('a')
3570 a.text = _str('Søk på nettetA')
3571 a.tail = "tail"
3572 b = SubElement(a, 'b')
3573 b.text = "B"
3574 b.tail = _str('Søk på nettetB')
3575 c = SubElement(a, 'c')
3576 c.text = "C"
3577
3578 self.assertRaises(UnicodeEncodeError,
3579 tostring, a, method="text")
3580
3581 self.assertEqual(
3582 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3583 tostring(a, encoding="UTF-8", method="text"))
3584
3597
3613
3617
3632
3650
3663
3665 tostring = self.etree.tostring
3666 Element = self.etree.Element
3667 SubElement = self.etree.SubElement
3668
3669 a = Element('a')
3670 b = SubElement(a, 'b')
3671 c = SubElement(a, 'c')
3672 d = SubElement(c, 'd')
3673 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3674 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3675 self.assertEqual(_bytes('<b></b>'),
3676 canonicalize(tostring(b, encoding=_unicode)))
3677 self.assertEqual(_bytes('<c><d></d></c>'),
3678 canonicalize(tostring(c, encoding=_unicode)))
3679
3684
3699
3701 tostring = self.etree.tostring
3702 Element = self.etree.Element
3703 SubElement = self.etree.SubElement
3704
3705 a = Element('a')
3706 b = SubElement(a, 'b')
3707 c = SubElement(a, 'c')
3708
3709 result = tostring(a, encoding=_unicode)
3710 self.assertEqual(result, "<a><b/><c/></a>")
3711
3712 result = tostring(a, encoding=_unicode, pretty_print=False)
3713 self.assertEqual(result, "<a><b/><c/></a>")
3714
3715 result = tostring(a, encoding=_unicode, pretty_print=True)
3716 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3717
3729
3731 class SubEl(etree.ElementBase):
3732 pass
3733
3734 el1 = SubEl()
3735 el2 = SubEl()
3736 self.assertEqual('SubEl', el1.tag)
3737 self.assertEqual('SubEl', el2.tag)
3738 el1.other = el2
3739 el2.other = el1
3740
3741 del el1, el2
3742 gc.collect()
3743
3744
3758
3760 root = etree.Element('parent')
3761 c1 = etree.SubElement(root, 'child1')
3762 c2 = etree.SubElement(root, 'child2')
3763
3764 root.remove(c1)
3765 root.remove(c2)
3766 c1.addnext(c2)
3767 c1.tail = 'abc'
3768 c2.tail = 'xyz'
3769 del c1
3770
3771 c2.getprevious()
3772
3773 self.assertEqual('child1', c2.getprevious().tag)
3774 self.assertEqual('abc', c2.getprevious().tail)
3775
3776
3777
3778 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3789
3790
3834
3835 res_instance = res()
3836 parser = etree.XMLParser(load_dtd = True)
3837 parser.resolvers.add(res_instance)
3838
3839 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3840 parser = parser)
3841
3842 self.include(tree)
3843
3844 called = list(res_instance.called.items())
3845 called.sort()
3846 self.assertEqual(
3847 [("dtd", True), ("include", True), ("input", True)],
3848 called)
3849
3851 data = textwrap.dedent('''
3852 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3853 <foo/>
3854 <xi:include href="./test.xml" />
3855 </doc>
3856 ''')
3857
3858 class Resolver(etree.Resolver):
3859 called = {}
3860
3861 def resolve(self, url, id, context):
3862 if url.endswith("test_xinclude.xml"):
3863 assert not self.called.get("input")
3864 self.called["input"] = True
3865 return None
3866 elif url.endswith('/test5.xml'):
3867 assert not self.called.get("DONE")
3868 self.called["DONE"] = True
3869 return self.resolve_string('<DONE/>', context)
3870 else:
3871 _, filename = url.rsplit('/', 1)
3872 assert not self.called.get(filename)
3873 self.called[filename] = True
3874 next_data = data.replace(
3875 'test.xml', 'test%d.xml' % len(self.called))
3876 return self.resolve_string(next_data, context)
3877
3878 res_instance = Resolver()
3879 parser = etree.XMLParser(load_dtd=True)
3880 parser.resolvers.add(res_instance)
3881
3882 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3883 parser=parser)
3884
3885 self.include(tree)
3886
3887 called = list(res_instance.called.items())
3888 called.sort()
3889 self.assertEqual(
3890 [("DONE", True), ("input", True), ("test.xml", True),
3891 ("test2.xml", True), ("test3.xml", True), ("test4.xml", True)],
3892 called)
3893
3894
3898
3899
3904
3905
3908 tree = self.parse(_bytes('<a><b/></a>'))
3909 f = BytesIO()
3910 tree.write_c14n(f)
3911 s = f.getvalue()
3912 self.assertEqual(_bytes('<a><b></b></a>'),
3913 s)
3914
3916 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3917 f = BytesIO()
3918 tree.write_c14n(f, compression=9)
3919 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3920 try:
3921 s = gzfile.read()
3922 finally:
3923 gzfile.close()
3924 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3925 s)
3926
3938
3954
3972
3984
3996
3998 tree = self.parse(_bytes(
3999 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4000 f = BytesIO()
4001 tree.write_c14n(f)
4002 s = f.getvalue()
4003 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4004 s)
4005 f = BytesIO()
4006 tree.write_c14n(f, exclusive=False)
4007 s = f.getvalue()
4008 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4009 s)
4010 f = BytesIO()
4011 tree.write_c14n(f, exclusive=True)
4012 s = f.getvalue()
4013 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4014 s)
4015
4016 f = BytesIO()
4017 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
4018 s = f.getvalue()
4019 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
4020 s)
4021
4023 tree = self.parse(_bytes(
4024 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4025 s = etree.tostring(tree, method='c14n')
4026 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4027 s)
4028 s = etree.tostring(tree, method='c14n', exclusive=False)
4029 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4030 s)
4031 s = etree.tostring(tree, method='c14n', exclusive=True)
4032 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4033 s)
4034
4035 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
4036 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
4037 s)
4038
4040 tree = self.parse(_bytes(
4041 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4042 s = etree.tostring(tree.getroot(), method='c14n')
4043 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4044 s)
4045 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
4046 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4047 s)
4048 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
4049 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4050 s)
4051
4052 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
4053 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
4054 s)
4055 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
4056 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
4057 s)
4058
4059 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
4060 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
4061 s)
4062
4064 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
4065 tree = self.parse(_bytes(
4066 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4067
4068 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
4069 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4070 s)
4071
4072
4075 tree = self.parse(_bytes('<a><b/></a>'))
4076 f = BytesIO()
4077 tree.write(f)
4078 s = f.getvalue()
4079 self.assertEqual(_bytes('<a><b/></a>'),
4080 s)
4081
4083 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4084 f = BytesIO()
4085 tree.write(f, compression=9)
4086 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
4087 try:
4088 s = gzfile.read()
4089 finally:
4090 gzfile.close()
4091 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4092 s)
4093
4095 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4096 f = BytesIO()
4097 tree.write(f, compression=0)
4098 s0 = f.getvalue()
4099
4100 f = BytesIO()
4101 tree.write(f)
4102 self.assertEqual(f.getvalue(), s0)
4103
4104 f = BytesIO()
4105 tree.write(f, compression=1)
4106 s = f.getvalue()
4107 self.assertTrue(len(s) <= len(s0))
4108 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
4109 try:
4110 s1 = gzfile.read()
4111 finally:
4112 gzfile.close()
4113
4114 f = BytesIO()
4115 tree.write(f, compression=9)
4116 s = f.getvalue()
4117 self.assertTrue(len(s) <= len(s0))
4118 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
4119 try:
4120 s9 = gzfile.read()
4121 finally:
4122 gzfile.close()
4123
4124 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4125 s0)
4126 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4127 s1)
4128 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4129 s9)
4130
4142
4158
4170
4183
4185 etree = etree
4186
4208
4210 """This can't really be tested as long as there isn't a way to
4211 reset the logging setup ...
4212 """
4213 parse = self.etree.parse
4214
4215 messages = []
4216 class Logger(self.etree.PyErrorLog):
4217 def log(self, entry, message, *args):
4218 messages.append(message)
4219
4220 self.etree.use_global_python_log(Logger())
4221 f = BytesIO('<a><b></c></b></a>')
4222 try:
4223 parse(f)
4224 except SyntaxError:
4225 pass
4226 f.close()
4227
4228 self.assertTrue([ message for message in messages
4229 if 'mismatch' in message ])
4230 self.assertTrue([ message for message in messages
4231 if ':PARSER:' in message])
4232 self.assertTrue([ message for message in messages
4233 if ':ERR_TAG_NAME_MISMATCH:' in message ])
4234 self.assertTrue([ message for message in messages
4235 if ':1:15:' in message ])
4236
4237
4239 etree = etree
4240
4244
4246 class Target(object):
4247 def start(self, tag, attrib):
4248 return 'start(%s)' % tag
4249 def end(self, tag):
4250 return 'end(%s)' % tag
4251 def close(self):
4252 return 'close()'
4253
4254 parser = self.etree.XMLPullParser(target=Target())
4255 events = parser.read_events()
4256
4257 parser.feed('<root><element>')
4258 self.assertFalse(list(events))
4259 self.assertFalse(list(events))
4260 parser.feed('</element><child>')
4261 self.assertEqual([('end', 'end(element)')], list(events))
4262 parser.feed('</child>')
4263 self.assertEqual([('end', 'end(child)')], list(events))
4264 parser.feed('</root>')
4265 self.assertEqual([('end', 'end(root)')], list(events))
4266 self.assertFalse(list(events))
4267 self.assertEqual('close()', parser.close())
4268
4270 class Target(object):
4271 def start(self, tag, attrib):
4272 return 'start(%s)' % tag
4273 def end(self, tag):
4274 return 'end(%s)' % tag
4275 def close(self):
4276 return 'close()'
4277
4278 parser = self.etree.XMLPullParser(
4279 ['start', 'end'], target=Target())
4280 events = parser.read_events()
4281
4282 parser.feed('<root><element>')
4283 self.assertEqual(
4284 [('start', 'start(root)'), ('start', 'start(element)')],
4285 list(events))
4286 self.assertFalse(list(events))
4287 parser.feed('</element><child>')
4288 self.assertEqual(
4289 [('end', 'end(element)'), ('start', 'start(child)')],
4290 list(events))
4291 parser.feed('</child>')
4292 self.assertEqual(
4293 [('end', 'end(child)')],
4294 list(events))
4295 parser.feed('</root>')
4296 self.assertEqual(
4297 [('end', 'end(root)')],
4298 list(events))
4299 self.assertFalse(list(events))
4300 self.assertEqual('close()', parser.close())
4301
4303 parser = self.etree.XMLPullParser(
4304 ['start', 'end'], target=etree.TreeBuilder())
4305 events = parser.read_events()
4306
4307 parser.feed('<root><element>')
4308 self.assert_event_tags(
4309 events, [('start', 'root'), ('start', 'element')])
4310 self.assertFalse(list(events))
4311 parser.feed('</element><child>')
4312 self.assert_event_tags(
4313 events, [('end', 'element'), ('start', 'child')])
4314 parser.feed('</child>')
4315 self.assert_event_tags(
4316 events, [('end', 'child')])
4317 parser.feed('</root>')
4318 self.assert_event_tags(
4319 events, [('end', 'root')])
4320 self.assertFalse(list(events))
4321 root = parser.close()
4322 self.assertEqual('root', root.tag)
4323
4325 class Target(etree.TreeBuilder):
4326 def end(self, tag):
4327 el = super(Target, self).end(tag)
4328 el.tag += '-huhu'
4329 return el
4330
4331 parser = self.etree.XMLPullParser(
4332 ['start', 'end'], target=Target())
4333 events = parser.read_events()
4334
4335 parser.feed('<root><element>')
4336 self.assert_event_tags(
4337 events, [('start', 'root'), ('start', 'element')])
4338 self.assertFalse(list(events))
4339 parser.feed('</element><child>')
4340 self.assert_event_tags(
4341 events, [('end', 'element-huhu'), ('start', 'child')])
4342 parser.feed('</child>')
4343 self.assert_event_tags(
4344 events, [('end', 'child-huhu')])
4345 parser.feed('</root>')
4346 self.assert_event_tags(
4347 events, [('end', 'root-huhu')])
4348 self.assertFalse(list(events))
4349 root = parser.close()
4350 self.assertEqual('root-huhu', root.tag)
4351
4352
4376
4377 if __name__ == '__main__':
4378 print('to test use test.py %s' % __file__)
4379