| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
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 from __future__ import absolute_import
11
12 import os.path
13 import unittest
14 import copy
15 import sys
16 import re
17 import gc
18 import operator
19 import tempfile
20 import textwrap
21 import zlib
22 import gzip
23 from contextlib import closing, contextmanager
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, _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 # Python 3
44 _unicode = str
49 handle, filename = tempfile.mkstemp()
50 try:
51 yield filename
52 finally:
53 os.close(handle)
54 os.remove(filename)
55
58 """Tests only for etree, not ElementTree"""
59 etree = etree
60
62 self.assertTrue(isinstance(etree.__version__, _unicode))
63 self.assertTrue(isinstance(etree.LXML_VERSION, tuple))
64 self.assertEqual(len(etree.LXML_VERSION), 4)
65 self.assertTrue(isinstance(etree.LXML_VERSION[0], int))
66 self.assertTrue(isinstance(etree.LXML_VERSION[1], int))
67 self.assertTrue(isinstance(etree.LXML_VERSION[2], int))
68 self.assertTrue(isinstance(etree.LXML_VERSION[3], int))
69 self.assertTrue(etree.__version__.startswith(
70 str(etree.LXML_VERSION[0])))
71
73 if hasattr(self.etree, '__pyx_capi__'):
74 # newer Pyrex compatible C-API
75 self.assertTrue(isinstance(self.etree.__pyx_capi__, dict))
76 self.assertTrue(len(self.etree.__pyx_capi__) > 0)
77 else:
78 # older C-API mechanism
79 self.assertTrue(hasattr(self.etree, '_import_c_api'))
80
82 import lxml
83 includes = lxml.get_include()
84 self.assertTrue(includes)
85 self.assertTrue(len(includes) >= 2)
86 self.assertTrue(os.path.join(os.path.dirname(lxml.__file__), 'includes') in includes,
87 includes)
88
90 Element = self.etree.Element
91 el = Element('name')
92 self.assertEqual(el.tag, 'name')
93 el = Element('{}name')
94 self.assertEqual(el.tag, 'name')
95
97 Element = self.etree.Element
98 el = Element('name')
99 self.assertRaises(ValueError, Element, '{}')
100 self.assertRaises(ValueError, setattr, el, 'tag', '{}')
101
102 self.assertRaises(ValueError, Element, '{test}')
103 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
104
106 Element = self.etree.Element
107 self.assertRaises(ValueError, Element, 'p:name')
108 self.assertRaises(ValueError, Element, '{test}p:name')
109
110 el = Element('name')
111 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
112
114 Element = self.etree.Element
115 self.assertRaises(ValueError, Element, "p'name")
116 self.assertRaises(ValueError, Element, 'p"name')
117
118 self.assertRaises(ValueError, Element, "{test}p'name")
119 self.assertRaises(ValueError, Element, '{test}p"name')
120
121 el = Element('name')
122 self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
123 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
124
126 Element = self.etree.Element
127 self.assertRaises(ValueError, Element, ' name ')
128 self.assertRaises(ValueError, Element, 'na me')
129 self.assertRaises(ValueError, Element, '{test} name')
130
131 el = Element('name')
132 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
133
135 Element = self.etree.Element
136 SubElement = self.etree.SubElement
137
138 el = Element('name')
139 self.assertRaises(ValueError, SubElement, el, '{}')
140 self.assertRaises(ValueError, SubElement, el, '{test}')
141
143 Element = self.etree.Element
144 SubElement = self.etree.SubElement
145
146 el = Element('name')
147 self.assertRaises(ValueError, SubElement, el, 'p:name')
148 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
149
151 Element = self.etree.Element
152 SubElement = self.etree.SubElement
153
154 el = Element('name')
155 self.assertRaises(ValueError, SubElement, el, "p'name")
156 self.assertRaises(ValueError, SubElement, el, "{test}p'name")
157
158 self.assertRaises(ValueError, SubElement, el, 'p"name')
159 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
160
162 Element = self.etree.Element
163 SubElement = self.etree.SubElement
164
165 el = Element('name')
166 self.assertRaises(ValueError, SubElement, el, ' name ')
167 self.assertRaises(ValueError, SubElement, el, 'na me')
168 self.assertRaises(ValueError, SubElement, el, '{test} name')
169
171 Element = self.etree.Element
172 SubElement = self.etree.SubElement
173
174 el = Element('name')
175 self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'})
176 self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'})
177 self.assertEqual(0, len(el))
178
180 QName = self.etree.QName
181 self.assertRaises(ValueError, QName, '')
182 self.assertRaises(ValueError, QName, None)
183 self.assertRaises(ValueError, QName, None, None)
184 self.assertRaises(ValueError, QName, 'test', '')
185
187 QName = self.etree.QName
188 q = QName(None, 'TAG')
189 self.assertEqual('TAG', q)
190 self.assertEqual('TAG', q.localname)
191 self.assertEqual(None, q.namespace)
192
194 QName = self.etree.QName
195 self.assertRaises(ValueError, QName, 'p:name')
196 self.assertRaises(ValueError, QName, 'test', 'p:name')
197
199 QName = self.etree.QName
200 self.assertRaises(ValueError, QName, ' name ')
201 self.assertRaises(ValueError, QName, 'na me')
202 self.assertRaises(ValueError, QName, 'test', ' name')
203
205 # ET doesn't have namespace/localname properties on QNames
206 QName = self.etree.QName
207 namespace, localname = 'http://myns', 'a'
208 qname = QName(namespace, localname)
209 self.assertEqual(namespace, qname.namespace)
210 self.assertEqual(localname, qname.localname)
211
213 # ET doesn't have namespace/localname properties on QNames
214 QName = self.etree.QName
215 qname1 = QName('http://myns', 'a')
216 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
217
218 qname2 = QName(a)
219 self.assertEqual(a.tag, qname1.text)
220 self.assertEqual(a.tag, qname1)
221 self.assertEqual(qname1.text, qname2.text)
222 self.assertEqual(qname1, qname2.text)
223 self.assertEqual(qname1.text, qname2)
224 self.assertEqual(qname1, qname2)
225
227 # ET doesn't resove QNames as text values
228 etree = self.etree
229 qname = etree.QName('http://myns', 'a')
230 a = etree.Element(qname, nsmap={'p' : 'http://myns'})
231 a.text = qname
232
233 self.assertEqual("p:a", a.text)
234
236 etree = self.etree
237 self.assertRaises(ValueError,
238 etree.Element, "root", nsmap={'"' : 'testns'})
239 self.assertRaises(ValueError,
240 etree.Element, "root", nsmap={'&' : 'testns'})
241 self.assertRaises(ValueError,
242 etree.Element, "root", nsmap={'a:b' : 'testns'})
243
245 # ET in Py 3.x has no "attrib.has_key()" method
246 XML = self.etree.XML
247
248 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
249 self.assertEqual(
250 True, root.attrib.has_key('bar'))
251 self.assertEqual(
252 False, root.attrib.has_key('baz'))
253 self.assertEqual(
254 False, root.attrib.has_key('hah'))
255 self.assertEqual(
256 True,
257 root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
258
260 Element = self.etree.Element
261 root = Element("root")
262 root.set("attr", "TEST")
263 self.assertEqual("TEST", root.get("attr"))
264
266 # ElementTree accepts arbitrary attribute values
267 # lxml.etree allows only strings
268 Element = self.etree.Element
269
270 root = Element("root")
271 root.set("attr", "TEST")
272 self.assertEqual("TEST", root.get("attr"))
273 self.assertRaises(TypeError, root.set, "newattr", 5)
274
276 Element = self.etree.Element
277
278 root = Element("root")
279 root.set("attr", "TEST")
280 self.assertEqual("TEST", root.attrib["attr"])
281
282 root2 = Element("root2", root.attrib, attr2='TOAST')
283 self.assertEqual("TEST", root2.attrib["attr"])
284 self.assertEqual("TOAST", root2.attrib["attr2"])
285 self.assertEqual(None, root.attrib.get("attr2"))
286
288 Element = self.etree.Element
289
290 keys = ["attr%d" % i for i in range(10)]
291 values = ["TEST-%d" % i for i in range(10)]
292 items = list(zip(keys, values))
293
294 root = Element("root")
295 for key, value in items:
296 root.set(key, value)
297 self.assertEqual(keys, root.attrib.keys())
298 self.assertEqual(values, root.attrib.values())
299
300 root2 = Element("root2", root.attrib,
301 attr_99='TOAST-1', attr_98='TOAST-2')
302 self.assertEqual(['attr_98', 'attr_99'] + keys,
303 root2.attrib.keys())
304 self.assertEqual(['TOAST-2', 'TOAST-1'] + values,
305 root2.attrib.values())
306
307 self.assertEqual(keys, root.attrib.keys())
308 self.assertEqual(values, root.attrib.values())
309
311 # ElementTree accepts arbitrary attribute values
312 # lxml.etree allows only strings, or None for (html5) boolean attributes
313 Element = self.etree.Element
314 root = Element("root")
315 self.assertRaises(TypeError, root.set, "newattr", 5)
316 self.assertRaises(TypeError, root.set, "newattr", object)
317 self.assertRaises(TypeError, root.set, "newattr", None)
318 self.assertRaises(TypeError, root.set, "newattr")
319
321 XML = self.etree.XML
322 xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>')
323
324 root = XML(xml)
325 self.etree.strip_attributes(root, 'a')
326 self.assertEqual(_bytes('<test b="10" c="20"><x b="2"></x></test>'),
327 self._writeElement(root))
328
329 root = XML(xml)
330 self.etree.strip_attributes(root, 'b', 'c')
331 self.assertEqual(_bytes('<test a="5"><x a="4"></x></test>'),
332 self._writeElement(root))
333
335 XML = self.etree.XML
336 xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>')
337
338 root = XML(xml)
339 self.etree.strip_attributes(root, 'a')
340 self.assertEqual(
341 _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'),
342 self._writeElement(root))
343
344 root = XML(xml)
345 self.etree.strip_attributes(root, '{http://test/ns}a', 'c')
346 self.assertEqual(
347 _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'),
348 self._writeElement(root))
349
350 root = XML(xml)
351 self.etree.strip_attributes(root, '{http://test/ns}*')
352 self.assertEqual(
353 _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'),
354 self._writeElement(root))
355
357 XML = self.etree.XML
358 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
359
360 root = XML(xml)
361 self.etree.strip_elements(root, 'a')
362 self.assertEqual(_bytes('<test><x></x></test>'),
363 self._writeElement(root))
364
365 root = XML(xml)
366 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
367 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'),
368 self._writeElement(root))
369
370 root = XML(xml)
371 self.etree.strip_elements(root, 'c')
372 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
373 self._writeElement(root))
374
376 XML = self.etree.XML
377 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>')
378
379 root = XML(xml)
380 self.etree.strip_elements(root, 'a')
381 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>'),
382 self._writeElement(root))
383
384 root = XML(xml)
385 self.etree.strip_elements(root, '{urn:a}b', 'c')
386 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>'),
387 self._writeElement(root))
388
389 root = XML(xml)
390 self.etree.strip_elements(root, '{urn:a}*', 'c')
391 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
392 self._writeElement(root))
393
394 root = XML(xml)
395 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
396 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
397 self._writeElement(root))
398
417
443
470
497
516
529
531 # lxml.etree separates target and text
532 Element = self.etree.Element
533 SubElement = self.etree.SubElement
534 ProcessingInstruction = self.etree.ProcessingInstruction
535
536 a = Element('a')
537 a.append(ProcessingInstruction('foo', 'some more text'))
538 self.assertEqual(a[0].target, 'foo')
539 self.assertEqual(a[0].text, 'some more text')
540
542 XML = self.etree.XML
543 root = XML(_bytes("<test><?mypi my test ?></test>"))
544 self.assertEqual(root[0].target, "mypi")
545 self.assertEqual(root[0].text, "my test ")
546
548 XML = self.etree.XML
549 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
550 self.assertEqual(root[0].target, "mypi")
551 self.assertEqual(root[0].get('my'), "1")
552 self.assertEqual(root[0].get('test'), " abc ")
553 self.assertEqual(root[0].get('quotes'), "' '")
554 self.assertEqual(root[0].get('only'), None)
555 self.assertEqual(root[0].get('names'), None)
556 self.assertEqual(root[0].get('nope'), None)
557
559 XML = self.etree.XML
560 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
561 self.assertEqual(root[0].target, "mypi")
562 self.assertEqual(root[0].attrib['my'], "1")
563 self.assertEqual(root[0].attrib['test'], " abc ")
564 self.assertEqual(root[0].attrib['quotes'], "' '")
565 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
566 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
567 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
568
570 # previously caused a crash
571 ProcessingInstruction = self.etree.ProcessingInstruction
572
573 a = ProcessingInstruction("PI", "ONE")
574 b = copy.deepcopy(a)
575 b.text = "ANOTHER"
576
577 self.assertEqual('ONE', a.text)
578 self.assertEqual('ANOTHER', b.text)
579
581 XML = self.etree.XML
582 tostring = self.etree.tostring
583 root = XML(_bytes("<?mypi my test ?><test/><!--comment -->"))
584 tree1 = self.etree.ElementTree(root)
585 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"),
586 tostring(tree1))
587
588 tree2 = copy.deepcopy(tree1)
589 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"),
590 tostring(tree2))
591
592 root2 = copy.deepcopy(tree1.getroot())
593 self.assertEqual(_bytes("<test/>"),
594 tostring(root2))
595
597 XML = self.etree.XML
598 tostring = self.etree.tostring
599 xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>')
600 root = XML(xml)
601 tree1 = self.etree.ElementTree(root)
602 self.assertEqual(xml, tostring(tree1))
603
604 tree2 = copy.deepcopy(tree1)
605 self.assertEqual(xml, tostring(tree2))
606
607 root2 = copy.deepcopy(tree1.getroot())
608 self.assertEqual(_bytes("<test/>"),
609 tostring(root2))
610
612 XML = self.etree.XML
613 tostring = self.etree.tostring
614 xml = _bytes('<!-- comment --><!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>')
615 root = XML(xml)
616 tree1 = self.etree.ElementTree(root)
617 self.assertEqual(xml, tostring(tree1))
618
619 tree2 = copy.deepcopy(tree1)
620 self.assertEqual(xml, tostring(tree2))
621
623 fromstring = self.etree.fromstring
624 tostring = self.etree.tostring
625 XMLParser = self.etree.XMLParser
626
627 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
628 parser = XMLParser(remove_comments=True)
629 root = fromstring(xml, parser)
630 self.assertEqual(
631 _bytes('<a><b><c/></b></a>'),
632 tostring(root))
633
635 parse = self.etree.parse
636 tostring = self.etree.tostring
637 XMLParser = self.etree.XMLParser
638
639 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>')
640
641 f = BytesIO(xml)
642 tree = parse(f)
643 self.assertEqual(
644 xml,
645 tostring(tree))
646
647 parser = XMLParser(remove_pis=True)
648 tree = parse(f, parser)
649 self.assertEqual(
650 _bytes('<a><b><c/></b></a>'),
651 tostring(tree))
652
654 # ET raises IOError only
655 parse = self.etree.parse
656 self.assertRaises(TypeError, parse, 'notthere.xml', object())
657
659 # ET removes comments
660 iterparse = self.etree.iterparse
661 tostring = self.etree.tostring
662
663 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
664 events = list(iterparse(f))
665 root = events[-1][1]
666 self.assertEqual(3, len(events))
667 self.assertEqual(
668 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
669 tostring(root))
670
672 # ET removes comments
673 iterparse = self.etree.iterparse
674 tostring = self.etree.tostring
675
676 def name(event, el):
677 if event == 'comment':
678 return el.text
679 else:
680 return el.tag
681
682 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
683 events = list(iterparse(f, events=('end', 'comment')))
684 root = events[-1][1]
685 self.assertEqual(6, len(events))
686 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'],
687 [ name(*item) for item in events ])
688 self.assertEqual(
689 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
690 tostring(root))
691
693 # ET removes pis
694 iterparse = self.etree.iterparse
695 tostring = self.etree.tostring
696 ElementTree = self.etree.ElementTree
697
698 def name(event, el):
699 if event == 'pi':
700 return (el.target, el.text)
701 else:
702 return el.tag
703
704 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
705 events = list(iterparse(f, events=('end', 'pi')))
706 root = events[-2][1]
707 self.assertEqual(8, len(events))
708 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
709 ('pid','d'), 'a', ('pie','e')],
710 [ name(*item) for item in events ])
711 self.assertEqual(
712 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
713 tostring(ElementTree(root)))
714
716 iterparse = self.etree.iterparse
717 tostring = self.etree.tostring
718
719 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
720 events = list(iterparse(f, remove_comments=True,
721 events=('end', 'comment')))
722 root = events[-1][1]
723 self.assertEqual(3, len(events))
724 self.assertEqual(['c', 'b', 'a'],
725 [ el.tag for (event, el) in events ])
726 self.assertEqual(
727 _bytes('<a><b><c/></b></a>'),
728 tostring(root))
729
731 iterparse = self.etree.iterparse
732 f = BytesIO('<a><b><c/></a>')
733 # ET raises ExpatError, lxml raises XMLSyntaxError
734 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
735
737 iterparse = self.etree.iterparse
738 f = BytesIO('<a><b><c/></a>')
739 it = iterparse(f, events=('start', 'end'), recover=True)
740 events = [(ev, el.tag) for ev, el in it]
741 root = it.root
742 self.assertTrue(root is not None)
743
744 self.assertEqual(1, events.count(('start', 'a')))
745 self.assertEqual(1, events.count(('end', 'a')))
746
747 self.assertEqual(1, events.count(('start', 'b')))
748 self.assertEqual(1, events.count(('end', 'b')))
749
750 self.assertEqual(1, events.count(('start', 'c')))
751 self.assertEqual(1, events.count(('end', 'c')))
752
754 iterparse = self.etree.iterparse
755 f = BytesIO('<a><b><c/></d><b><c/></a></b>')
756 it = iterparse(f, events=('start', 'end'), recover=True)
757 events = [(ev, el.tag) for ev, el in it]
758 root = it.root
759 self.assertTrue(root is not None)
760
761 self.assertEqual(1, events.count(('start', 'a')))
762 self.assertEqual(1, events.count(('end', 'a')))
763
764 self.assertEqual(2, events.count(('start', 'b')))
765 self.assertEqual(2, events.count(('end', 'b')))
766
767 self.assertEqual(2, events.count(('start', 'c')))
768 self.assertEqual(2, events.count(('end', 'c')))
769
771 iterparse = self.etree.iterparse
772 f = BytesIO("""
773 <a> \n \n <b> b test </b> \n
774
775 \n\t <c> \n </c> </a> \n """)
776 iterator = iterparse(f, remove_blank_text=True)
777 text = [ (element.text, element.tail)
778 for event, element in iterator ]
779 self.assertEqual(
780 [(" b test ", None), (" \n ", None), (None, None)],
781 text)
782
784 iterparse = self.etree.iterparse
785 f = BytesIO('<a><b><d/></b><c/></a>')
786
787 iterator = iterparse(f, tag="b", events=('start', 'end'))
788 events = list(iterator)
789 root = iterator.root
790 self.assertEqual(
791 [('start', root[0]), ('end', root[0])],
792 events)
793
795 iterparse = self.etree.iterparse
796 f = BytesIO('<a><b><d/></b><c/></a>')
797
798 iterator = iterparse(f, tag="*", events=('start', 'end'))
799 events = list(iterator)
800 self.assertEqual(
801 8,
802 len(events))
803
805 iterparse = self.etree.iterparse
806 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
807
808 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
809 events = list(iterator)
810 root = iterator.root
811 self.assertEqual(
812 [('start', root[0]), ('end', root[0])],
813 events)
814
816 iterparse = self.etree.iterparse
817 f = BytesIO('<a><b><d/></b><c/></a>')
818 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
819 events = list(iterator)
820 root = iterator.root
821 self.assertEqual(
822 [('start', root[0]), ('end', root[0])],
823 events)
824
825 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
826 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
827 events = list(iterator)
828 root = iterator.root
829 self.assertEqual([], events)
830
832 iterparse = self.etree.iterparse
833 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
834 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
835 events = list(iterator)
836 self.assertEqual(8, len(events))
837
839 iterparse = self.etree.iterparse
840 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
841 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
842 events = list(iterator)
843 self.assertEqual([], events)
844
845 f = BytesIO('<a><b><d/></b><c/></a>')
846 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
847 events = list(iterator)
848 self.assertEqual(8, len(events))
849
851 text = _str('Søk på nettet')
852 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
853 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
854 ).encode('iso-8859-1')
855
856 self.assertRaises(self.etree.ParseError,
857 list, self.etree.iterparse(BytesIO(xml_latin1)))
858
860 text = _str('Søk på nettet', encoding="UTF-8")
861 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
862 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
863 ).encode('iso-8859-1')
864
865 iterator = self.etree.iterparse(BytesIO(xml_latin1),
866 encoding="iso-8859-1")
867 self.assertEqual(1, len(list(iterator)))
868
869 a = iterator.root
870 self.assertEqual(a.text, text)
871
873 tostring = self.etree.tostring
874 f = BytesIO('<root><![CDATA[test]]></root>')
875 context = self.etree.iterparse(f, strip_cdata=False)
876 content = [ el.text for event,el in context ]
877
878 self.assertEqual(['test'], content)
879 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
880 tostring(context.root))
881
885
887 self.etree.XMLParser(encoding="ascii")
888 self.etree.XMLParser(encoding="utf-8")
889 self.etree.XMLParser(encoding="iso-8859-1")
890
892 parser = self.etree.XMLParser(recover=True)
893
894 parser.feed('<?xml version=')
895 parser.feed('"1.0"?><ro')
896 parser.feed('ot><')
897 parser.feed('a test="works"')
898 parser.feed('><othertag/></root') # <a> not closed!
899 parser.feed('>')
900
901 root = parser.close()
902
903 self.assertEqual(root.tag, "root")
904 self.assertEqual(len(root), 1)
905 self.assertEqual(root[0].tag, "a")
906 self.assertEqual(root[0].get("test"), "works")
907 self.assertEqual(len(root[0]), 1)
908 self.assertEqual(root[0][0].tag, "othertag")
909 # FIXME: would be nice to get some errors logged ...
910 #self.assertTrue(len(parser.error_log) > 0, "error log is empty")
911
913 # test that recover mode plays nicely with the no-id-dict setup
914 parser = self.etree.XMLParser(recover=True, collect_ids=False)
915
916 parser.feed('<?xml version=')
917 parser.feed('"1.0"?><ro')
918 parser.feed('ot xml:id="123"><')
919 parser.feed('a test="works" xml:id=')
920 parser.feed('"321"><othertag/></root') # <a> not closed!
921 parser.feed('>')
922
923 root = parser.close()
924
925 self.assertEqual(root.tag, "root")
926 self.assertEqual(len(root), 1)
927 self.assertEqual(root[0].tag, "a")
928 self.assertEqual(root[0].get("test"), "works")
929 self.assertEqual(root[0].attrib, {
930 'test': 'works',
931 '{http://www.w3.org/XML/1998/namespace}id': '321'})
932 self.assertEqual(len(root[0]), 1)
933 self.assertEqual(root[0][0].tag, "othertag")
934 # FIXME: would be nice to get some errors logged ...
935 #self.assertTrue(len(parser.error_log) > 0, "error log is empty")
936
938 assertEqual = self.assertEqual
939 assertFalse = self.assertFalse
940
941 events = []
942 class Target(object):
943 def start(self, tag, attrib):
944 events.append("start")
945 assertFalse(attrib)
946 assertEqual("TAG", tag)
947 def end(self, tag):
948 events.append("end")
949 assertEqual("TAG", tag)
950 def close(self):
951 return "DONE" # no Element!
952
953 parser = self.etree.XMLParser(target=Target())
954 tree = self.etree.ElementTree()
955
956 self.assertRaises(TypeError,
957 tree.parse, BytesIO("<TAG/>"), parser=parser)
958 self.assertEqual(["start", "end"], events)
959
961 # ET doesn't call .close() on errors
962 events = []
963 class Target(object):
964 def start(self, tag, attrib):
965 events.append("start-" + tag)
966 def end(self, tag):
967 events.append("end-" + tag)
968 if tag == 'a':
969 raise ValueError("dead and gone")
970 def data(self, data):
971 events.append("data-" + data)
972 def close(self):
973 events.append("close")
974 return "DONE"
975
976 parser = self.etree.XMLParser(target=Target())
977
978 try:
979 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
980 done = parser.close()
981 self.fail("error expected, but parsing succeeded")
982 except ValueError:
983 done = 'value error received as expected'
984
985 self.assertEqual(["start-root", "data-A", "start-a",
986 "data-ca", "end-a", "close"],
987 events)
988
990 # ET doesn't call .close() on errors
991 events = []
992 class Target(object):
993 def start(self, tag, attrib):
994 events.append("start-" + tag)
995 def end(self, tag):
996 events.append("end-" + tag)
997 if tag == 'a':
998 raise ValueError("dead and gone")
999 def data(self, data):
1000 events.append("data-" + data)
1001 def close(self):
1002 events.append("close")
1003 return "DONE"
1004
1005 parser = self.etree.XMLParser(target=Target())
1006
1007 try:
1008 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
1009 parser=parser)
1010 self.fail("error expected, but parsing succeeded")
1011 except ValueError:
1012 done = 'value error received as expected'
1013
1014 self.assertEqual(["start-root", "data-A", "start-a",
1015 "data-ca", "end-a", "close"],
1016 events)
1017
1019 # test that target parsing works nicely with the no-id-hash setup
1020 events = []
1021 class Target(object):
1022 def start(self, tag, attrib):
1023 events.append("start-" + tag)
1024 def end(self, tag):
1025 events.append("end-" + tag)
1026 def data(self, data):
1027 events.append("data-" + data)
1028 def comment(self, text):
1029 events.append("comment-" + text)
1030 def close(self):
1031 return "DONE"
1032
1033 parser = self.etree.XMLParser(target=Target(), collect_ids=False)
1034
1035 parser.feed(_bytes('<!--a--><root xml:id="123">A<!--b-->'))
1036 parser.feed(_bytes('<sub xml:id="321"/>B</root>'))
1037 done = parser.close()
1038
1039 self.assertEqual("DONE", done)
1040 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
1041 "start-sub", "end-sub", "data-B", "end-root"],
1042 events)
1043
1045 events = []
1046 class Target(object):
1047 def start(self, tag, attrib):
1048 events.append("start-" + tag)
1049 def end(self, tag):
1050 events.append("end-" + tag)
1051 def data(self, data):
1052 events.append("data-" + data)
1053 def comment(self, text):
1054 events.append("comment-" + text)
1055 def close(self):
1056 return "DONE"
1057
1058 parser = self.etree.XMLParser(target=Target())
1059
1060 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
1061 done = parser.close()
1062
1063 self.assertEqual("DONE", done)
1064 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
1065 "start-sub", "end-sub", "comment-c", "data-B",
1066 "end-root", "comment-d"],
1067 events)
1068
1070 events = []
1071 class Target(object):
1072 def start(self, tag, attrib):
1073 events.append("start-" + tag)
1074 def end(self, tag):
1075 events.append("end-" + tag)
1076 def data(self, data):
1077 events.append("data-" + data)
1078 def pi(self, target, data):
1079 events.append("pi-" + target + "-" + data)
1080 def close(self):
1081 return "DONE"
1082
1083 parser = self.etree.XMLParser(target=Target())
1084
1085 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
1086 done = parser.close()
1087
1088 self.assertEqual("DONE", done)
1089 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b",
1090 "data-B", "end-root", "pi-test-c"],
1091 events)
1092
1094 events = []
1095 class Target(object):
1096 def start(self, tag, attrib):
1097 events.append("start-" + tag)
1098 def end(self, tag):
1099 events.append("end-" + tag)
1100 def data(self, data):
1101 events.append("data-" + data)
1102 def close(self):
1103 return "DONE"
1104
1105 parser = self.etree.XMLParser(target=Target(),
1106 strip_cdata=False)
1107
1108 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
1109 done = parser.close()
1110
1111 self.assertEqual("DONE", done)
1112 self.assertEqual(["start-root", "data-A", "start-a",
1113 "data-ca", "end-a", "data-B", "end-root"],
1114 events)
1115
1117 events = []
1118 class Target(object):
1119 def start(self, tag, attrib):
1120 events.append("start-" + tag)
1121 def end(self, tag):
1122 events.append("end-" + tag)
1123 def data(self, data):
1124 events.append("data-" + data)
1125 def close(self):
1126 events.append("close")
1127 return "DONE"
1128
1129 parser = self.etree.XMLParser(target=Target(),
1130 recover=True)
1131
1132 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
1133 done = parser.close()
1134
1135 self.assertEqual("DONE", done)
1136 self.assertEqual(["start-root", "data-A", "start-a",
1137 "data-ca", "end-a", "data-B",
1138 "end-root", "close"],
1139 events)
1140
1142 iterwalk = self.etree.iterwalk
1143 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
1144
1145 iterator = iterwalk(root, tag="b", events=('start', 'end'))
1146 events = list(iterator)
1147 self.assertEqual(
1148 [('start', root[0]), ('end', root[0])],
1149 events)
1150
1152 iterwalk = self.etree.iterwalk
1153 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
1154
1155 iterator = iterwalk(root, tag="*", events=('start', 'end'))
1156 events = list(iterator)
1157 self.assertEqual(
1158 8,
1159 len(events))
1160
1162 iterwalk = self.etree.iterwalk
1163 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1164
1165 events = list(iterwalk(root))
1166 self.assertEqual(
1167 [('end', root[0]), ('end', root[1]), ('end', root)],
1168 events)
1169
1171 iterwalk = self.etree.iterwalk
1172 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1173
1174 iterator = iterwalk(root, events=('start',))
1175 events = list(iterator)
1176 self.assertEqual(
1177 [('start', root), ('start', root[0]), ('start', root[1])],
1178 events)
1179
1181 iterwalk = self.etree.iterwalk
1182 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1183
1184 iterator = iterwalk(root, events=('start','end'))
1185 events = list(iterator)
1186 self.assertEqual(
1187 [('start', root), ('start', root[0]), ('end', root[0]),
1188 ('start', root[1]), ('end', root[1]), ('end', root)],
1189 events)
1190
1192 iterwalk = self.etree.iterwalk
1193 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1194
1195 iterator = iterwalk(root)
1196 for event, elem in iterator:
1197 elem.clear()
1198
1199 self.assertEqual(0,
1200 len(root))
1201
1203 iterwalk = self.etree.iterwalk
1204 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1205
1206 attr_name = '{testns}bla'
1207 events = []
1208 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1209 for event, elem in iterator:
1210 events.append(event)
1211 if event == 'start':
1212 if elem.tag != '{ns1}a':
1213 elem.set(attr_name, 'value')
1214
1215 self.assertEqual(
1216 ['start-ns', 'start', 'start', 'start-ns', 'start',
1217 'end', 'end-ns', 'end', 'end', 'end-ns'],
1218 events)
1219
1220 self.assertEqual(
1221 None,
1222 root.get(attr_name))
1223 self.assertEqual(
1224 'value',
1225 root[0].get(attr_name))
1226
1228 iterwalk = self.etree.iterwalk
1229 root = self.etree.XML(_bytes('<a><b><c/></b><d><e/></d></a>'))
1230
1231 iterator = iterwalk(root)
1232 tags = []
1233 for event, elem in iterator:
1234 tags.append(elem.tag)
1235 # requesting a skip after an 'end' event should never have an effect
1236 iterator.skip_subtree()
1237
1238 self.assertEqual(['c', 'b', 'e', 'd', 'a'], tags)
1239
1241 iterwalk = self.etree.iterwalk
1242 root = self.etree.XML(_bytes('<a><b><c/></b><d><e/></d></a>'))
1243
1244 iterator = iterwalk(root, events=('start', 'end'))
1245 tags = []
1246 for event, elem in iterator:
1247 tags.append((event, elem.tag))
1248 if elem.tag in ('b', 'e'):
1249 # skipping should only have an effect on 'start', not on 'end'
1250 iterator.skip_subtree()
1251
1252 self.assertEqual(
1253 [('start', 'a'),
1254 ('start', 'b'), ('end', 'b'), # ignored child 'c'
1255 ('start', 'd'),
1256 ('start', 'e'), ('end', 'e'),
1257 ('end', 'd'),
1258 ('end', 'a')],
1259 tags)
1260
1262 iterwalk = self.etree.iterwalk
1263 root = self.etree.XML(_bytes(
1264 '<a xmlns="ns1"><b xmlns="nsb"><c xmlns="ns2"/></b><d xmlns="ns2"><e/></d></a>'))
1265
1266 events = []
1267 iterator = iterwalk(root, events=('start','start-ns','end-ns'))
1268 for event, elem in iterator:
1269 if event in ('start-ns', 'end-ns'):
1270 events.append((event, elem))
1271 if event == 'start-ns' and elem == ('', 'nsb'):
1272 events.append('skip')
1273 iterator.skip_subtree()
1274 else:
1275 events.append((event, elem.tag))
1276
1277 self.assertEqual(
1278 [('start-ns', ('', 'ns1')),
1279 ('start', '{ns1}a'),
1280 ('start-ns', ('', 'nsb')),
1281 'skip',
1282 ('start', '{nsb}b'),
1283 ('end-ns', None),
1284 ('start-ns', ('', 'ns2')),
1285 ('start', '{ns2}d'),
1286 ('start', '{ns2}e'),
1287 ('end-ns', None),
1288 ('end-ns', None)
1289 ],
1290 events)
1291
1293 iterwalk = self.etree.iterwalk
1294 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
1295
1296 counts = []
1297 for event, elem in iterwalk(root):
1298 counts.append(len(list(elem.getiterator())))
1299 self.assertEqual(
1300 [1,2,1,4],
1301 counts)
1302
1304 parse = self.etree.parse
1305 parser = self.etree.XMLParser(dtd_validation=True)
1306 assertEqual = self.assertEqual
1307 test_url = _str("__nosuch.dtd")
1308
1309 class MyResolver(self.etree.Resolver):
1310 def resolve(self, url, id, context):
1311 assertEqual(url, test_url)
1312 return self.resolve_string(
1313 _str('''<!ENTITY myentity "%s">
1314 <!ELEMENT doc ANY>''') % url, context)
1315
1316 parser.resolvers.add(MyResolver())
1317
1318 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1319 tree = parse(StringIO(xml), parser)
1320 root = tree.getroot()
1321 self.assertEqual(root.text, test_url)
1322
1324 parse = self.etree.parse
1325 parser = self.etree.XMLParser(dtd_validation=True)
1326 assertEqual = self.assertEqual
1327 test_url = _str("__nosuch.dtd")
1328
1329 class MyResolver(self.etree.Resolver):
1330 def resolve(self, url, id, context):
1331 assertEqual(url, test_url)
1332 return self.resolve_string(
1333 (_str('''<!ENTITY myentity "%s">
1334 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1335 context)
1336
1337 parser.resolvers.add(MyResolver())
1338
1339 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1340 tree = parse(StringIO(xml), parser)
1341 root = tree.getroot()
1342 self.assertEqual(root.text, test_url)
1343
1345 parse = self.etree.parse
1346 parser = self.etree.XMLParser(dtd_validation=True)
1347 assertEqual = self.assertEqual
1348 test_url = _str("__nosuch.dtd")
1349
1350 class MyResolver(self.etree.Resolver):
1351 def resolve(self, url, id, context):
1352 assertEqual(url, test_url)
1353 return self.resolve_file(
1354 SillyFileLike(
1355 _str('''<!ENTITY myentity "%s">
1356 <!ELEMENT doc ANY>''') % url), context)
1357
1358 parser.resolvers.add(MyResolver())
1359
1360 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1361 tree = parse(StringIO(xml), parser)
1362 root = tree.getroot()
1363 self.assertEqual(root.text, test_url)
1364
1366 parse = self.etree.parse
1367 parser = self.etree.XMLParser(attribute_defaults=True)
1368 assertEqual = self.assertEqual
1369 test_url = _str("__nosuch.dtd")
1370
1371 class MyResolver(self.etree.Resolver):
1372 def resolve(self, url, id, context):
1373 assertEqual(url, test_url)
1374 return self.resolve_filename(
1375 fileInTestDir('test.dtd'), context)
1376
1377 parser.resolvers.add(MyResolver())
1378
1379 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1380 tree = parse(StringIO(xml), parser)
1381 root = tree.getroot()
1382 self.assertEqual(
1383 root.attrib, {'default': 'valueA'})
1384 self.assertEqual(
1385 root[0].attrib, {'default': 'valueB'})
1386
1388 parse = self.etree.parse
1389 parser = self.etree.XMLParser(attribute_defaults=True)
1390 assertEqual = self.assertEqual
1391 test_url = _str("__nosuch.dtd")
1392
1393 class MyResolver(self.etree.Resolver):
1394 def resolve(self, url, id, context):
1395 expected = fileUrlInTestDir(test_url)
1396 url = url.replace('file://', 'file:') # depends on libxml2 version
1397 expected = expected.replace('file://', 'file:')
1398 assertEqual(url, expected)
1399 return self.resolve_filename(
1400 fileUrlInTestDir('test.dtd'), context)
1401
1402 parser.resolvers.add(MyResolver())
1403
1404 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1405 tree = parse(StringIO(xml), parser,
1406 base_url=fileUrlInTestDir('__test.xml'))
1407 root = tree.getroot()
1408 self.assertEqual(
1409 root.attrib, {'default': 'valueA'})
1410 self.assertEqual(
1411 root[0].attrib, {'default': 'valueB'})
1412
1414 parse = self.etree.parse
1415 parser = self.etree.XMLParser(attribute_defaults=True)
1416 assertEqual = self.assertEqual
1417 test_url = _str("__nosuch.dtd")
1418
1419 class MyResolver(self.etree.Resolver):
1420 def resolve(self, url, id, context):
1421 assertEqual(url, test_url)
1422 return self.resolve_file(
1423 open(fileInTestDir('test.dtd'), 'rb'), context)
1424
1425 parser.resolvers.add(MyResolver())
1426
1427 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1428 tree = parse(StringIO(xml), parser)
1429 root = tree.getroot()
1430 self.assertEqual(
1431 root.attrib, {'default': 'valueA'})
1432 self.assertEqual(
1433 root[0].attrib, {'default': 'valueB'})
1434
1436 parse = self.etree.parse
1437 parser = self.etree.XMLParser(load_dtd=True)
1438 assertEqual = self.assertEqual
1439 test_url = _str("__nosuch.dtd")
1440
1441 class check(object):
1442 resolved = False
1443
1444 class MyResolver(self.etree.Resolver):
1445 def resolve(self, url, id, context):
1446 assertEqual(url, test_url)
1447 check.resolved = True
1448 return self.resolve_empty(context)
1449
1450 parser.resolvers.add(MyResolver())
1451
1452 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1453 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1454 self.assertTrue(check.resolved)
1455
1457 parse = self.etree.parse
1458 parser = self.etree.XMLParser(dtd_validation=True)
1459
1460 class _LocalException(Exception):
1461 pass
1462
1463 class MyResolver(self.etree.Resolver):
1464 def resolve(self, url, id, context):
1465 raise _LocalException
1466
1467 parser.resolvers.add(MyResolver())
1468
1469 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1470 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1471
1472 if etree.LIBXML_VERSION > (2,6,20):
1474 parse = self.etree.parse
1475 tostring = self.etree.tostring
1476 parser = self.etree.XMLParser(resolve_entities=False)
1477 Entity = self.etree.Entity
1478
1479 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>')
1480 tree = parse(BytesIO(xml), parser)
1481 root = tree.getroot()
1482 self.assertEqual(root[0].tag, Entity)
1483 self.assertEqual(root[0].text, "&myentity;")
1484 self.assertEqual(root[0].tail, None)
1485 self.assertEqual(root[0].name, "myentity")
1486
1487 self.assertEqual(_bytes('<doc>&myentity;</doc>'),
1488 tostring(root))
1489
1491 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1492 <root>
1493 <child1/>
1494 <child2/>
1495 <child3> </child3>
1496 </root>''')
1497
1498 parser = self.etree.XMLParser(resolve_entities=False)
1499 root = etree.fromstring(xml, parser)
1500 self.assertEqual([ el.tag for el in root ],
1501 ['child1', 'child2', 'child3'])
1502
1503 root[0] = root[-1]
1504 self.assertEqual([ el.tag for el in root ],
1505 ['child3', 'child2'])
1506 self.assertEqual(root[0][0].text, ' ')
1507 self.assertEqual(root[0][0].name, 'nbsp')
1508
1510 Entity = self.etree.Entity
1511 Element = self.etree.Element
1512 tostring = self.etree.tostring
1513
1514 root = Element("root")
1515 root.append( Entity("test") )
1516
1517 self.assertEqual(root[0].tag, Entity)
1518 self.assertEqual(root[0].text, "&test;")
1519 self.assertEqual(root[0].tail, None)
1520 self.assertEqual(root[0].name, "test")
1521
1522 self.assertEqual(_bytes('<root>&test;</root>'),
1523 tostring(root))
1524
1526 Entity = self.etree.Entity
1527 self.assertEqual(Entity("test").text, '&test;')
1528 self.assertEqual(Entity("#17683").text, '䔓')
1529 self.assertEqual(Entity("#x1768").text, 'ᝨ')
1530 self.assertEqual(Entity("#x98AF").text, '颯')
1531
1533 Entity = self.etree.Entity
1534 self.assertRaises(ValueError, Entity, 'a b c')
1535 self.assertRaises(ValueError, Entity, 'a,b')
1536 self.assertRaises(ValueError, Entity, 'a\0b')
1537 self.assertRaises(ValueError, Entity, '#abc')
1538 self.assertRaises(ValueError, Entity, '#xxyz')
1539
1541 CDATA = self.etree.CDATA
1542 Element = self.etree.Element
1543 tostring = self.etree.tostring
1544
1545 root = Element("root")
1546 root.text = CDATA('test')
1547
1548 self.assertEqual('test',
1549 root.text)
1550 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1551 tostring(root))
1552
1554 CDATA = self.etree.CDATA
1555 Element = self.etree.Element
1556 SubElement = self.etree.SubElement
1557 tostring = self.etree.tostring
1558
1559 root = Element("root")
1560 child = SubElement(root, 'child')
1561 child.tail = CDATA('test')
1562
1563 self.assertEqual('test', child.tail)
1564 self.assertEqual(_bytes('<root><child/><![CDATA[test]]></root>'),
1565 tostring(root))
1566
1567 root = Element("root")
1568 root.tail = CDATA('test')
1569
1570 self.assertEqual('test', root.tail)
1571 self.assertEqual(_bytes('<root/><![CDATA[test]]>'),
1572 tostring(root))
1573
1575 CDATA = self.etree.CDATA
1576 Element = self.etree.Element
1577 root = Element("root")
1578
1579 root.text = CDATA("test")
1580 self.assertEqual('test', root.text)
1581
1582 root.text = CDATA(_str("test"))
1583 self.assertEqual('test', root.text)
1584
1585 self.assertRaises(TypeError, CDATA, 1)
1586
1588 CDATA = self.etree.CDATA
1589 Element = self.etree.Element
1590
1591 root = Element("root")
1592 cdata = CDATA('test')
1593
1594 self.assertRaises(TypeError,
1595 root.set, 'attr', cdata)
1596 self.assertRaises(TypeError,
1597 operator.setitem, root.attrib, 'attr', cdata)
1598
1600 tostring = self.etree.tostring
1601 parser = self.etree.XMLParser(strip_cdata=False)
1602 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1603
1604 self.assertEqual('test', root.text)
1605 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1606 tostring(root))
1607
1609 tostring = self.etree.tostring
1610 parser = self.etree.XMLParser(strip_cdata=False)
1611 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1612 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1613 tostring(root))
1614
1615 self.assertEqual(['test'], root.xpath('//text()'))
1616
1617 # TypeError in etree, AssertionError in ElementTree;
1619 Element = self.etree.Element
1620 SubElement = self.etree.SubElement
1621
1622 a = Element('a')
1623 b = SubElement(a, 'b')
1624
1625 self.assertRaises(TypeError,
1626 a.__setitem__, 0, 'foo')
1627
1629 Element = self.etree.Element
1630 root = Element('root')
1631 # raises AssertionError in ElementTree
1632 self.assertRaises(TypeError, root.append, None)
1633 self.assertRaises(TypeError, root.extend, [None])
1634 self.assertRaises(TypeError, root.extend, [Element('one'), None])
1635 self.assertEqual('one', root[0].tag)
1636
1638 Element = self.etree.Element
1639 SubElement = self.etree.SubElement
1640 root = Element('root')
1641 self.assertRaises(ValueError, root.append, root)
1642 child = SubElement(root, 'child')
1643 self.assertRaises(ValueError, child.append, root)
1644 child2 = SubElement(child, 'child2')
1645 self.assertRaises(ValueError, child2.append, root)
1646 self.assertRaises(ValueError, child2.append, child)
1647 self.assertEqual('child2', root[0][0].tag)
1648
1650 Element = self.etree.Element
1651 SubElement = self.etree.SubElement
1652 root = Element('root')
1653 SubElement(root, 'a')
1654 SubElement(root, 'b')
1655
1656 self.assertEqual(['a', 'b'],
1657 [c.tag for c in root])
1658 root[1].addnext(root[0])
1659 self.assertEqual(['b', 'a'],
1660 [c.tag for c in root])
1661
1663 Element = self.etree.Element
1664 SubElement = self.etree.SubElement
1665 root = Element('root')
1666 SubElement(root, 'a')
1667 SubElement(root, 'b')
1668
1669 self.assertEqual(['a', 'b'],
1670 [c.tag for c in root])
1671 root[0].addprevious(root[1])
1672 self.assertEqual(['b', 'a'],
1673 [c.tag for c in root])
1674
1676 Element = self.etree.Element
1677 SubElement = self.etree.SubElement
1678 root = Element('root')
1679 a = SubElement(root, 'a')
1680 b = SubElement(a, 'b')
1681 # appending parent as sibling is forbidden
1682 self.assertRaises(ValueError, b.addnext, a)
1683 self.assertEqual(['a'], [c.tag for c in root])
1684 self.assertEqual(['b'], [c.tag for c in a])
1685
1687 Element = self.etree.Element
1688 SubElement = self.etree.SubElement
1689 root = Element('root')
1690 a = SubElement(root, 'a')
1691 b = SubElement(a, 'b')
1692 # appending parent as sibling is forbidden
1693 self.assertRaises(ValueError, b.addprevious, a)
1694 self.assertEqual(['a'], [c.tag for c in root])
1695 self.assertEqual(['b'], [c.tag for c in a])
1696
1698 Element = self.etree.Element
1699 SubElement = self.etree.SubElement
1700 root = Element('root')
1701 a = SubElement(root, 'a')
1702 b = SubElement(a, 'b')
1703 c = SubElement(b, 'c')
1704 # appending parent as sibling is forbidden
1705 self.assertRaises(ValueError, c.addnext, a)
1706
1708 Element = self.etree.Element
1709 SubElement = self.etree.SubElement
1710 root = Element('root')
1711 a = SubElement(root, 'a')
1712 b = SubElement(a, 'b')
1713 c = SubElement(b, 'c')
1714 # appending parent as sibling is forbidden
1715 self.assertRaises(ValueError, c.addprevious, a)
1716
1718 Element = self.etree.Element
1719 SubElement = self.etree.SubElement
1720 root = Element('root')
1721 a = SubElement(root, 'a')
1722 b = SubElement(root, 'b')
1723 a.addprevious(a)
1724 self.assertEqual('a', root[0].tag)
1725 self.assertEqual('b', root[1].tag)
1726 b.addprevious(b)
1727 self.assertEqual('a', root[0].tag)
1728 self.assertEqual('b', root[1].tag)
1729 b.addprevious(a)
1730 self.assertEqual('a', root[0].tag)
1731 self.assertEqual('b', root[1].tag)
1732
1734 Element = self.etree.Element
1735 SubElement = self.etree.SubElement
1736 root = Element('root')
1737 a = SubElement(root, 'a')
1738 b = SubElement(root, 'b')
1739 a.addnext(a)
1740 self.assertEqual('a', root[0].tag)
1741 self.assertEqual('b', root[1].tag)
1742 b.addnext(b)
1743 self.assertEqual('a', root[0].tag)
1744 self.assertEqual('b', root[1].tag)
1745 a.addnext(b)
1746 self.assertEqual('a', root[0].tag)
1747 self.assertEqual('b', root[1].tag)
1748
1750 Element = self.etree.Element
1751 a = Element('a')
1752 b = Element('b')
1753 self.assertRaises(TypeError, a.addnext, b)
1754
1756 Element = self.etree.Element
1757 SubElement = self.etree.SubElement
1758 PI = self.etree.PI
1759 root = Element('root')
1760 SubElement(root, 'a')
1761 pi = PI('TARGET', 'TEXT')
1762 pi.tail = "TAIL"
1763
1764 self.assertEqual(_bytes('<root><a></a></root>'),
1765 self._writeElement(root))
1766 root[0].addprevious(pi)
1767 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
1768 self._writeElement(root))
1769
1771 Element = self.etree.Element
1772 PI = self.etree.PI
1773 root = Element('root')
1774 pi = PI('TARGET', 'TEXT')
1775 pi.tail = "TAIL"
1776
1777 self.assertEqual(_bytes('<root></root>'),
1778 self._writeElement(root))
1779 root.addprevious(pi)
1780 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'),
1781 self._writeElement(root))
1782
1784 Element = self.etree.Element
1785 SubElement = self.etree.SubElement
1786 PI = self.etree.PI
1787 root = Element('root')
1788 SubElement(root, 'a')
1789 pi = PI('TARGET', 'TEXT')
1790 pi.tail = "TAIL"
1791
1792 self.assertEqual(_bytes('<root><a></a></root>'),
1793 self._writeElement(root))
1794 root[0].addnext(pi)
1795 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
1796 self._writeElement(root))
1797
1799 Element = self.etree.Element
1800 PI = self.etree.PI
1801 root = Element('root')
1802 pi = PI('TARGET', 'TEXT')
1803 pi.tail = "TAIL"
1804
1805 self.assertEqual(_bytes('<root></root>'),
1806 self._writeElement(root))
1807 root.addnext(pi)
1808 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'),
1809 self._writeElement(root))
1810
1812 Element = self.etree.Element
1813 SubElement = self.etree.SubElement
1814 Comment = self.etree.Comment
1815 root = Element('root')
1816 SubElement(root, 'a')
1817 comment = Comment('TEXT ')
1818 comment.tail = "TAIL"
1819
1820 self.assertEqual(_bytes('<root><a></a></root>'),
1821 self._writeElement(root))
1822 root[0].addnext(comment)
1823 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
1824 self._writeElement(root))
1825
1827 Element = self.etree.Element
1828 Comment = self.etree.Comment
1829 root = Element('root')
1830 comment = Comment('TEXT ')
1831 comment.tail = "TAIL"
1832
1833 self.assertEqual(_bytes('<root></root>'),
1834 self._writeElement(root))
1835 root.addnext(comment)
1836 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'),
1837 self._writeElement(root))
1838
1840 Element = self.etree.Element
1841 SubElement = self.etree.SubElement
1842 Comment = self.etree.Comment
1843 root = Element('root')
1844 SubElement(root, 'a')
1845 comment = Comment('TEXT ')
1846 comment.tail = "TAIL"
1847
1848 self.assertEqual(_bytes('<root><a></a></root>'),
1849 self._writeElement(root))
1850 root[0].addprevious(comment)
1851 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
1852 self._writeElement(root))
1853
1855 Element = self.etree.Element
1856 Comment = self.etree.Comment
1857 root = Element('root')
1858 comment = Comment('TEXT ')
1859 comment.tail = "TAIL"
1860
1861 self.assertEqual(_bytes('<root></root>'),
1862 self._writeElement(root))
1863 root.addprevious(comment)
1864 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'),
1865 self._writeElement(root))
1866
1867 # ET's Elements have items() and key(), but not values()
1869 XML = self.etree.XML
1870
1871 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
1872 values = root.values()
1873 values.sort()
1874 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1875
1876 # gives error in ElementTree
1878 Element = self.etree.Element
1879 Comment = self.etree.Comment
1880
1881 a = Element('a')
1882 a.append(Comment())
1883 self.assertEqual(
1884 _bytes('<a><!----></a>'),
1885 self._writeElement(a))
1886
1887 # ElementTree ignores comments
1889 ElementTree = self.etree.ElementTree
1890 tostring = self.etree.tostring
1891
1892 xml = _bytes('<a><b/><!----><c/></a>')
1893 f = BytesIO(xml)
1894 doc = ElementTree(file=f)
1895 a = doc.getroot()
1896 self.assertEqual(
1897 '',
1898 a[1].text)
1899 self.assertEqual(
1900 xml,
1901 tostring(a))
1902
1903 # ElementTree ignores comments
1905 ElementTree = self.etree.ElementTree
1906
1907 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
1908 doc = ElementTree(file=f)
1909 a = doc.getroot()
1910 self.assertEqual(
1911 ' hoi ',
1912 a[1].text)
1913
1914 # does not raise an exception in ElementTree
1916 Element = self.etree.Element
1917 Comment = self.etree.Comment
1918
1919 c = Comment()
1920 el = Element('myel')
1921
1922 self.assertRaises(TypeError, c.append, el)
1923 self.assertRaises(TypeError, c.insert, 0, el)
1924 self.assertRaises(TypeError, c.set, "myattr", "test")
1925
1927 c = self.etree.Comment()
1928 self.assertEqual(0, len(c.attrib))
1929
1930 self.assertFalse(c.attrib.__contains__('nope'))
1931 self.assertFalse('nope' in c.attrib)
1932 self.assertFalse('nope' in c.attrib.keys())
1933 self.assertFalse('nope' in c.attrib.values())
1934 self.assertFalse(('nope', 'huhu') in c.attrib.items())
1935
1936 self.assertEqual([], list(c.attrib))
1937 self.assertEqual([], list(c.attrib.keys()))
1938 self.assertEqual([], list(c.attrib.items()))
1939 self.assertEqual([], list(c.attrib.values()))
1940 self.assertEqual([], list(c.attrib.iterkeys()))
1941 self.assertEqual([], list(c.attrib.iteritems()))
1942 self.assertEqual([], list(c.attrib.itervalues()))
1943
1944 self.assertEqual('HUHU', c.attrib.pop('nope', 'HUHU'))
1945 self.assertRaises(KeyError, c.attrib.pop, 'nope')
1946
1947 self.assertRaises(KeyError, c.attrib.__getitem__, 'only')
1948 self.assertRaises(KeyError, c.attrib.__getitem__, 'names')
1949 self.assertRaises(KeyError, c.attrib.__getitem__, 'nope')
1950 self.assertRaises(KeyError, c.attrib.__setitem__, 'nope', 'yep')
1951 self.assertRaises(KeyError, c.attrib.__delitem__, 'nope')
1952
1953 # test passing 'None' to dump()
1956
1958 ElementTree = self.etree.ElementTree
1959
1960 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
1961 doc = ElementTree(file=f)
1962 a = doc.getroot()
1963 self.assertEqual(
1964 None,
1965 a.prefix)
1966 self.assertEqual(
1967 'foo',
1968 a[0].prefix)
1969
1971 ElementTree = self.etree.ElementTree
1972
1973 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
1974 doc = ElementTree(file=f)
1975 a = doc.getroot()
1976 self.assertEqual(
1977 None,
1978 a.prefix)
1979 self.assertEqual(
1980 None,
1981 a[0].prefix)
1982
1984 Element = self.etree.Element
1985 SubElement = self.etree.SubElement
1986
1987 a = Element('a')
1988 b = SubElement(a, 'b')
1989 c = SubElement(a, 'c')
1990 d = SubElement(b, 'd')
1991 self.assertEqual(
1992 None,
1993 a.getparent())
1994 self.assertEqual(
1995 a,
1996 b.getparent())
1997 self.assertEqual(
1998 b.getparent(),
1999 c.getparent())
2000 self.assertEqual(
2001 b,
2002 d.getparent())
2003
2005 XML = self.etree.XML
2006
2007 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
2008 result = []
2009 for el in root.iterchildren():
2010 result.append(el.tag)
2011 self.assertEqual(['one', 'two', 'three'], result)
2012
2014 XML = self.etree.XML
2015
2016 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
2017 result = []
2018 for el in root.iterchildren(reversed=True):
2019 result.append(el.tag)
2020 self.assertEqual(['three', 'two', 'one'], result)
2021
2023 XML = self.etree.XML
2024
2025 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
2026 result = []
2027 for el in root.iterchildren(tag='two'):
2028 result.append(el.text)
2029 self.assertEqual(['Two', 'Bla'], result)
2030
2032 XML = self.etree.XML
2033
2034 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
2035 result = []
2036 for el in root.iterchildren('two'):
2037 result.append(el.text)
2038 self.assertEqual(['Two', 'Bla'], result)
2039
2041 XML = self.etree.XML
2042
2043 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
2044 result = []
2045 for el in root.iterchildren(reversed=True, tag='two'):
2046 result.append(el.text)
2047 self.assertEqual(['Bla', 'Two'], result)
2048
2050 XML = self.etree.XML
2051
2052 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
2053 result = []
2054 for el in root.iterchildren(tag=['two', 'three']):
2055 result.append(el.text)
2056 self.assertEqual(['Two', 'Bla', None], result)
2057
2059 XML = self.etree.XML
2060
2061 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
2062 result = []
2063 for el in root.iterchildren('two', 'three'):
2064 result.append(el.text)
2065 self.assertEqual(['Two', 'Bla', None], result)
2066
2068 XML = self.etree.XML
2069
2070 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
2071 result = []
2072 for el in root.iterchildren(reversed=True, tag=['two', 'three']):
2073 result.append(el.text)
2074 self.assertEqual([None, 'Bla', 'Two'], result)
2075
2077 Element = self.etree.Element
2078 SubElement = self.etree.SubElement
2079
2080 a = Element('a')
2081 b = SubElement(a, 'b')
2082 c = SubElement(a, 'c')
2083 d = SubElement(b, 'd')
2084 self.assertEqual(
2085 [],
2086 list(a.iterancestors()))
2087 self.assertEqual(
2088 [a],
2089 list(b.iterancestors()))
2090 self.assertEqual(
2091 [a],
2092 list(c.iterancestors()))
2093 self.assertEqual(
2094 [b, a],
2095 list(d.iterancestors()))
2096
2098 Element = self.etree.Element
2099 SubElement = self.etree.SubElement
2100
2101 a = Element('a')
2102 b = SubElement(a, 'b')
2103 c = SubElement(a, 'c')
2104 d = SubElement(b, 'd')
2105 self.assertEqual(
2106 [a],
2107 list(d.iterancestors('a')))
2108 self.assertEqual(
2109 [a],
2110 list(d.iterancestors(tag='a')))
2111
2112 self.assertEqual(
2113 [b, a],
2114 list(d.iterancestors('*')))
2115 self.assertEqual(
2116 [b, a],
2117 list(d.iterancestors(tag='*')))
2118
2120 Element = self.etree.Element
2121 SubElement = self.etree.SubElement
2122
2123 a = Element('a')
2124 b = SubElement(a, 'b')
2125 c = SubElement(a, 'c')
2126 d = SubElement(b, 'd')
2127 self.assertEqual(
2128 [b, a],
2129 list(d.iterancestors(tag=('a', 'b'))))
2130 self.assertEqual(
2131 [b, a],
2132 list(d.iterancestors('a', 'b')))
2133
2134 self.assertEqual(
2135 [],
2136 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
2137 self.assertEqual(
2138 [],
2139 list(d.iterancestors('w', 'x', 'y', 'z')))
2140
2141 self.assertEqual(
2142 [],
2143 list(d.iterancestors(tag=('d', 'x'))))
2144 self.assertEqual(
2145 [],
2146 list(d.iterancestors('d', 'x')))
2147
2148 self.assertEqual(
2149 [b, a],
2150 list(d.iterancestors(tag=('b', '*'))))
2151 self.assertEqual(
2152 [b, a],
2153 list(d.iterancestors('b', '*')))
2154
2155 self.assertEqual(
2156 [b],
2157 list(d.iterancestors(tag=('b', 'c'))))
2158 self.assertEqual(
2159 [b],
2160 list(d.iterancestors('b', 'c')))
2161
2163 Element = self.etree.Element
2164 SubElement = self.etree.SubElement
2165
2166 a = Element('a')
2167 b = SubElement(a, 'b')
2168 c = SubElement(a, 'c')
2169 d = SubElement(b, 'd')
2170 e = SubElement(c, 'e')
2171
2172 self.assertEqual(
2173 [b, d, c, e],
2174 list(a.iterdescendants()))
2175 self.assertEqual(
2176 [],
2177 list(d.iterdescendants()))
2178
2180 Element = self.etree.Element
2181 SubElement = self.etree.SubElement
2182
2183 a = Element('a')
2184 b = SubElement(a, 'b')
2185 c = SubElement(a, 'c')
2186 d = SubElement(b, 'd')
2187 e = SubElement(c, 'e')
2188
2189 self.assertEqual(
2190 [],
2191 list(a.iterdescendants('a')))
2192 self.assertEqual(
2193 [],
2194 list(a.iterdescendants(tag='a')))
2195
2196 a2 = SubElement(e, 'a')
2197 self.assertEqual(
2198 [a2],
2199 list(a.iterdescendants('a')))
2200
2201 self.assertEqual(
2202 [a2],
2203 list(c.iterdescendants('a')))
2204 self.assertEqual(
2205 [a2],
2206 list(c.iterdescendants(tag='a')))
2207
2209 Element = self.etree.Element
2210 SubElement = self.etree.SubElement
2211
2212 a = Element('a')
2213 b = SubElement(a, 'b')
2214 c = SubElement(a, 'c')
2215 d = SubElement(b, 'd')
2216 e = SubElement(c, 'e')
2217
2218 self.assertEqual(
2219 [b, e],
2220 list(a.iterdescendants(tag=('a', 'b', 'e'))))
2221 self.assertEqual(
2222 [b, e],
2223 list(a.iterdescendants('a', 'b', 'e')))
2224
2225 a2 = SubElement(e, 'a')
2226 self.assertEqual(
2227 [b, a2],
2228 list(a.iterdescendants(tag=('a', 'b'))))
2229 self.assertEqual(
2230 [b, a2],
2231 list(a.iterdescendants('a', 'b')))
2232
2233 self.assertEqual(
2234 [],
2235 list(c.iterdescendants(tag=('x', 'y', 'z'))))
2236 self.assertEqual(
2237 [],
2238 list(c.iterdescendants('x', 'y', 'z')))
2239
2240 self.assertEqual(
2241 [b, d, c, e, a2],
2242 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
2243 self.assertEqual(
2244 [b, d, c, e, a2],
2245 list(a.iterdescendants('x', 'y', 'z', '*')))
2246
2248 Element = self.etree.Element
2249 SubElement = self.etree.SubElement
2250
2251 a = Element('a')
2252 b = SubElement(a, 'b')
2253 c = SubElement(a, 'c')
2254 d = SubElement(b, 'd')
2255 self.assertEqual(
2256 a,
2257 a.getroottree().getroot())
2258 self.assertEqual(
2259 a,
2260 b.getroottree().getroot())
2261 self.assertEqual(
2262 a,
2263 d.getroottree().getroot())
2264
2266 Element = self.etree.Element
2267 SubElement = self.etree.SubElement
2268
2269 a = Element('a')
2270 b = SubElement(a, 'b')
2271 c = SubElement(a, 'c')
2272 self.assertEqual(
2273 None,
2274 a.getnext())
2275 self.assertEqual(
2276 c,
2277 b.getnext())
2278 self.assertEqual(
2279 None,
2280 c.getnext())
2281
2283 Element = self.etree.Element
2284 SubElement = self.etree.SubElement
2285
2286 a = Element('a')
2287 b = SubElement(a, 'b')
2288 c = SubElement(a, 'c')
2289 d = SubElement(b, 'd')
2290 self.assertEqual(
2291 None,
2292 a.getprevious())
2293 self.assertEqual(
2294 b,
2295 c.getprevious())
2296 self.assertEqual(
2297 None,
2298 b.getprevious())
2299
2301 Element = self.etree.Element
2302 SubElement = self.etree.SubElement
2303
2304 a = Element('a')
2305 b = SubElement(a, 'b')
2306 c = SubElement(a, 'c')
2307 d = SubElement(b, 'd')
2308 self.assertEqual(
2309 [],
2310 list(a.itersiblings()))
2311 self.assertEqual(
2312 [c],
2313 list(b.itersiblings()))
2314 self.assertEqual(
2315 [],
2316 list(c.itersiblings()))
2317 self.assertEqual(
2318 [b],
2319 list(c.itersiblings(preceding=True)))
2320 self.assertEqual(
2321 [],
2322 list(b.itersiblings(preceding=True)))
2323
2325 Element = self.etree.Element
2326 SubElement = self.etree.SubElement
2327
2328 a = Element('a')
2329 b = SubElement(a, 'b')
2330 c = SubElement(a, 'c')
2331 d = SubElement(b, 'd')
2332 self.assertEqual(
2333 [],
2334 list(a.itersiblings(tag='XXX')))
2335 self.assertEqual(
2336 [c],
2337 list(b.itersiblings(tag='c')))
2338 self.assertEqual(
2339 [c],
2340 list(b.itersiblings(tag='*')))
2341 self.assertEqual(
2342 [b],
2343 list(c.itersiblings(preceding=True, tag='b')))
2344 self.assertEqual(
2345 [],
2346 list(c.itersiblings(preceding=True, tag='c')))
2347
2349 Element = self.etree.Element
2350 SubElement = self.etree.SubElement
2351
2352 a = Element('a')
2353 b = SubElement(a, 'b')
2354 c = SubElement(a, 'c')
2355 d = SubElement(b, 'd')
2356 e = SubElement(a, 'e')
2357 self.assertEqual(
2358 [],
2359 list(a.itersiblings(tag=('XXX', 'YYY'))))
2360 self.assertEqual(
2361 [c, e],
2362 list(b.itersiblings(tag=('c', 'd', 'e'))))
2363 self.assertEqual(
2364 [b],
2365 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2366 self.assertEqual(
2367 [c, b],
2368 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2369
2371 parseid = self.etree.parseid
2372 XML = self.etree.XML
2373 xml_text = _bytes('''
2374 <!DOCTYPE document [
2375 <!ELEMENT document (h1,p)*>
2376 <!ELEMENT h1 (#PCDATA)>
2377 <!ATTLIST h1 myid ID #REQUIRED>
2378 <!ELEMENT p (#PCDATA)>
2379 <!ATTLIST p someid ID #REQUIRED>
2380 ]>
2381 <document>
2382 <h1 myid="chapter1">...</h1>
2383 <p id="note1" class="note">...</p>
2384 <p>Regular paragraph.</p>
2385 <p xml:id="xmlid">XML:ID paragraph.</p>
2386 <p someid="warn1" class="warning">...</p>
2387 </document>
2388 ''')
2389
2390 tree, dic = parseid(BytesIO(xml_text))
2391 root = tree.getroot()
2392 root2 = XML(xml_text)
2393 self.assertEqual(self._writeElement(root),
2394 self._writeElement(root2))
2395 expected = {
2396 "chapter1" : root[0],
2397 "xmlid" : root[3],
2398 "warn1" : root[4]
2399 }
2400 self.assertTrue("chapter1" in dic)
2401 self.assertTrue("warn1" in dic)
2402 self.assertTrue("xmlid" in dic)
2403 self._checkIDDict(dic, expected)
2404
2406 XMLDTDID = self.etree.XMLDTDID
2407 XML = self.etree.XML
2408 xml_text = _bytes('''
2409 <!DOCTYPE document [
2410 <!ELEMENT document (h1,p)*>
2411 <!ELEMENT h1 (#PCDATA)>
2412 <!ATTLIST h1 myid ID #REQUIRED>
2413 <!ELEMENT p (#PCDATA)>
2414 <!ATTLIST p someid ID #REQUIRED>
2415 ]>
2416 <document>
2417 <h1 myid="chapter1">...</h1>
2418 <p id="note1" class="note">...</p>
2419 <p>Regular paragraph.</p>
2420 <p xml:id="xmlid">XML:ID paragraph.</p>
2421 <p someid="warn1" class="warning">...</p>
2422 </document>
2423 ''')
2424
2425 root, dic = XMLDTDID(xml_text)
2426 root2 = XML(xml_text)
2427 self.assertEqual(self._writeElement(root),
2428 self._writeElement(root2))
2429 expected = {
2430 "chapter1" : root[0],
2431 "xmlid" : root[3],
2432 "warn1" : root[4]
2433 }
2434 self.assertTrue("chapter1" in dic)
2435 self.assertTrue("warn1" in dic)
2436 self.assertTrue("xmlid" in dic)
2437 self._checkIDDict(dic, expected)
2438
2440 XMLDTDID = self.etree.XMLDTDID
2441 XML = self.etree.XML
2442 xml_text = _bytes('''
2443 <document>
2444 <h1 myid="chapter1">...</h1>
2445 <p id="note1" class="note">...</p>
2446 <p>Regular paragraph.</p>
2447 <p someid="warn1" class="warning">...</p>
2448 </document>
2449 ''')
2450
2451 root, dic = XMLDTDID(xml_text)
2452 root2 = XML(xml_text)
2453 self.assertEqual(self._writeElement(root),
2454 self._writeElement(root2))
2455 expected = {}
2456 self._checkIDDict(dic, expected)
2457
2459 XMLDTDID = self.etree.XMLDTDID
2460 XML = self.etree.XML
2461 xml_text = _bytes('''
2462 <!DOCTYPE document [
2463 <!ELEMENT document (h1,p)*>
2464 <!ELEMENT h1 (#PCDATA)>
2465 <!ATTLIST h1 myid ID #REQUIRED>
2466 <!ELEMENT p (#PCDATA)>
2467 <!ATTLIST p someid ID #REQUIRED>
2468 ]>
2469 <document>
2470 <h1 myid="chapter1">...</h1>
2471 <p id="note1" class="note">...</p>
2472 <p>Regular paragraph.</p>
2473 <p xml:id="xmlid">XML:ID paragraph.</p>
2474 <p someid="warn1" class="warning">...</p>
2475 </document>
2476 ''')
2477
2478 parser = etree.XMLParser(collect_ids=False)
2479 root, dic = XMLDTDID(xml_text, parser=parser)
2480 root2 = XML(xml_text)
2481 self.assertEqual(self._writeElement(root),
2482 self._writeElement(root2))
2483 self.assertFalse(dic)
2484 self._checkIDDict(dic, {})
2485
2487 self.assertEqual(len(dic),
2488 len(expected))
2489 self.assertEqual(sorted(dic.items()),
2490 sorted(expected.items()))
2491 if sys.version_info < (3,):
2492 self.assertEqual(sorted(dic.iteritems()),
2493 sorted(expected.iteritems()))
2494 self.assertEqual(sorted(dic.keys()),
2495 sorted(expected.keys()))
2496 if sys.version_info < (3,):
2497 self.assertEqual(sorted(dic.iterkeys()),
2498 sorted(expected.iterkeys()))
2499 if sys.version_info < (3,):
2500 self.assertEqual(sorted(dic.values()),
2501 sorted(expected.values()))
2502 self.assertEqual(sorted(dic.itervalues()),
2503 sorted(expected.itervalues()))
2504
2506 etree = self.etree
2507
2508 r = {'foo': 'http://ns.infrae.com/foo'}
2509 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2510 self.assertEqual(
2511 'foo',
2512 e.prefix)
2513 self.assertEqual(
2514 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2515 self._writeElement(e))
2516
2518 etree = self.etree
2519
2520 r = {None: 'http://ns.infrae.com/foo'}
2521 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2522 self.assertEqual(
2523 None,
2524 e.prefix)
2525 self.assertEqual(
2526 '{http://ns.infrae.com/foo}bar',
2527 e.tag)
2528 self.assertEqual(
2529 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2530 self._writeElement(e))
2531
2533 etree = self.etree
2534
2535 r = {None: 'http://ns.infrae.com/foo', 'p': 'http://test/'}
2536 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2537 self.assertEqual(None, e.prefix)
2538 self.assertEqual('{http://ns.infrae.com/foo}bar', e.tag)
2539 self.assertEqual(
2540 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:p="http://test/"></bar>'),
2541 self._writeElement(e))
2542
2544 etree = self.etree
2545
2546 r = {None: 'http://ns.infrae.com/foo',
2547 'hoi': 'http://ns.infrae.com/hoi'}
2548 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2549 e.set('{http://ns.infrae.com/hoi}test', 'value')
2550 self.assertEqual(
2551 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2552 self._writeElement(e))
2553
2555 etree = self.etree
2556
2557 root = etree.Element('{http://test/ns}root',
2558 nsmap={None: 'http://test/ns'})
2559 sub = etree.Element('{http://test/ns}sub',
2560 nsmap={'test': 'http://test/ns'})
2561
2562 sub.attrib['{http://test/ns}attr'] = 'value'
2563 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2564 self.assertEqual(
2565 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2566 etree.tostring(sub))
2567
2568 root.append(sub)
2569 self.assertEqual(
2570 _bytes('<root xmlns="http://test/ns">'
2571 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2572 '</root>'),
2573 etree.tostring(root))
2574
2576 etree = self.etree
2577
2578 root = etree.Element('root')
2579 sub = etree.Element('{http://test/ns}sub',
2580 nsmap={'test': 'http://test/ns'})
2581
2582 sub.attrib['{http://test/ns}attr'] = 'value'
2583 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2584 self.assertEqual(
2585 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2586 etree.tostring(sub))
2587
2588 root.append(sub)
2589 self.assertEqual(
2590 _bytes('<root>'
2591 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2592 '</root>'),
2593 etree.tostring(root))
2594
2596 etree = self.etree
2597
2598 root = etree.Element('root')
2599 sub = etree.Element('{http://test/ns}sub',
2600 nsmap={None: 'http://test/ns'})
2601
2602 sub.attrib['{http://test/ns}attr'] = 'value'
2603 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2604 self.assertEqual(
2605 _bytes('<sub xmlns="http://test/ns" '
2606 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2607 etree.tostring(sub))
2608
2609 root.append(sub)
2610 self.assertEqual(
2611 _bytes('<root>'
2612 '<sub xmlns="http://test/ns"'
2613 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2614 '</root>'),
2615 etree.tostring(root))
2616
2618 etree = self.etree
2619
2620 root = etree.Element('{http://test/ns}root',
2621 nsmap={'test': 'http://test/ns',
2622 None: 'http://test/ns'})
2623 sub = etree.Element('{http://test/ns}sub',
2624 nsmap={None: 'http://test/ns'})
2625
2626 sub.attrib['{http://test/ns}attr'] = 'value'
2627 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2628 self.assertEqual(
2629 _bytes('<sub xmlns="http://test/ns" '
2630 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2631 etree.tostring(sub))
2632
2633 root.append(sub)
2634 self.assertEqual(
2635 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2636 '<test:sub test:attr="value"/>'
2637 '</test:root>'),
2638 etree.tostring(root))
2639
2641 etree = self.etree
2642 r = {None: 'http://ns.infrae.com/foo',
2643 'hoi': 'http://ns.infrae.com/hoi'}
2644 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2645 tree = etree.ElementTree(element=e)
2646 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2647 self.assertEqual(
2648 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2649 self._writeElement(e))
2650
2652 etree = self.etree
2653
2654 r = {None: 'http://ns.infrae.com/foo'}
2655 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2656 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2657
2658 e1.append(e2)
2659
2660 self.assertEqual(
2661 None,
2662 e1.prefix)
2663 self.assertEqual(
2664 None,
2665 e1[0].prefix)
2666 self.assertEqual(
2667 '{http://ns.infrae.com/foo}bar',
2668 e1.tag)
2669 self.assertEqual(
2670 '{http://ns.infrae.com/foo}bar',
2671 e1[0].tag)
2672
2674 etree = self.etree
2675
2676 r = {None: 'http://ns.infrae.com/BAR'}
2677 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2678 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2679
2680 e1.append(e2)
2681
2682 self.assertEqual(
2683 None,
2684 e1.prefix)
2685 self.assertNotEqual(
2686 None,
2687 e2.prefix)
2688 self.assertEqual(
2689 '{http://ns.infrae.com/BAR}bar',
2690 e1.tag)
2691 self.assertEqual(
2692 '{http://ns.infrae.com/foo}bar',
2693 e2.tag)
2694
2696 ns_href = "http://a.b.c"
2697 one = self.etree.fromstring(
2698 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2699 baz = one[0][0]
2700
2701 two = self.etree.fromstring(
2702 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2703 two.append(baz)
2704 del one # make sure the source document is deallocated
2705
2706 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2707 self.assertEqual(
2708 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2709 self.etree.tostring(two))
2710
2712 xml = _bytes(
2713 '<foo xmlns="F" xmlns:x="x">'
2714 '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">'
2715 '<ns:baz/>'
2716 '</bar></foo>'
2717 )
2718 root = self.etree.fromstring(xml)
2719 self.assertEqual(xml, self.etree.tostring(root))
2720 self.etree.cleanup_namespaces(root)
2721 self.assertEqual(
2722 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
2723 self.etree.tostring(root))
2724
2726 xml = _bytes(
2727 '<foo xmlns="F" xmlns:x="X" xmlns:a="A">'
2728 '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">'
2729 '<ns:baz a:test="attr"/>'
2730 '</bar></foo>'
2731 )
2732 root = self.etree.fromstring(xml)
2733 self.assertEqual(xml, self.etree.tostring(root))
2734 self.etree.cleanup_namespaces(root)
2735 self.assertEqual(
2736 _bytes('<foo xmlns="F" xmlns:a="A">'
2737 '<bar xmlns:ns="NS" xmlns="B">'
2738 '<ns:baz a:test="attr"/>'
2739 '</bar></foo>'),
2740 self.etree.tostring(root))
2741
2743 xml = ('<n12:foo ' +
2744 ' '.join('xmlns:n{n}="NS{n}"'.format(n=i) for i in range(100)) +
2745 '><n68:a/></n12:foo>').encode('utf8')
2746 root = self.etree.fromstring(xml)
2747 self.assertEqual(xml, self.etree.tostring(root))
2748 self.etree.cleanup_namespaces(root)
2749 self.assertEqual(
2750 b'<n12:foo xmlns:n12="NS12" xmlns:n68="NS68"><n68:a/></n12:foo>',
2751 self.etree.tostring(root))
2752
2754 xml = ('<root>' +
2755 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) +
2756 '<n64:x/>' + '</a>'*100 + '</root>').encode('utf8')
2757 root = self.etree.fromstring(xml)
2758 self.assertEqual(xml, self.etree.tostring(root))
2759 self.etree.cleanup_namespaces(root)
2760 self.assertEqual(
2761 b'<root>' + b'<a>'*64 + b'<a xmlns:n64="NS64">' + b'<a>'*35 +
2762 b'<n64:x/>' + b'</a>'*100 + b'</root>',
2763 self.etree.tostring(root))
2764
2766 xml = ('<root>' +
2767 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) +
2768 '<n64:x xmlns:a="A" a:attr="X"/>' +
2769 '</a>'*100 +
2770 '</root>').encode('utf8')
2771 root = self.etree.fromstring(xml)
2772 self.assertEqual(xml, self.etree.tostring(root))
2773 self.etree.cleanup_namespaces(root, top_nsmap={'n64': 'NS64'})
2774 self.assertEqual(
2775 b'<root xmlns:n64="NS64">' + b'<a>'*100 +
2776 b'<n64:x xmlns:a="A" a:attr="X"/>' + b'</a>'*100 + b'</root>',
2777 self.etree.tostring(root))
2778
2780 xml = ('<root xmlns:n64="NS64" xmlns:foo="FOO" xmlns:unused1="UNUSED" xmlns:no="NO">'
2781 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>'
2782 '<foo>foo:bar</foo>'
2783 '</root>').encode('utf8')
2784 root = self.etree.fromstring(xml)
2785 self.assertEqual(xml, self.etree.tostring(root))
2786 self.etree.cleanup_namespaces(root, keep_ns_prefixes=['foo'])
2787 self.assertEqual(
2788 b'<root xmlns:n64="NS64" xmlns:foo="FOO">'
2789 b'<a><n64:x xmlns:a="A" a:attr="X"/></a>'
2790 b'<foo>foo:bar</foo>'
2791 b'</root>',
2792 self.etree.tostring(root))
2793
2795 xml = ('<root xmlns:n64="NS64" xmlns:unused1="UNUSED" xmlns:no="NO">'
2796 '<sub xmlns:foo="FOO">'
2797 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>'
2798 '<foo>foo:bar</foo>'
2799 '</sub>'
2800 '</root>').encode('utf8')
2801 root = self.etree.fromstring(xml)
2802 self.assertEqual(xml, self.etree.tostring(root))
2803 self.etree.cleanup_namespaces(
2804 root,
2805 top_nsmap={'foo': 'FOO', 'unused1': 'UNUSED'},
2806 keep_ns_prefixes=['foo'])
2807 self.assertEqual(
2808 b'<root xmlns:n64="NS64" xmlns:foo="FOO">'
2809 b'<sub>'
2810 b'<a><n64:x xmlns:a="A" a:attr="X"/></a>'
2811 b'<foo>foo:bar</foo>'
2812 b'</sub>'
2813 b'</root>',
2814 self.etree.tostring(root))
2815
2817 etree = self.etree
2818
2819 r = {None: 'http://ns.infrae.com/foo',
2820 'hoi': 'http://ns.infrae.com/hoi'}
2821 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2822 self.assertEqual(
2823 r,
2824 e.nsmap)
2825
2827 etree = self.etree
2828
2829 re = {None: 'http://ns.infrae.com/foo',
2830 'hoi': 'http://ns.infrae.com/hoi'}
2831 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2832
2833 rs = {None: 'http://ns.infrae.com/honk',
2834 'top': 'http://ns.infrae.com/top'}
2835 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2836
2837 r = re.copy()
2838 r.update(rs)
2839 self.assertEqual(re, e.nsmap)
2840 self.assertEqual(r, s.nsmap)
2841
2843 etree = self.etree
2844 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2845 self.assertEqual({'hha': None}, el.nsmap)
2846
2848 Element = self.etree.Element
2849 SubElement = self.etree.SubElement
2850
2851 a = Element('a')
2852 b = SubElement(a, 'b')
2853 c = SubElement(a, 'c')
2854 d = SubElement(b, 'd')
2855 e = SubElement(c, 'e')
2856 f = SubElement(c, 'f')
2857
2858 self.assertEqual(
2859 [a, b],
2860 list(a.getiterator('a', 'b')))
2861 self.assertEqual(
2862 [],
2863 list(a.getiterator('x', 'y')))
2864 self.assertEqual(
2865 [a, f],
2866 list(a.getiterator('f', 'a')))
2867 self.assertEqual(
2868 [c, e, f],
2869 list(c.getiterator('c', '*', 'a')))
2870 self.assertEqual(
2871 [],
2872 list(a.getiterator( (), () )))
2873
2875 Element = self.etree.Element
2876 SubElement = self.etree.SubElement
2877
2878 a = Element('a')
2879 b = SubElement(a, 'b')
2880 c = SubElement(a, 'c')
2881 d = SubElement(b, 'd')
2882 e = SubElement(c, 'e')
2883 f = SubElement(c, 'f')
2884
2885 self.assertEqual(
2886 [a, b],
2887 list(a.getiterator( ('a', 'b') )))
2888 self.assertEqual(
2889 [],
2890 list(a.getiterator( ('x', 'y') )))
2891 self.assertEqual(
2892 [a, f],
2893 list(a.getiterator( ('f', 'a') )))
2894 self.assertEqual(
2895 [c, e, f],
2896 list(c.getiterator( ('c', '*', 'a') )))
2897 self.assertEqual(
2898 [],
2899 list(a.getiterator( () )))
2900
2902 Element = self.etree.Element
2903 SubElement = self.etree.SubElement
2904
2905 a = Element('{a}a')
2906 b = SubElement(a, '{a}b')
2907 c = SubElement(a, '{a}c')
2908 d = SubElement(b, '{b}d')
2909 e = SubElement(c, '{a}e')
2910 f = SubElement(c, '{b}f')
2911 g = SubElement(c, 'g')
2912
2913 self.assertEqual(
2914 [a],
2915 list(a.getiterator('{a}a')))
2916 self.assertEqual(
2917 [],
2918 list(a.getiterator('{b}a')))
2919 self.assertEqual(
2920 [],
2921 list(a.getiterator('a')))
2922 self.assertEqual(
2923 [a,b,d,c,e,f,g],
2924 list(a.getiterator('*')))
2925 self.assertEqual(
2926 [f],
2927 list(c.getiterator('{b}*')))
2928 self.assertEqual(
2929 [d, f],
2930 list(a.getiterator('{b}*')))
2931 self.assertEqual(
2932 [g],
2933 list(a.getiterator('g')))
2934 self.assertEqual(
2935 [g],
2936 list(a.getiterator('{}g')))
2937 self.assertEqual(
2938 [g],
2939 list(a.getiterator('{}*')))
2940
2942 Element = self.etree.Element
2943 SubElement = self.etree.SubElement
2944
2945 a = Element('{a}a')
2946 b = SubElement(a, '{nsA}b')
2947 c = SubElement(b, '{nsB}b')
2948 d = SubElement(a, 'b')
2949 e = SubElement(a, '{nsA}e')
2950 f = SubElement(e, '{nsB}e')
2951 g = SubElement(e, 'e')
2952
2953 self.assertEqual(
2954 [b, c, d],
2955 list(a.getiterator('{*}b')))
2956 self.assertEqual(
2957 [e, f, g],
2958 list(a.getiterator('{*}e')))
2959 self.assertEqual(
2960 [a, b, c, d, e, f, g],
2961 list(a.getiterator('{*}*')))
2962
2964 Element = self.etree.Element
2965 Entity = self.etree.Entity
2966 SubElement = self.etree.SubElement
2967
2968 a = Element('a')
2969 b = SubElement(a, 'b')
2970 entity_b = Entity("TEST-b")
2971 b.append(entity_b)
2972
2973 self.assertEqual(
2974 [entity_b],
2975 list(a.getiterator(Entity)))
2976
2977 entity_a = Entity("TEST-a")
2978 a.append(entity_a)
2979
2980 self.assertEqual(
2981 [entity_b, entity_a],
2982 list(a.getiterator(Entity)))
2983
2984 self.assertEqual(
2985 [entity_b],
2986 list(b.getiterator(Entity)))
2987
2989 Element = self.etree.Element
2990 Comment = self.etree.Comment
2991 PI = self.etree.PI
2992 SubElement = self.etree.SubElement
2993
2994 a = Element('a')
2995 b = SubElement(a, 'b')
2996 a.append(Comment("test"))
2997 a.append(PI("pi", "content"))
2998 c = SubElement(a, 'c')
2999
3000 self.assertEqual(
3001 [a, b, c],
3002 list(a.getiterator(Element)))
3003
3005 # ElementTree iterates over everything here
3006 Element = self.etree.Element
3007 Comment = self.etree.Comment
3008 PI = self.etree.PI
3009 SubElement = self.etree.SubElement
3010
3011 a = Element('a')
3012 b = SubElement(a, 'b')
3013 a.append(Comment("test"))
3014 a.append(PI("pi", "content"))
3015 c = SubElement(a, 'c')
3016
3017 self.assertEqual(
3018 [a, b, c],
3019 list(a.getiterator('*')))
3020
3022 a = etree.Element("a")
3023 b = etree.SubElement(a, "b")
3024 c = etree.SubElement(a, "c")
3025 d1 = etree.SubElement(c, "d")
3026 d2 = etree.SubElement(c, "d")
3027 c.text = d1.text = 'TEXT'
3028
3029 tree = etree.ElementTree(a)
3030 self.assertEqual('.', tree.getelementpath(a))
3031 self.assertEqual('c/d[1]', tree.getelementpath(d1))
3032 self.assertEqual('c/d[2]', tree.getelementpath(d2))
3033
3034 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
3035 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
3036
3037 tree = etree.ElementTree(c)
3038 self.assertEqual('.', tree.getelementpath(c))
3039 self.assertEqual('d[2]', tree.getelementpath(d2))
3040 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
3041
3042 tree = etree.ElementTree(b) # not a parent of a/c/d1/d2
3043 self.assertEqual('.', tree.getelementpath(b))
3044 self.assertRaises(ValueError, tree.getelementpath, a)
3045 self.assertRaises(ValueError, tree.getelementpath, c)
3046 self.assertRaises(ValueError, tree.getelementpath, d2)
3047
3049 a = etree.Element("{http://ns1/}a")
3050 b = etree.SubElement(a, "{http://ns1/}b")
3051 c = etree.SubElement(a, "{http://ns1/}c")
3052 d1 = etree.SubElement(c, "{http://ns1/}d")
3053 d2 = etree.SubElement(c, "{http://ns2/}d")
3054 d3 = etree.SubElement(c, "{http://ns1/}d")
3055
3056 tree = etree.ElementTree(a)
3057 self.assertEqual('.', tree.getelementpath(a))
3058 self.assertEqual('{http://ns1/}c/{http://ns1/}d[1]',
3059 tree.getelementpath(d1))
3060 self.assertEqual('{http://ns1/}c/{http://ns2/}d',
3061 tree.getelementpath(d2))
3062 self.assertEqual('{http://ns1/}c/{http://ns1/}d[2]',
3063 tree.getelementpath(d3))
3064
3065 self.assertEqual(a, tree.find(tree.getelementpath(a)))
3066 self.assertEqual(b, tree.find(tree.getelementpath(b)))
3067 self.assertEqual(c, tree.find(tree.getelementpath(c)))
3068 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
3069 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
3070 self.assertEqual(d3, tree.find(tree.getelementpath(d3)))
3071
3072 tree = etree.ElementTree(c)
3073 self.assertEqual('{http://ns1/}d[1]', tree.getelementpath(d1))
3074 self.assertEqual('{http://ns2/}d', tree.getelementpath(d2))
3075 self.assertEqual('{http://ns1/}d[2]', tree.getelementpath(d3))
3076 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
3077 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
3078 self.assertEqual(d3, tree.find(tree.getelementpath(d3)))
3079
3080 tree = etree.ElementTree(b) # not a parent of d1/d2
3081 self.assertRaises(ValueError, tree.getelementpath, d1)
3082 self.assertRaises(ValueError, tree.getelementpath, d2)
3083
3085 XML = self.etree.XML
3086 ElementTree = self.etree.ElementTree
3087 QName = self.etree.QName
3088 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
3089 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
3090
3092 XML = self.etree.XML
3093 ElementTree = self.etree.ElementTree
3094 QName = self.etree.QName
3095 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
3096 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
3097
3099 XML = self.etree.XML
3100 ElementTree = self.etree.ElementTree
3101 QName = self.etree.QName
3102 tree = ElementTree(XML(
3103 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
3104 self.assertEqual(len(list(tree.findall(QName("b")))), 2)
3105 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
3106
3108 XML = self.etree.XML
3109 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
3110 self.assertEqual(len(root.findall(".//{X}b")), 2)
3111 self.assertEqual(len(root.findall(".//{X}*")), 2)
3112 self.assertEqual(len(root.findall(".//b")), 3)
3113
3115 XML = self.etree.XML
3116 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
3117 nsmap = {'xx': 'X'}
3118 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
3119 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
3120 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
3121 nsmap = {'xx': 'Y'}
3122 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
3123 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
3124 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
3125
3127 XML = self.etree.XML
3128 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
3129 nsmap = {'xx': 'X'}
3130 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
3131 nsmap = {'xx': 'X', None: 'Y'}
3132 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 1)
3133 nsmap = {'xx': 'X', '': 'Y'}
3134 self.assertRaises(ValueError, root.findall, ".//xx:b", namespaces=nsmap)
3135
3137 XML = self.etree.XML
3138 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>'))
3139 self.assertRaises(SyntaxError, root.findall, '')
3140 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element
3141 self.assertRaises(SyntaxError, root.findall, './//')
3142
3144 etree = self.etree
3145 e = etree.Element('foo')
3146 for i in range(10):
3147 etree.SubElement(e, 'a%s' % i)
3148 for i in range(10):
3149 self.assertEqual(
3150 i,
3151 e.index(e[i]))
3152 self.assertEqual(
3153 3, e.index(e[3], 3))
3154 self.assertRaises(
3155 ValueError, e.index, e[3], 4)
3156 self.assertRaises(
3157 ValueError, e.index, e[3], 0, 2)
3158 self.assertRaises(
3159 ValueError, e.index, e[8], 0, -3)
3160 self.assertRaises(
3161 ValueError, e.index, e[8], -5, -3)
3162 self.assertEqual(
3163 8, e.index(e[8], 0, -1))
3164 self.assertEqual(
3165 8, e.index(e[8], -12, -1))
3166 self.assertEqual(
3167 0, e.index(e[0], -12, -1))
3168
3170 etree = self.etree
3171 e = etree.Element('foo')
3172 for i in range(10):
3173 el = etree.SubElement(e, 'a%s' % i)
3174 el.text = "text%d" % i
3175 el.tail = "tail%d" % i
3176
3177 child0 = e[0]
3178 child1 = e[1]
3179 child2 = e[2]
3180
3181 e.replace(e[0], e[1])
3182 self.assertEqual(
3183 9, len(e))
3184 self.assertEqual(
3185 child1, e[0])
3186 self.assertEqual(
3187 child1.text, "text1")
3188 self.assertEqual(
3189 child1.tail, "tail1")
3190 self.assertEqual(
3191 child0.tail, "tail0")
3192 self.assertEqual(
3193 child2, e[1])
3194
3195 e.replace(e[-1], e[0])
3196 self.assertEqual(
3197 child1, e[-1])
3198 self.assertEqual(
3199 child1.text, "text1")
3200 self.assertEqual(
3201 child1.tail, "tail1")
3202 self.assertEqual(
3203 child2, e[0])
3204
3206 etree = self.etree
3207 e = etree.Element('foo')
3208 for i in range(10):
3209 etree.SubElement(e, 'a%s' % i)
3210
3211 new_element = etree.Element("test")
3212 new_element.text = "TESTTEXT"
3213 new_element.tail = "TESTTAIL"
3214 child1 = e[1]
3215 e.replace(e[0], new_element)
3216 self.assertEqual(
3217 new_element, e[0])
3218 self.assertEqual(
3219 "TESTTEXT",
3220 e[0].text)
3221 self.assertEqual(
3222 "TESTTAIL",
3223 e[0].tail)
3224 self.assertEqual(
3225 child1, e[1])
3226
3228 Element = self.etree.Element
3229 SubElement = self.etree.SubElement
3230
3231 a = Element('a')
3232
3233 e = Element('e')
3234 f = Element('f')
3235 g = Element('g')
3236
3237 s = [e, f, g]
3238 a[::-1] = s
3239 self.assertEqual(
3240 [g, f, e],
3241 list(a))
3242
3244 Element = self.etree.Element
3245 SubElement = self.etree.SubElement
3246
3247 a = Element('a')
3248 b = SubElement(a, 'b')
3249 c = SubElement(a, 'c')
3250 d = SubElement(a, 'd')
3251 e = SubElement(a, 'e')
3252
3253 x = Element('x')
3254 y = Element('y')
3255
3256 a[1::2] = [x, y]
3257 self.assertEqual(
3258 [b, x, d, y],
3259 list(a))
3260
3262 Element = self.etree.Element
3263 SubElement = self.etree.SubElement
3264
3265 a = Element('a')
3266 b = SubElement(a, 'b')
3267 c = SubElement(a, 'c')
3268 d = SubElement(a, 'd')
3269 e = SubElement(a, 'e')
3270
3271 x = Element('x')
3272 y = Element('y')
3273
3274 a[1::-1] = [x, y]
3275 self.assertEqual(
3276 [y, x, d, e],
3277 list(a))
3278
3280 Element = self.etree.Element
3281 SubElement = self.etree.SubElement
3282
3283 a = Element('a')
3284 b = SubElement(a, 'b')
3285 c = SubElement(a, 'c')
3286 d = SubElement(a, 'd')
3287 e = SubElement(a, 'e')
3288
3289 x = Element('x')
3290 y = Element('y')
3291
3292 a[::-2] = [x, y]
3293 self.assertEqual(
3294 [b, y, d, x],
3295 list(a))
3296
3298 Element = self.etree.Element
3299 SubElement = self.etree.SubElement
3300 try:
3301 slice
3302 except NameError:
3303 print("slice() not found")
3304 return
3305
3306 a = Element('a')
3307 b = SubElement(a, 'b')
3308 c = SubElement(a, 'c')
3309 d = SubElement(a, 'd')
3310 e = SubElement(a, 'e')
3311
3312 x = Element('x')
3313 y = Element('y')
3314 z = Element('z')
3315
3316 self.assertRaises(
3317 ValueError,
3318 operator.setitem, a, slice(1,None,2), [x, y, z])
3319
3320 self.assertEqual(
3321 [b, c, d, e],
3322 list(a))
3323
3325 XML = self.etree.XML
3326 root = XML(_bytes('''<?xml version="1.0"?>
3327 <root><test>
3328
3329 <bla/></test>
3330 </root>
3331 '''))
3332
3333 self.assertEqual(
3334 [2, 2, 4],
3335 [ el.sourceline for el in root.getiterator() ])
3336
3338 XML = self.etree.XML
3339 root = XML(_bytes(
3340 '<?xml version="1.0"?>\n'
3341 '<root>' + '\n' * 65536 +
3342 '<p>' + '\n' * 65536 + '</p>\n' +
3343 '<br/>\n'
3344 '</root>'))
3345
3346 if self.etree.LIBXML_VERSION >= (2, 9):
3347 expected = [2, 131074, 131076]
3348 else:
3349 expected = [2, 65535, 65535]
3350
3351 self.assertEqual(expected, [el.sourceline for el in root.iter()])
3352
3354 parse = self.etree.parse
3355 tree = parse(fileInTestDir('include/test_xinclude.xml'))
3356
3357 self.assertEqual(
3358 [1, 2, 3],
3359 [ el.sourceline for el in tree.getiterator() ])
3360
3362 iterparse = self.etree.iterparse
3363 lines = [ el.sourceline for (event, el) in
3364 iterparse(fileInTestDir('include/test_xinclude.xml')) ]
3365
3366 self.assertEqual(
3367 [2, 3, 1],
3368 lines)
3369
3371 iterparse = self.etree.iterparse
3372 lines = [ el.sourceline for (event, el) in
3373 iterparse(fileInTestDir('include/test_xinclude.xml'),
3374 events=("start",)) ]
3375
3376 self.assertEqual(
3377 [1, 2, 3],
3378 lines)
3379
3381 Element = self.etree.Element
3382 SubElement = self.etree.SubElement
3383 el = Element("test")
3384 self.assertEqual(None, el.sourceline)
3385
3386 child = SubElement(el, "test")
3387 self.assertEqual(None, el.sourceline)
3388 self.assertEqual(None, child.sourceline)
3389
3391 etree = self.etree
3392 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3393 docinfo = root.getroottree().docinfo
3394 self.assertEqual(docinfo.URL, "http://no/such/url")
3395
3397 etree = self.etree
3398 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3399 docinfo = root.getroottree().docinfo
3400 self.assertEqual(docinfo.URL, "http://no/such/url")
3401 docinfo.URL = "https://secret/url"
3402 self.assertEqual(docinfo.URL, "https://secret/url")
3403
3405 etree = self.etree
3406 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
3407 docinfo = tree.docinfo
3408 self.assertEqual(docinfo.URL, "http://no/such/url")
3409
3411 etree = self.etree
3412 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3413 base_url="http://no/such/url")
3414 docinfo = tree.docinfo
3415 self.assertEqual(docinfo.URL, "http://no/such/url")
3416
3418 etree = self.etree
3419 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
3420 docinfo = root.getroottree().docinfo
3421 self.assertEqual(docinfo.URL, "http://no/such/url")
3422
3424 etree = self.etree
3425 xml_header = '<?xml version="1.0" encoding="ascii"?>'
3426 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3427 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3428 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
3429
3430 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3431
3432 tree = etree.parse(BytesIO(xml))
3433 docinfo = tree.docinfo
3434 self.assertEqual(docinfo.encoding, "ascii")
3435 self.assertEqual(docinfo.xml_version, "1.0")
3436 self.assertEqual(docinfo.public_id, pub_id)
3437 self.assertEqual(docinfo.system_url, sys_id)
3438 self.assertEqual(docinfo.root_name, 'html')
3439 self.assertEqual(docinfo.doctype, doctype_string)
3440
3442 etree = self.etree
3443 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
3444 sys_id = "some.dtd"
3445 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
3446 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3447
3448 tree = etree.parse(BytesIO(xml))
3449 docinfo = tree.docinfo
3450 self.assertEqual(docinfo.encoding, "UTF-8")
3451 self.assertEqual(docinfo.xml_version, "1.0")
3452 self.assertEqual(docinfo.public_id, None)
3453 self.assertEqual(docinfo.system_url, sys_id)
3454 self.assertEqual(docinfo.root_name, 'html')
3455 self.assertEqual(docinfo.doctype, doctype_string)
3456
3458 etree = self.etree
3459 xml = _bytes('<html><body></body></html>')
3460 tree = etree.parse(BytesIO(xml))
3461 docinfo = tree.docinfo
3462 self.assertEqual(docinfo.encoding, "UTF-8")
3463 self.assertEqual(docinfo.xml_version, "1.0")
3464 self.assertEqual(docinfo.public_id, None)
3465 self.assertEqual(docinfo.system_url, None)
3466 self.assertEqual(docinfo.root_name, 'html')
3467 self.assertEqual(docinfo.doctype, '')
3468
3470 etree = self.etree
3471 xml = _bytes('<!DOCTYPE root><root></root>')
3472 tree = etree.parse(BytesIO(xml))
3473 docinfo = tree.docinfo
3474 self.assertEqual(docinfo.encoding, "UTF-8")
3475 self.assertEqual(docinfo.xml_version, "1.0")
3476 self.assertEqual(docinfo.public_id, None)
3477 self.assertEqual(docinfo.system_url, None)
3478 self.assertEqual(docinfo.root_name, 'root')
3479 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
3480
3482 etree = self.etree
3483 xml = _bytes('<!DOCTYPE root>\n<root/>')
3484 tree = etree.parse(BytesIO(xml))
3485 self.assertEqual(xml, etree.tostring(tree))
3486
3488 etree = self.etree
3489 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3490 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3491 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
3492
3493 xml = _bytes('<!DOCTYPE root>\n<root/>')
3494 tree = etree.parse(BytesIO(xml))
3495 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
3496 etree.tostring(tree, doctype=doctype_string))
3497
3499 etree = self.etree
3500 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3501 self.assertEqual(root.base, "http://no/such/url")
3502 self.assertEqual(
3503 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3504 root.base = "https://secret/url"
3505 self.assertEqual(root.base, "https://secret/url")
3506 self.assertEqual(
3507 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3508 "https://secret/url")
3509
3511 etree = self.etree
3512 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3513 self.assertEqual(root.base, "http://no/such/url")
3514 self.assertEqual(
3515 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3516 root.set('{http://www.w3.org/XML/1998/namespace}base',
3517 "https://secret/url")
3518 self.assertEqual(root.base, "https://secret/url")
3519 self.assertEqual(
3520 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3521 "https://secret/url")
3522
3524 etree = self.etree
3525 root = etree.HTML(_bytes("<html><body></body></html>"),
3526 base_url="http://no/such/url")
3527 self.assertEqual(root.base, "http://no/such/url")
3528
3530 etree = self.etree
3531 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
3532 self.assertEqual(root.base, "http://no/such/url")
3533
3535 # parse from a file object that returns unicode strings
3536 f = LargeFileLikeUnicode()
3537 tree = self.etree.parse(f)
3538 root = tree.getroot()
3539 self.assertTrue(root.tag.endswith('root'))
3540
3542 # check that DTDs that go in also go back out
3543 xml = _bytes('''\
3544 <!DOCTYPE test SYSTEM "test.dtd" [
3545 <!ENTITY entity "tasty">
3546 <!ELEMENT test (a)>
3547 <!ELEMENT a (#PCDATA)>
3548 ]>
3549 <test><a>test-test</a></test>\
3550 ''')
3551 tree = self.etree.parse(BytesIO(xml))
3552 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
3553 xml.replace(_bytes(" "), _bytes("")))
3554
3556 Element = self.etree.Element
3557
3558 a = Element('a')
3559 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3560 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3561
3562 self.assertRaises(ValueError, Element, 'ha\0ho')
3563
3565 Element = self.etree.Element
3566
3567 a = Element('a')
3568 self.assertRaises(ValueError, setattr, a, "text",
3569 _str('ha\0ho'))
3570 self.assertRaises(ValueError, setattr, a, "tail",
3571 _str('ha\0ho'))
3572
3573 self.assertRaises(ValueError, Element,
3574 _str('ha\0ho'))
3575
3577 Element = self.etree.Element
3578
3579 a = Element('a')
3580 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3581 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3582
3583 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3584 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3585
3586 self.assertRaises(ValueError, Element, 'ha\x07ho')
3587 self.assertRaises(ValueError, Element, 'ha\x02ho')
3588
3590 Element = self.etree.Element
3591
3592 a = Element('a')
3593 self.assertRaises(ValueError, setattr, a, "text",
3594 _str('ha\x07ho'))
3595 self.assertRaises(ValueError, setattr, a, "text",
3596 _str('ha\x02ho'))
3597
3598 self.assertRaises(ValueError, setattr, a, "tail",
3599 _str('ha\x07ho'))
3600 self.assertRaises(ValueError, setattr, a, "tail",
3601 _str('ha\x02ho'))
3602
3603 self.assertRaises(ValueError, Element,
3604 _str('ha\x07ho'))
3605 self.assertRaises(ValueError, Element,
3606 _str('ha\x02ho'))
3607
3609 Element = self.etree.Element
3610
3611 a = Element('a')
3612 self.assertRaises(ValueError, setattr, a, "text",
3613 _str('ha\u1234\x07ho'))
3614 self.assertRaises(ValueError, setattr, a, "text",
3615 _str('ha\u1234\x02ho'))
3616
3617 self.assertRaises(ValueError, setattr, a, "tail",
3618 _str('ha\u1234\x07ho'))
3619 self.assertRaises(ValueError, setattr, a, "tail",
3620 _str('ha\u1234\x02ho'))
3621
3622 self.assertRaises(ValueError, Element,
3623 _str('ha\u1234\x07ho'))
3624 self.assertRaises(ValueError, Element,
3625 _str('ha\u1234\x02ho'))
3626
3628 # ElementTree fails to serialize this
3629 tostring = self.etree.tostring
3630 Element = self.etree.Element
3631 SubElement = self.etree.SubElement
3632
3633 a = Element('a')
3634 b = SubElement(a, 'b')
3635 c = SubElement(a, 'c')
3636
3637 result = tostring(a, encoding='UTF-16')
3638 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3639 canonicalize(result))
3640
3642 # ElementTree raises an AssertionError here
3643 tostring = self.etree.tostring
3644 self.assertRaises(TypeError, self.etree.tostring, None)
3645
3647 tostring = self.etree.tostring
3648 Element = self.etree.Element
3649 SubElement = self.etree.SubElement
3650
3651 a = Element('a')
3652 b = SubElement(a, 'b')
3653 c = SubElement(a, 'c')
3654
3655 result = tostring(a)
3656 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3657
3658 result = tostring(a, pretty_print=False)
3659 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3660
3661 result = tostring(a, pretty_print=True)
3662 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3663
3665 tostring = self.etree.tostring
3666 Element = self.etree.Element
3667 SubElement = self.etree.SubElement
3668
3669 a = Element('a')
3670 a.tail = "aTAIL"
3671 b = SubElement(a, 'b')
3672 b.tail = "bTAIL"
3673 c = SubElement(a, 'c')
3674
3675 result = tostring(a)
3676 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3677
3678 result = tostring(a, with_tail=False)
3679 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>"))
3680
3681 result = tostring(a, with_tail=True)
3682 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3683
3685 tostring = self.etree.tostring
3686 html = self.etree.fromstring(
3687 '<html><body>'
3688 '<div><p>Some text<i>\r\n</i></p></div>\r\n'
3689 '</body></html>',
3690 parser=self.etree.HTMLParser())
3691 self.assertEqual(html.tag, 'html')
3692 div = html.find('.//div')
3693 self.assertEqual(div.tail, '\r\n')
3694 result = tostring(div, method='html')
3695 self.assertEqual(
3696 result,
3697 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3698 result = tostring(div, method='html', with_tail=True)
3699 self.assertEqual(
3700 result,
3701 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3702 result = tostring(div, method='html', with_tail=False)
3703 self.assertEqual(
3704 result,
3705 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3706
3708 tostring = self.etree.tostring
3709 XML = self.etree.XML
3710 ElementTree = self.etree.ElementTree
3711 Element = self.etree.Element
3712
3713 tree = Element("root").getroottree()
3714 self.assertEqual(None, tree.docinfo.standalone)
3715
3716 tree = XML(_bytes("<root/>")).getroottree()
3717 self.assertEqual(None, tree.docinfo.standalone)
3718
3719 tree = XML(_bytes(
3720 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
3721 )).getroottree()
3722 self.assertEqual(True, tree.docinfo.standalone)
3723
3724 tree = XML(_bytes(
3725 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
3726 )).getroottree()
3727 self.assertEqual(False, tree.docinfo.standalone)
3728
3730 tostring = self.etree.tostring
3731 XML = self.etree.XML
3732 ElementTree = self.etree.ElementTree
3733
3734 root = XML(_bytes("<root/>"))
3735
3736 tree = ElementTree(root)
3737 self.assertEqual(None, tree.docinfo.standalone)
3738
3739 result = tostring(root, xml_declaration=True, encoding="ASCII")
3740 self.assertEqual(result, _bytes(
3741 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3742
3743 result = tostring(root, xml_declaration=True, encoding="ASCII",
3744 standalone=True)
3745 self.assertEqual(result, _bytes(
3746 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3747
3748 tree = ElementTree(XML(result))
3749 self.assertEqual(True, tree.docinfo.standalone)
3750
3751 result = tostring(root, xml_declaration=True, encoding="ASCII",
3752 standalone=False)
3753 self.assertEqual(result, _bytes(
3754 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3755
3756 tree = ElementTree(XML(result))
3757 self.assertEqual(False, tree.docinfo.standalone)
3758
3760 tostring = self.etree.tostring
3761 XML = self.etree.XML
3762 ElementTree = self.etree.ElementTree
3763
3764 root = XML(_bytes(
3765 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
3766
3767 tree = ElementTree(root)
3768 self.assertEqual(True, tree.docinfo.standalone)
3769
3770 result = tostring(root, xml_declaration=True, encoding="ASCII")
3771 self.assertEqual(result, _bytes(
3772 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3773
3774 result = tostring(root, xml_declaration=True, encoding="ASCII",
3775 standalone=True)
3776 self.assertEqual(result, _bytes(
3777 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3778
3780 tostring = self.etree.tostring
3781 Element = self.etree.Element
3782 SubElement = self.etree.SubElement
3783
3784 a = Element('a')
3785 a.text = "A"
3786 a.tail = "tail"
3787 b = SubElement(a, 'b')
3788 b.text = "B"
3789 b.tail = _str("Søk på nettet")
3790 c = SubElement(a, 'c')
3791 c.text = "C"
3792
3793 result = tostring(a, method="text", encoding="UTF-16")
3794
3795 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3796 result)
3797
3799 tostring = self.etree.tostring
3800 Element = self.etree.Element
3801 SubElement = self.etree.SubElement
3802
3803 a = Element('a')
3804 a.text = _str('Søk på nettetA')
3805 a.tail = "tail"
3806 b = SubElement(a, 'b')
3807 b.text = "B"
3808 b.tail = _str('Søk på nettetB')
3809 c = SubElement(a, 'c')
3810 c.text = "C"
3811
3812 self.assertRaises(UnicodeEncodeError,
3813 tostring, a, method="text")
3814
3815 self.assertEqual(
3816 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3817 tostring(a, encoding="UTF-8", method="text"))
3818
3820 tounicode = self.etree.tounicode
3821 Element = self.etree.Element
3822 SubElement = self.etree.SubElement
3823
3824 a = Element('a')
3825 b = SubElement(a, 'b')
3826 c = SubElement(a, 'c')
3827
3828 self.assertTrue(isinstance(tounicode(a), _unicode))
3829 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3830 canonicalize(tounicode(a)))
3831
3833 tounicode = self.etree.tounicode
3834 Element = self.etree.Element
3835 SubElement = self.etree.SubElement
3836
3837 a = Element('a')
3838 b = SubElement(a, 'b')
3839 c = SubElement(a, 'c')
3840 d = SubElement(c, 'd')
3841 self.assertTrue(isinstance(tounicode(b), _unicode))
3842 self.assertTrue(isinstance(tounicode(c), _unicode))
3843 self.assertEqual(_bytes('<b></b>'),
3844 canonicalize(tounicode(b)))
3845 self.assertEqual(_bytes('<c><d></d></c>'),
3846 canonicalize(tounicode(c)))
3847
3851
3853 tounicode = self.etree.tounicode
3854 Element = self.etree.Element
3855 SubElement = self.etree.SubElement
3856
3857 a = Element('a')
3858 b = SubElement(a, 'b')
3859 c = SubElement(a, 'c')
3860 d = SubElement(c, 'd')
3861 b.tail = 'Foo'
3862
3863 self.assertTrue(isinstance(tounicode(b), _unicode))
3864 self.assertTrue(tounicode(b) == '<b/>Foo' or
3865 tounicode(b) == '<b />Foo')
3866
3868 tounicode = self.etree.tounicode
3869 Element = self.etree.Element
3870 SubElement = self.etree.SubElement
3871
3872 a = Element('a')
3873 b = SubElement(a, 'b')
3874 c = SubElement(a, 'c')
3875
3876 result = tounicode(a)
3877 self.assertEqual(result, "<a><b/><c/></a>")
3878
3879 result = tounicode(a, pretty_print=False)
3880 self.assertEqual(result, "<a><b/><c/></a>")
3881
3882 result = tounicode(a, pretty_print=True)
3883 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3884
3886 tostring = self.etree.tostring
3887 Element = self.etree.Element
3888 SubElement = self.etree.SubElement
3889
3890 a = Element('a')
3891 b = SubElement(a, 'b')
3892 c = SubElement(a, 'c')
3893
3894 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode))
3895 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3896 canonicalize(tostring(a, encoding=_unicode)))
3897
3899 tostring = self.etree.tostring
3900 Element = self.etree.Element
3901 SubElement = self.etree.SubElement
3902
3903 a = Element('a')
3904 b = SubElement(a, 'b')
3905 c = SubElement(a, 'c')
3906 d = SubElement(c, 'd')
3907 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3908 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3909 self.assertEqual(_bytes('<b></b>'),
3910 canonicalize(tostring(b, encoding=_unicode)))
3911 self.assertEqual(_bytes('<c><d></d></c>'),
3912 canonicalize(tostring(c, encoding=_unicode)))
3913
3915 tostring = self.etree.tostring
3916 self.assertRaises(TypeError, self.etree.tostring,
3917 None, encoding=_unicode)
3918
3920 tostring = self.etree.tostring
3921 Element = self.etree.Element
3922 SubElement = self.etree.SubElement
3923
3924 a = Element('a')
3925 b = SubElement(a, 'b')
3926 c = SubElement(a, 'c')
3927 d = SubElement(c, 'd')
3928 b.tail = 'Foo'
3929
3930 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3931 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or
3932 tostring(b, encoding=_unicode) == '<b />Foo')
3933
3935 tostring = self.etree.tostring
3936 Element = self.etree.Element
3937 SubElement = self.etree.SubElement
3938
3939 a = Element('a')
3940 b = SubElement(a, 'b')
3941 c = SubElement(a, 'c')
3942
3943 result = tostring(a, encoding=_unicode)
3944 self.assertEqual(result, "<a><b/><c/></a>")
3945
3946 result = tostring(a, encoding=_unicode, pretty_print=False)
3947 self.assertEqual(result, "<a><b/><c/></a>")
3948
3949 result = tostring(a, encoding=_unicode, pretty_print=True)
3950 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3951
3953 root = etree.Element('parent')
3954 etree.SubElement(root, 'child')
3955
3956 self.assertEqual(len(root), 1)
3957 self.assertEqual(root[0].tag, 'child')
3958
3959 # in PyPy, GC used to kill the Python proxy instance without cleanup
3960 gc.collect()
3961 self.assertEqual(len(root), 1)
3962 self.assertEqual(root[0].tag, 'child')
3963
3967
3968 el1 = SubEl()
3969 el2 = SubEl()
3970 self.assertEqual('SubEl', el1.tag)
3971 self.assertEqual('SubEl', el2.tag)
3972 el1.other = el2
3973 el2.other = el1
3974
3975 del el1, el2
3976 gc.collect()
3977 # not really testing anything here, but it shouldn't crash
3978
3980 root = etree.Element('parent')
3981 c1 = etree.SubElement(root, 'child1')
3982 c2 = etree.SubElement(root, 'child2')
3983
3984 root.remove(c1)
3985 root.remove(c2)
3986 c1.addnext(c2)
3987 del c1
3988 # trigger deallocation attempt of c1
3989 c2.getprevious()
3990 # make sure it wasn't deallocated
3991 self.assertEqual('child1', c2.getprevious().tag)
3992
3994 root = etree.Element('parent')
3995 c1 = etree.SubElement(root, 'child1')
3996 c2 = etree.SubElement(root, 'child2')
3997
3998 root.remove(c1)
3999 root.remove(c2)
4000 c1.addnext(c2)
4001 c1.tail = 'abc'
4002 c2.tail = 'xyz'
4003 del c1
4004 # trigger deallocation attempt of c1
4005 c2.getprevious()
4006 # make sure it wasn't deallocated
4007 self.assertEqual('child1', c2.getprevious().tag)
4008 self.assertEqual('abc', c2.getprevious().tail)
4009
4010 # helper methods
4011
4013 """Write out element for comparison.
4014 """
4015 ElementTree = self.etree.ElementTree
4016 f = BytesIO()
4017 tree = ElementTree(element=element)
4018 tree.write(f, encoding=encoding, compression=compression)
4019 data = f.getvalue()
4020 if compression:
4021 data = zlib.decompress(data)
4022 return canonicalize(data)
4023
4027 filename = fileInTestDir('test_broken.xml')
4028 root = etree.XML(_bytes('''\
4029 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
4030 <xi:include href="%s" parse="text"/>
4031 </doc>
4032 ''' % path2url(filename)))
4033 old_text = root.text
4034 content = read_file(filename)
4035 old_tail = root[0].tail
4036
4037 self.include( etree.ElementTree(root) )
4038 self.assertEqual(old_text + content + old_tail,
4039 root.text)
4040
4042 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
4043 self.assertNotEqual(
4044 'a',
4045 tree.getroot()[1].tag)
4046 # process xincludes
4047 self.include( tree )
4048 # check whether we find it replaced with included data
4049 self.assertEqual(
4050 'a',
4051 tree.getroot()[1].tag)
4052
4054 class res(etree.Resolver):
4055 include_text = read_file(fileInTestDir('test.xml'))
4056 called = {}
4057 def resolve(self, url, id, context):
4058 if url.endswith(".dtd"):
4059 self.called["dtd"] = True
4060 return self.resolve_filename(
4061 fileInTestDir('test.dtd'), context)
4062 elif url.endswith("test_xinclude.xml"):
4063 self.called["input"] = True
4064 return None # delegate to default resolver
4065 else:
4066 self.called["include"] = True
4067 return self.resolve_string(self.include_text, context)
4068
4069 res_instance = res()
4070 parser = etree.XMLParser(load_dtd = True)
4071 parser.resolvers.add(res_instance)
4072
4073 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
4074 parser = parser)
4075
4076 self.include(tree)
4077
4078 called = list(res_instance.called.items())
4079 called.sort()
4080 self.assertEqual(
4081 [("dtd", True), ("include", True), ("input", True)],
4082 called)
4083
4085 data = textwrap.dedent('''
4086 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
4087 <foo/>
4088 <xi:include href="./test.xml" />
4089 </doc>
4090 ''')
4091
4092 class Resolver(etree.Resolver):
4093 called = {}
4094
4095 def resolve(self, url, id, context):
4096 if url.endswith("test_xinclude.xml"):
4097 assert not self.called.get("input")
4098 self.called["input"] = True
4099 return None # delegate to default resolver
4100 elif url.endswith('/test5.xml'):
4101 assert not self.called.get("DONE")
4102 self.called["DONE"] = True
4103 return self.resolve_string('<DONE/>', context)
4104 else:
4105 _, filename = url.rsplit('/', 1)
4106 assert not self.called.get(filename)
4107 self.called[filename] = True
4108 next_data = data.replace(
4109 'test.xml', 'test%d.xml' % len(self.called))
4110 return self.resolve_string(next_data, context)
4111
4112 res_instance = Resolver()
4113 parser = etree.XMLParser(load_dtd=True)
4114 parser.resolvers.add(res_instance)
4115
4116 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
4117 parser=parser)
4118
4119 self.include(tree)
4120
4121 called = list(res_instance.called.items())
4122 called.sort()
4123 self.assertEqual(
4124 [("DONE", True), ("input", True), ("test.xml", True),
4125 ("test2.xml", True), ("test3.xml", True), ("test4.xml", True)],
4126 called)
4127
4132
4138
4142 tree = self.parse(_bytes('<a><b/></a>'))
4143 f = BytesIO()
4144 tree.write_c14n(f)
4145 s = f.getvalue()
4146 self.assertEqual(_bytes('<a><b></b></a>'),
4147 s)
4148
4150 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4151 f = BytesIO()
4152 tree.write_c14n(f, compression=9)
4153 with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile:
4154 s = gzfile.read()
4155 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
4156 s)
4157
4159 tree = self.parse(_bytes('<a><b/></a>'))
4160 with tmpfile() as filename:
4161 tree.write_c14n(filename)
4162 data = read_file(filename, 'rb')
4163 self.assertEqual(_bytes('<a><b></b></a>'),
4164 data)
4165
4167 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4168 with tmpfile() as filename:
4169 tree.write_c14n(filename, compression=9)
4170 with closing(gzip.open(filename, 'rb')) as f:
4171 data = f.read()
4172 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
4173 data)
4174
4176 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
4177 f = BytesIO()
4178 tree.write_c14n(f)
4179 s = f.getvalue()
4180 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
4181 s)
4182 f = BytesIO()
4183 tree.write_c14n(f, with_comments=True)
4184 s = f.getvalue()
4185 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
4186 s)
4187 f = BytesIO()
4188 tree.write_c14n(f, with_comments=False)
4189 s = f.getvalue()
4190 self.assertEqual(_bytes('<a><b></b></a>'),
4191 s)
4192
4194 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
4195 s = etree.tostring(tree, method='c14n')
4196 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
4197 s)
4198 s = etree.tostring(tree, method='c14n', with_comments=True)
4199 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
4200 s)
4201 s = etree.tostring(tree, method='c14n', with_comments=False)
4202 self.assertEqual(_bytes('<a><b></b></a>'),
4203 s)
4204
4206 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
4207 s = etree.tostring(tree.getroot(), method='c14n')
4208 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
4209 s)
4210 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
4211 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
4212 s)
4213 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
4214 self.assertEqual(_bytes('<a><b></b></a>'),
4215 s)
4216
4218 tree = self.parse(_bytes(
4219 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4220 f = BytesIO()
4221 tree.write_c14n(f)
4222 s = f.getvalue()
4223 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4224 s)
4225 f = BytesIO()
4226 tree.write_c14n(f, exclusive=False)
4227 s = f.getvalue()
4228 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4229 s)
4230 f = BytesIO()
4231 tree.write_c14n(f, exclusive=True)
4232 s = f.getvalue()
4233 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4234 s)
4235
4236 f = BytesIO()
4237 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
4238 s = f.getvalue()
4239 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
4240 s)
4241
4243 tree = self.parse(_bytes(
4244 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4245 s = etree.tostring(tree, method='c14n')
4246 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4247 s)
4248 s = etree.tostring(tree, method='c14n', exclusive=False)
4249 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4250 s)
4251 s = etree.tostring(tree, method='c14n', exclusive=True)
4252 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4253 s)
4254
4255 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
4256 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
4257 s)
4258
4260 tree = self.parse(_bytes(
4261 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4262 s = etree.tostring(tree.getroot(), method='c14n')
4263 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4264 s)
4265 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
4266 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4267 s)
4268 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
4269 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4270 s)
4271
4272 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
4273 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
4274 s)
4275 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
4276 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
4277 s)
4278
4279 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
4280 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
4281 s)
4282
4284 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
4285 tree = self.parse(_bytes(
4286 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4287
4288 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
4289 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4290 s)
4291
4295 tree = self.parse(_bytes('<a><b/></a>'))
4296 f = BytesIO()
4297 tree.write(f)
4298 s = f.getvalue()
4299 self.assertEqual(_bytes('<a><b/></a>'),
4300 s)
4301
4303 tree = self.parse(_bytes('<a><b/></a>'))
4304 f = BytesIO()
4305 tree.write(f, doctype='HUHU')
4306 s = f.getvalue()
4307 self.assertEqual(_bytes('HUHU\n<a><b/></a>'),
4308 s)
4309
4311 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4312 f = BytesIO()
4313 tree.write(f, compression=9)
4314 with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile:
4315 s = gzfile.read()
4316 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4317 s)
4318
4320 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4321 f = BytesIO()
4322 tree.write(f, compression=9, doctype='<!DOCTYPE a>')
4323 with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile:
4324 s = gzfile.read()
4325 self.assertEqual(_bytes('<!DOCTYPE a>\n<a>'+'<b/>'*200+'</a>'),
4326 s)
4327
4329 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4330 f = BytesIO()
4331 tree.write(f, compression=0)
4332 s0 = f.getvalue()
4333
4334 f = BytesIO()
4335 tree.write(f)
4336 self.assertEqual(f.getvalue(), s0)
4337
4338 f = BytesIO()
4339 tree.write(f, compression=1)
4340 s = f.getvalue()
4341 self.assertTrue(len(s) <= len(s0))
4342 with closing(gzip.GzipFile(fileobj=BytesIO(s))) as gzfile:
4343 s1 = gzfile.read()
4344
4345 f = BytesIO()
4346 tree.write(f, compression=9)
4347 s = f.getvalue()
4348 self.assertTrue(len(s) <= len(s0))
4349 with closing(gzip.GzipFile(fileobj=BytesIO(s))) as gzfile:
4350 s9 = gzfile.read()
4351
4352 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4353 s0)
4354 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4355 s1)
4356 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4357 s9)
4358
4360 tree = self.parse(_bytes('<a><b/></a>'))
4361 with tmpfile() as filename:
4362 tree.write(filename)
4363 data = read_file(filename, 'rb')
4364 self.assertEqual(_bytes('<a><b/></a>'),
4365 data)
4366
4368 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4369 with tmpfile() as filename:
4370 tree.write(filename, compression=9)
4371 with closing(gzip.open(filename, 'rb')) as f:
4372 data = f.read()
4373 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4374 data)
4375
4377 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4378 with tmpfile() as filename:
4379 tree.write(filename, compression=9)
4380 data = etree.tostring(etree.parse(filename))
4381 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4382 data)
4383
4392
4395 etree = etree
4396
4398 parse = self.etree.parse
4399 f = BytesIO('<a><b></c></b></a>')
4400 self.etree.clear_error_log()
4401 try:
4402 parse(f)
4403 logs = None
4404 except SyntaxError:
4405 e = sys.exc_info()[1]
4406 logs = e.error_log
4407 f.close()
4408 self.assertTrue([ log for log in logs
4409 if 'mismatch' in log.message ])
4410 self.assertTrue([ log for log in logs
4411 if 'PARSER' in log.domain_name])
4412 self.assertTrue([ log for log in logs
4413 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
4414 self.assertTrue([ log for log in logs
4415 if 1 == log.line ])
4416 self.assertTrue([ log for log in logs
4417 if 15 == log.column ])
4418
4429
4430 self.etree.use_global_python_log(Logger())
4431 f = BytesIO('<a><b></c></b></a>')
4432 try:
4433 parse(f)
4434 except SyntaxError:
4435 pass
4436 f.close()
4437
4438 self.assertTrue([ message for message in messages
4439 if 'mismatch' in message ])
4440 self.assertTrue([ message for message in messages
4441 if ':PARSER:' in message])
4442 self.assertTrue([ message for message in messages
4443 if ':ERR_TAG_NAME_MISMATCH:' in message ])
4444 self.assertTrue([ message for message in messages
4445 if ':1:15:' in message ])
4446
4461 def close(self):
4462 return 'close()'
4463
4464 parser = self.etree.XMLPullParser(target=Target())
4465 events = parser.read_events()
4466
4467 parser.feed('<root><element>')
4468 self.assertFalse(list(events))
4469 self.assertFalse(list(events))
4470 parser.feed('</element><child>')
4471 self.assertEqual([('end', 'end(element)')], list(events))
4472 parser.feed('</child>')
4473 self.assertEqual([('end', 'end(child)')], list(events))
4474 parser.feed('</root>')
4475 self.assertEqual([('end', 'end(root)')], list(events))
4476 self.assertFalse(list(events))
4477 self.assertEqual('close()', parser.close())
4478
4483 def end(self, tag):
4484 return 'end(%s)' % tag
4485 def close(self):
4486 return 'close()'
4487
4488 parser = self.etree.XMLPullParser(
4489 ['start', 'end'], target=Target())
4490 events = parser.read_events()
4491
4492 parser.feed('<root><element>')
4493 self.assertEqual(
4494 [('start', 'start(root)'), ('start', 'start(element)')],
4495 list(events))
4496 self.assertFalse(list(events))
4497 parser.feed('</element><child>')
4498 self.assertEqual(
4499 [('end', 'end(element)'), ('start', 'start(child)')],
4500 list(events))
4501 parser.feed('</child>')
4502 self.assertEqual(
4503 [('end', 'end(child)')],
4504 list(events))
4505 parser.feed('</root>')
4506 self.assertEqual(
4507 [('end', 'end(root)')],
4508 list(events))
4509 self.assertFalse(list(events))
4510 self.assertEqual('close()', parser.close())
4511
4513 parser = self.etree.XMLPullParser(
4514 ['start', 'end'], target=etree.TreeBuilder())
4515 events = parser.read_events()
4516
4517 parser.feed('<root><element>')
4518 self.assert_event_tags(
4519 events, [('start', 'root'), ('start', 'element')])
4520 self.assertFalse(list(events))
4521 parser.feed('</element><child>')
4522 self.assert_event_tags(
4523 events, [('end', 'element'), ('start', 'child')])
4524 parser.feed('</child>')
4525 self.assert_event_tags(
4526 events, [('end', 'child')])
4527 parser.feed('</root>')
4528 self.assert_event_tags(
4529 events, [('end', 'root')])
4530 self.assertFalse(list(events))
4531 root = parser.close()
4532 self.assertEqual('root', root.tag)
4533
4535 class Target(etree.TreeBuilder):
4536 def end(self, tag):
4537 el = super(Target, self).end(tag)
4538 el.tag += '-huhu'
4539 return el
4540
4541 parser = self.etree.XMLPullParser(
4542 ['start', 'end'], target=Target())
4543 events = parser.read_events()
4544
4545 parser.feed('<root><element>')
4546 self.assert_event_tags(
4547 events, [('start', 'root'), ('start', 'element')])
4548 self.assertFalse(list(events))
4549 parser.feed('</element><child>')
4550 self.assert_event_tags(
4551 events, [('end', 'element-huhu'), ('start', 'child')])
4552 parser.feed('</child>')
4553 self.assert_event_tags(
4554 events, [('end', 'child-huhu')])
4555 parser.feed('</root>')
4556 self.assert_event_tags(
4557 events, [('end', 'root-huhu')])
4558 self.assertFalse(list(events))
4559 root = parser.close()
4560 self.assertEqual('root-huhu', root.tag)
4561
4564 suite = unittest.TestSuite()
4565 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
4566 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
4567 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
4568 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
4569 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
4570 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
4571 suite.addTests([unittest.makeSuite(XMLPullParserTest)])
4572
4573 # add original doctests from ElementTree selftest modules
4574 from . import selftest, selftest2
4575 suite.addTests(doctest.DocTestSuite(selftest))
4576 suite.addTests(doctest.DocTestSuite(selftest2))
4577
4578 # add doctests
4579 suite.addTests(doctest.DocTestSuite(etree))
4580 suite.addTests(
4581 [make_doctest('../../../doc/tutorial.txt')])
4582 if sys.version_info >= (2,6):
4583 # now requires the 'with' statement
4584 suite.addTests(
4585 [make_doctest('../../../doc/api.txt')])
4586 suite.addTests(
4587 [make_doctest('../../../doc/FAQ.txt')])
4588 suite.addTests(
4589 [make_doctest('../../../doc/parsing.txt')])
4590 suite.addTests(
4591 [make_doctest('../../../doc/resolvers.txt')])
4592 return suite
4593
4594
4595 if __name__ == '__main__':
4596 print('to test use test.py %s' % __file__)
4597
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Mar 13 20:17:56 2018 | http://epydoc.sourceforge.net |