| 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
1200
1210
1224
1226 iterwalk = self.etree.iterwalk
1227 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1228
1229 iterator = iterwalk(root)
1230 for event, elem in iterator:
1231 elem.clear()
1232
1233 self.assertEqual(0,
1234 len(root))
1235
1237 iterwalk = self.etree.iterwalk
1238 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1239
1240 attr_name = '{testns}bla'
1241 events = []
1242 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1243 for event, elem in iterator:
1244 events.append(event)
1245 if event == 'start':
1246 if elem.tag != '{ns1}a':
1247 elem.set(attr_name, 'value')
1248
1249 self.assertEqual(
1250 ['start-ns', 'start', 'start', 'start-ns', 'start',
1251 'end', 'end-ns', 'end', 'end', 'end-ns'],
1252 events)
1253
1254 self.assertEqual(
1255 None,
1256 root.get(attr_name))
1257 self.assertEqual(
1258 'value',
1259 root[0].get(attr_name))
1260
1262 iterwalk = self.etree.iterwalk
1263 root = self.etree.XML(_bytes('<a><b><c/></b><d><e/></d></a>'))
1264
1265 iterator = iterwalk(root)
1266 tags = []
1267 for event, elem in iterator:
1268 tags.append(elem.tag)
1269 # requesting a skip after an 'end' event should never have an effect
1270 iterator.skip_subtree()
1271
1272 self.assertEqual(['c', 'b', 'e', 'd', 'a'], tags)
1273
1275 iterwalk = self.etree.iterwalk
1276 root = self.etree.XML(_bytes('<a><b><c/></b><d><e/></d></a>'))
1277
1278 iterator = iterwalk(root, events=('start', 'end'))
1279 tags = []
1280 for event, elem in iterator:
1281 tags.append((event, elem.tag))
1282 if elem.tag in ('b', 'e'):
1283 # skipping should only have an effect on 'start', not on 'end'
1284 iterator.skip_subtree()
1285
1286 self.assertEqual(
1287 [('start', 'a'),
1288 ('start', 'b'), ('end', 'b'), # ignored child 'c'
1289 ('start', 'd'),
1290 ('start', 'e'), ('end', 'e'),
1291 ('end', 'd'),
1292 ('end', 'a')],
1293 tags)
1294
1296 iterwalk = self.etree.iterwalk
1297 root = self.etree.XML(_bytes(
1298 '<a xmlns="ns1"><b xmlns="nsb"><c xmlns="ns2"/></b><d xmlns="ns2"><e/></d></a>'))
1299
1300 events = []
1301 iterator = iterwalk(root, events=('start','start-ns','end-ns'))
1302 for event, elem in iterator:
1303 if event in ('start-ns', 'end-ns'):
1304 events.append((event, elem))
1305 if event == 'start-ns' and elem == ('', 'nsb'):
1306 events.append('skip')
1307 iterator.skip_subtree()
1308 else:
1309 events.append((event, elem.tag))
1310
1311 self.assertEqual(
1312 [('start-ns', ('', 'ns1')),
1313 ('start', '{ns1}a'),
1314 ('start-ns', ('', 'nsb')),
1315 'skip',
1316 ('start', '{nsb}b'),
1317 ('end-ns', None),
1318 ('start-ns', ('', 'ns2')),
1319 ('start', '{ns2}d'),
1320 ('start', '{ns2}e'),
1321 ('end-ns', None),
1322 ('end-ns', None)
1323 ],
1324 events)
1325
1327 iterwalk = self.etree.iterwalk
1328 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
1329
1330 counts = []
1331 for event, elem in iterwalk(root):
1332 counts.append(len(list(elem.getiterator())))
1333 self.assertEqual(
1334 [1,2,1,4],
1335 counts)
1336
1338 parse = self.etree.parse
1339 parser = self.etree.XMLParser(dtd_validation=True)
1340 assertEqual = self.assertEqual
1341 test_url = _str("__nosuch.dtd")
1342
1343 class MyResolver(self.etree.Resolver):
1344 def resolve(self, url, id, context):
1345 assertEqual(url, test_url)
1346 return self.resolve_string(
1347 _str('''<!ENTITY myentity "%s">
1348 <!ELEMENT doc ANY>''') % url, context)
1349
1350 parser.resolvers.add(MyResolver())
1351
1352 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1353 tree = parse(StringIO(xml), parser)
1354 root = tree.getroot()
1355 self.assertEqual(root.text, test_url)
1356
1358 parse = self.etree.parse
1359 parser = self.etree.XMLParser(dtd_validation=True)
1360 assertEqual = self.assertEqual
1361 test_url = _str("__nosuch.dtd")
1362
1363 class MyResolver(self.etree.Resolver):
1364 def resolve(self, url, id, context):
1365 assertEqual(url, test_url)
1366 return self.resolve_string(
1367 (_str('''<!ENTITY myentity "%s">
1368 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1369 context)
1370
1371 parser.resolvers.add(MyResolver())
1372
1373 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1374 tree = parse(StringIO(xml), parser)
1375 root = tree.getroot()
1376 self.assertEqual(root.text, test_url)
1377
1379 parse = self.etree.parse
1380 parser = self.etree.XMLParser(dtd_validation=True)
1381 assertEqual = self.assertEqual
1382 test_url = _str("__nosuch.dtd")
1383
1384 class MyResolver(self.etree.Resolver):
1385 def resolve(self, url, id, context):
1386 assertEqual(url, test_url)
1387 return self.resolve_file(
1388 SillyFileLike(
1389 _str('''<!ENTITY myentity "%s">
1390 <!ELEMENT doc ANY>''') % url), context)
1391
1392 parser.resolvers.add(MyResolver())
1393
1394 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1395 tree = parse(StringIO(xml), parser)
1396 root = tree.getroot()
1397 self.assertEqual(root.text, test_url)
1398
1400 parse = self.etree.parse
1401 parser = self.etree.XMLParser(attribute_defaults=True)
1402 assertEqual = self.assertEqual
1403 test_url = _str("__nosuch.dtd")
1404
1405 class MyResolver(self.etree.Resolver):
1406 def resolve(self, url, id, context):
1407 assertEqual(url, test_url)
1408 return self.resolve_filename(
1409 fileInTestDir('test.dtd'), context)
1410
1411 parser.resolvers.add(MyResolver())
1412
1413 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1414 tree = parse(StringIO(xml), parser)
1415 root = tree.getroot()
1416 self.assertEqual(
1417 root.attrib, {'default': 'valueA'})
1418 self.assertEqual(
1419 root[0].attrib, {'default': 'valueB'})
1420
1422 parse = self.etree.parse
1423 parser = self.etree.XMLParser(attribute_defaults=True)
1424 assertEqual = self.assertEqual
1425 test_url = _str("__nosuch.dtd")
1426
1427 class MyResolver(self.etree.Resolver):
1428 def resolve(self, url, id, context):
1429 expected = fileUrlInTestDir(test_url)
1430 url = url.replace('file://', 'file:') # depends on libxml2 version
1431 expected = expected.replace('file://', 'file:')
1432 assertEqual(url, expected)
1433 return self.resolve_filename(
1434 fileUrlInTestDir('test.dtd'), context)
1435
1436 parser.resolvers.add(MyResolver())
1437
1438 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1439 tree = parse(StringIO(xml), parser,
1440 base_url=fileUrlInTestDir('__test.xml'))
1441 root = tree.getroot()
1442 self.assertEqual(
1443 root.attrib, {'default': 'valueA'})
1444 self.assertEqual(
1445 root[0].attrib, {'default': 'valueB'})
1446
1448 parse = self.etree.parse
1449 parser = self.etree.XMLParser(attribute_defaults=True)
1450 assertEqual = self.assertEqual
1451 test_url = _str("__nosuch.dtd")
1452
1453 class MyResolver(self.etree.Resolver):
1454 def resolve(self, url, id, context):
1455 assertEqual(url, test_url)
1456 return self.resolve_file(
1457 open(fileInTestDir('test.dtd'), 'rb'), context)
1458
1459 parser.resolvers.add(MyResolver())
1460
1461 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1462 tree = parse(StringIO(xml), parser)
1463 root = tree.getroot()
1464 self.assertEqual(
1465 root.attrib, {'default': 'valueA'})
1466 self.assertEqual(
1467 root[0].attrib, {'default': 'valueB'})
1468
1470 parse = self.etree.parse
1471 parser = self.etree.XMLParser(load_dtd=True)
1472 assertEqual = self.assertEqual
1473 test_url = _str("__nosuch.dtd")
1474
1475 class check(object):
1476 resolved = False
1477
1478 class MyResolver(self.etree.Resolver):
1479 def resolve(self, url, id, context):
1480 assertEqual(url, test_url)
1481 check.resolved = True
1482 return self.resolve_empty(context)
1483
1484 parser.resolvers.add(MyResolver())
1485
1486 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1487 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1488 self.assertTrue(check.resolved)
1489
1491 parse = self.etree.parse
1492 parser = self.etree.XMLParser(dtd_validation=True)
1493
1494 class _LocalException(Exception):
1495 pass
1496
1497 class MyResolver(self.etree.Resolver):
1498 def resolve(self, url, id, context):
1499 raise _LocalException
1500
1501 parser.resolvers.add(MyResolver())
1502
1503 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1504 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1505
1506 if etree.LIBXML_VERSION > (2,6,20):
1508 parse = self.etree.parse
1509 tostring = self.etree.tostring
1510 parser = self.etree.XMLParser(resolve_entities=False)
1511 Entity = self.etree.Entity
1512
1513 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>')
1514 tree = parse(BytesIO(xml), parser)
1515 root = tree.getroot()
1516 self.assertEqual(root[0].tag, Entity)
1517 self.assertEqual(root[0].text, "&myentity;")
1518 self.assertEqual(root[0].tail, None)
1519 self.assertEqual(root[0].name, "myentity")
1520
1521 self.assertEqual(_bytes('<doc>&myentity;</doc>'),
1522 tostring(root))
1523
1525 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1526 <root>
1527 <child1/>
1528 <child2/>
1529 <child3> </child3>
1530 </root>''')
1531
1532 parser = self.etree.XMLParser(resolve_entities=False)
1533 root = etree.fromstring(xml, parser)
1534 self.assertEqual([ el.tag for el in root ],
1535 ['child1', 'child2', 'child3'])
1536
1537 root[0] = root[-1]
1538 self.assertEqual([ el.tag for el in root ],
1539 ['child3', 'child2'])
1540 self.assertEqual(root[0][0].text, ' ')
1541 self.assertEqual(root[0][0].name, 'nbsp')
1542
1544 Entity = self.etree.Entity
1545 Element = self.etree.Element
1546 tostring = self.etree.tostring
1547
1548 root = Element("root")
1549 root.append( Entity("test") )
1550
1551 self.assertEqual(root[0].tag, Entity)
1552 self.assertEqual(root[0].text, "&test;")
1553 self.assertEqual(root[0].tail, None)
1554 self.assertEqual(root[0].name, "test")
1555
1556 self.assertEqual(_bytes('<root>&test;</root>'),
1557 tostring(root))
1558
1560 Entity = self.etree.Entity
1561 self.assertEqual(Entity("test").text, '&test;')
1562 self.assertEqual(Entity("#17683").text, '䔓')
1563 self.assertEqual(Entity("#x1768").text, 'ᝨ')
1564 self.assertEqual(Entity("#x98AF").text, '颯')
1565
1567 Entity = self.etree.Entity
1568 self.assertRaises(ValueError, Entity, 'a b c')
1569 self.assertRaises(ValueError, Entity, 'a,b')
1570 self.assertRaises(ValueError, Entity, 'a\0b')
1571 self.assertRaises(ValueError, Entity, '#abc')
1572 self.assertRaises(ValueError, Entity, '#xxyz')
1573
1575 CDATA = self.etree.CDATA
1576 Element = self.etree.Element
1577 tostring = self.etree.tostring
1578
1579 root = Element("root")
1580 root.text = CDATA('test')
1581
1582 self.assertEqual('test',
1583 root.text)
1584 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1585 tostring(root))
1586
1588 CDATA = self.etree.CDATA
1589 Element = self.etree.Element
1590 SubElement = self.etree.SubElement
1591 tostring = self.etree.tostring
1592
1593 root = Element("root")
1594 child = SubElement(root, 'child')
1595 child.tail = CDATA('test')
1596
1597 self.assertEqual('test', child.tail)
1598 self.assertEqual(_bytes('<root><child/><![CDATA[test]]></root>'),
1599 tostring(root))
1600
1601 root = Element("root")
1602 root.tail = CDATA('test')
1603
1604 self.assertEqual('test', root.tail)
1605 self.assertEqual(_bytes('<root/><![CDATA[test]]>'),
1606 tostring(root))
1607
1609 CDATA = self.etree.CDATA
1610 Element = self.etree.Element
1611 root = Element("root")
1612
1613 root.text = CDATA("test")
1614 self.assertEqual('test', root.text)
1615
1616 root.text = CDATA(_str("test"))
1617 self.assertEqual('test', root.text)
1618
1619 self.assertRaises(TypeError, CDATA, 1)
1620
1622 CDATA = self.etree.CDATA
1623 Element = self.etree.Element
1624
1625 root = Element("root")
1626 cdata = CDATA('test')
1627
1628 self.assertRaises(TypeError,
1629 root.set, 'attr', cdata)
1630 self.assertRaises(TypeError,
1631 operator.setitem, root.attrib, 'attr', cdata)
1632
1634 tostring = self.etree.tostring
1635 parser = self.etree.XMLParser(strip_cdata=False)
1636 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1637
1638 self.assertEqual('test', root.text)
1639 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1640 tostring(root))
1641
1643 tostring = self.etree.tostring
1644 parser = self.etree.XMLParser(strip_cdata=False)
1645 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1646 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1647 tostring(root))
1648
1649 self.assertEqual(['test'], root.xpath('//text()'))
1650
1651 # TypeError in etree, AssertionError in ElementTree;
1653 Element = self.etree.Element
1654 SubElement = self.etree.SubElement
1655
1656 a = Element('a')
1657 b = SubElement(a, 'b')
1658
1659 self.assertRaises(TypeError,
1660 a.__setitem__, 0, 'foo')
1661
1663 Element = self.etree.Element
1664 root = Element('root')
1665 # raises AssertionError in ElementTree
1666 self.assertRaises(TypeError, root.append, None)
1667 self.assertRaises(TypeError, root.extend, [None])
1668 self.assertRaises(TypeError, root.extend, [Element('one'), None])
1669 self.assertEqual('one', root[0].tag)
1670
1672 Element = self.etree.Element
1673 SubElement = self.etree.SubElement
1674 root = Element('root')
1675 self.assertRaises(ValueError, root.append, root)
1676 child = SubElement(root, 'child')
1677 self.assertRaises(ValueError, child.append, root)
1678 child2 = SubElement(child, 'child2')
1679 self.assertRaises(ValueError, child2.append, root)
1680 self.assertRaises(ValueError, child2.append, child)
1681 self.assertEqual('child2', root[0][0].tag)
1682
1684 Element = self.etree.Element
1685 SubElement = self.etree.SubElement
1686 root = Element('root')
1687 SubElement(root, 'a')
1688 SubElement(root, 'b')
1689
1690 self.assertEqual(['a', 'b'],
1691 [c.tag for c in root])
1692 root[1].addnext(root[0])
1693 self.assertEqual(['b', 'a'],
1694 [c.tag for c in root])
1695
1697 Element = self.etree.Element
1698 SubElement = self.etree.SubElement
1699 root = Element('root')
1700 SubElement(root, 'a')
1701 SubElement(root, 'b')
1702
1703 self.assertEqual(['a', 'b'],
1704 [c.tag for c in root])
1705 root[0].addprevious(root[1])
1706 self.assertEqual(['b', 'a'],
1707 [c.tag for c in root])
1708
1710 Element = self.etree.Element
1711 SubElement = self.etree.SubElement
1712 root = Element('root')
1713 a = SubElement(root, 'a')
1714 b = SubElement(a, 'b')
1715 # appending parent as sibling is forbidden
1716 self.assertRaises(ValueError, b.addnext, a)
1717 self.assertEqual(['a'], [c.tag for c in root])
1718 self.assertEqual(['b'], [c.tag for c in a])
1719
1721 Element = self.etree.Element
1722 SubElement = self.etree.SubElement
1723 root = Element('root')
1724 a = SubElement(root, 'a')
1725 b = SubElement(a, 'b')
1726 # appending parent as sibling is forbidden
1727 self.assertRaises(ValueError, b.addprevious, a)
1728 self.assertEqual(['a'], [c.tag for c in root])
1729 self.assertEqual(['b'], [c.tag for c in a])
1730
1732 Element = self.etree.Element
1733 SubElement = self.etree.SubElement
1734 root = Element('root')
1735 a = SubElement(root, 'a')
1736 b = SubElement(a, 'b')
1737 c = SubElement(b, 'c')
1738 # appending parent as sibling is forbidden
1739 self.assertRaises(ValueError, c.addnext, a)
1740
1742 Element = self.etree.Element
1743 SubElement = self.etree.SubElement
1744 root = Element('root')
1745 a = SubElement(root, 'a')
1746 b = SubElement(a, 'b')
1747 c = SubElement(b, 'c')
1748 # appending parent as sibling is forbidden
1749 self.assertRaises(ValueError, c.addprevious, a)
1750
1752 Element = self.etree.Element
1753 SubElement = self.etree.SubElement
1754 root = Element('root')
1755 a = SubElement(root, 'a')
1756 b = SubElement(root, 'b')
1757 a.addprevious(a)
1758 self.assertEqual('a', root[0].tag)
1759 self.assertEqual('b', root[1].tag)
1760 b.addprevious(b)
1761 self.assertEqual('a', root[0].tag)
1762 self.assertEqual('b', root[1].tag)
1763 b.addprevious(a)
1764 self.assertEqual('a', root[0].tag)
1765 self.assertEqual('b', root[1].tag)
1766
1768 Element = self.etree.Element
1769 SubElement = self.etree.SubElement
1770 root = Element('root')
1771 a = SubElement(root, 'a')
1772 b = SubElement(root, 'b')
1773 a.addnext(a)
1774 self.assertEqual('a', root[0].tag)
1775 self.assertEqual('b', root[1].tag)
1776 b.addnext(b)
1777 self.assertEqual('a', root[0].tag)
1778 self.assertEqual('b', root[1].tag)
1779 a.addnext(b)
1780 self.assertEqual('a', root[0].tag)
1781 self.assertEqual('b', root[1].tag)
1782
1784 Element = self.etree.Element
1785 a = Element('a')
1786 b = Element('b')
1787 self.assertRaises(TypeError, a.addnext, b)
1788
1790 Element = self.etree.Element
1791 SubElement = self.etree.SubElement
1792 PI = self.etree.PI
1793 root = Element('root')
1794 SubElement(root, 'a')
1795 pi = PI('TARGET', 'TEXT')
1796 pi.tail = "TAIL"
1797
1798 self.assertEqual(_bytes('<root><a></a></root>'),
1799 self._writeElement(root))
1800 root[0].addprevious(pi)
1801 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
1802 self._writeElement(root))
1803
1805 Element = self.etree.Element
1806 PI = self.etree.PI
1807 root = Element('root')
1808 pi = PI('TARGET', 'TEXT')
1809 pi.tail = "TAIL"
1810
1811 self.assertEqual(_bytes('<root></root>'),
1812 self._writeElement(root))
1813 root.addprevious(pi)
1814 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'),
1815 self._writeElement(root))
1816
1818 Element = self.etree.Element
1819 SubElement = self.etree.SubElement
1820 PI = self.etree.PI
1821 root = Element('root')
1822 SubElement(root, 'a')
1823 pi = PI('TARGET', 'TEXT')
1824 pi.tail = "TAIL"
1825
1826 self.assertEqual(_bytes('<root><a></a></root>'),
1827 self._writeElement(root))
1828 root[0].addnext(pi)
1829 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
1830 self._writeElement(root))
1831
1833 Element = self.etree.Element
1834 PI = self.etree.PI
1835 root = Element('root')
1836 pi = PI('TARGET', 'TEXT')
1837 pi.tail = "TAIL"
1838
1839 self.assertEqual(_bytes('<root></root>'),
1840 self._writeElement(root))
1841 root.addnext(pi)
1842 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'),
1843 self._writeElement(root))
1844
1846 Element = self.etree.Element
1847 SubElement = self.etree.SubElement
1848 Comment = self.etree.Comment
1849 root = Element('root')
1850 SubElement(root, 'a')
1851 comment = Comment('TEXT ')
1852 comment.tail = "TAIL"
1853
1854 self.assertEqual(_bytes('<root><a></a></root>'),
1855 self._writeElement(root))
1856 root[0].addnext(comment)
1857 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
1858 self._writeElement(root))
1859
1861 Element = self.etree.Element
1862 Comment = self.etree.Comment
1863 root = Element('root')
1864 comment = Comment('TEXT ')
1865 comment.tail = "TAIL"
1866
1867 self.assertEqual(_bytes('<root></root>'),
1868 self._writeElement(root))
1869 root.addnext(comment)
1870 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'),
1871 self._writeElement(root))
1872
1874 Element = self.etree.Element
1875 SubElement = self.etree.SubElement
1876 Comment = self.etree.Comment
1877 root = Element('root')
1878 SubElement(root, 'a')
1879 comment = Comment('TEXT ')
1880 comment.tail = "TAIL"
1881
1882 self.assertEqual(_bytes('<root><a></a></root>'),
1883 self._writeElement(root))
1884 root[0].addprevious(comment)
1885 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
1886 self._writeElement(root))
1887
1889 Element = self.etree.Element
1890 Comment = self.etree.Comment
1891 root = Element('root')
1892 comment = Comment('TEXT ')
1893 comment.tail = "TAIL"
1894
1895 self.assertEqual(_bytes('<root></root>'),
1896 self._writeElement(root))
1897 root.addprevious(comment)
1898 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'),
1899 self._writeElement(root))
1900
1901 # ET's Elements have items() and key(), but not values()
1903 XML = self.etree.XML
1904
1905 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
1906 values = root.values()
1907 values.sort()
1908 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1909
1910 # gives error in ElementTree
1912 Element = self.etree.Element
1913 Comment = self.etree.Comment
1914
1915 a = Element('a')
1916 a.append(Comment())
1917 self.assertEqual(
1918 _bytes('<a><!----></a>'),
1919 self._writeElement(a))
1920
1921 # ElementTree ignores comments
1923 ElementTree = self.etree.ElementTree
1924 tostring = self.etree.tostring
1925
1926 xml = _bytes('<a><b/><!----><c/></a>')
1927 f = BytesIO(xml)
1928 doc = ElementTree(file=f)
1929 a = doc.getroot()
1930 self.assertEqual(
1931 '',
1932 a[1].text)
1933 self.assertEqual(
1934 xml,
1935 tostring(a))
1936
1937 # ElementTree ignores comments
1939 ElementTree = self.etree.ElementTree
1940
1941 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
1942 doc = ElementTree(file=f)
1943 a = doc.getroot()
1944 self.assertEqual(
1945 ' hoi ',
1946 a[1].text)
1947
1948 # does not raise an exception in ElementTree
1950 Element = self.etree.Element
1951 Comment = self.etree.Comment
1952
1953 c = Comment()
1954 el = Element('myel')
1955
1956 self.assertRaises(TypeError, c.append, el)
1957 self.assertRaises(TypeError, c.insert, 0, el)
1958 self.assertRaises(TypeError, c.set, "myattr", "test")
1959
1961 c = self.etree.Comment()
1962 self.assertEqual(0, len(c.attrib))
1963
1964 self.assertFalse(c.attrib.__contains__('nope'))
1965 self.assertFalse('nope' in c.attrib)
1966 self.assertFalse('nope' in c.attrib.keys())
1967 self.assertFalse('nope' in c.attrib.values())
1968 self.assertFalse(('nope', 'huhu') in c.attrib.items())
1969
1970 self.assertEqual([], list(c.attrib))
1971 self.assertEqual([], list(c.attrib.keys()))
1972 self.assertEqual([], list(c.attrib.items()))
1973 self.assertEqual([], list(c.attrib.values()))
1974 self.assertEqual([], list(c.attrib.iterkeys()))
1975 self.assertEqual([], list(c.attrib.iteritems()))
1976 self.assertEqual([], list(c.attrib.itervalues()))
1977
1978 self.assertEqual('HUHU', c.attrib.pop('nope', 'HUHU'))
1979 self.assertRaises(KeyError, c.attrib.pop, 'nope')
1980
1981 self.assertRaises(KeyError, c.attrib.__getitem__, 'only')
1982 self.assertRaises(KeyError, c.attrib.__getitem__, 'names')
1983 self.assertRaises(KeyError, c.attrib.__getitem__, 'nope')
1984 self.assertRaises(KeyError, c.attrib.__setitem__, 'nope', 'yep')
1985 self.assertRaises(KeyError, c.attrib.__delitem__, 'nope')
1986
1987 # test passing 'None' to dump()
1990
1992 ElementTree = self.etree.ElementTree
1993
1994 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
1995 doc = ElementTree(file=f)
1996 a = doc.getroot()
1997 self.assertEqual(
1998 None,
1999 a.prefix)
2000 self.assertEqual(
2001 'foo',
2002 a[0].prefix)
2003
2005 ElementTree = self.etree.ElementTree
2006
2007 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
2008 doc = ElementTree(file=f)
2009 a = doc.getroot()
2010 self.assertEqual(
2011 None,
2012 a.prefix)
2013 self.assertEqual(
2014 None,
2015 a[0].prefix)
2016
2018 Element = self.etree.Element
2019 SubElement = self.etree.SubElement
2020
2021 a = Element('a')
2022 b = SubElement(a, 'b')
2023 c = SubElement(a, 'c')
2024 d = SubElement(b, 'd')
2025 self.assertEqual(
2026 None,
2027 a.getparent())
2028 self.assertEqual(
2029 a,
2030 b.getparent())
2031 self.assertEqual(
2032 b.getparent(),
2033 c.getparent())
2034 self.assertEqual(
2035 b,
2036 d.getparent())
2037
2039 XML = self.etree.XML
2040
2041 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
2042 result = []
2043 for el in root.iterchildren():
2044 result.append(el.tag)
2045 self.assertEqual(['one', 'two', 'three'], result)
2046
2048 XML = self.etree.XML
2049
2050 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
2051 result = []
2052 for el in root.iterchildren(reversed=True):
2053 result.append(el.tag)
2054 self.assertEqual(['three', 'two', 'one'], result)
2055
2057 XML = self.etree.XML
2058
2059 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
2060 result = []
2061 for el in root.iterchildren(tag='two'):
2062 result.append(el.text)
2063 self.assertEqual(['Two', 'Bla'], result)
2064
2066 XML = self.etree.XML
2067
2068 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
2069 result = []
2070 for el in root.iterchildren('two'):
2071 result.append(el.text)
2072 self.assertEqual(['Two', 'Bla'], result)
2073
2075 XML = self.etree.XML
2076
2077 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
2078 result = []
2079 for el in root.iterchildren(reversed=True, tag='two'):
2080 result.append(el.text)
2081 self.assertEqual(['Bla', 'Two'], result)
2082
2084 XML = self.etree.XML
2085
2086 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
2087 result = []
2088 for el in root.iterchildren(tag=['two', 'three']):
2089 result.append(el.text)
2090 self.assertEqual(['Two', 'Bla', None], result)
2091
2093 XML = self.etree.XML
2094
2095 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
2096 result = []
2097 for el in root.iterchildren('two', 'three'):
2098 result.append(el.text)
2099 self.assertEqual(['Two', 'Bla', None], result)
2100
2102 XML = self.etree.XML
2103
2104 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
2105 result = []
2106 for el in root.iterchildren(reversed=True, tag=['two', 'three']):
2107 result.append(el.text)
2108 self.assertEqual([None, 'Bla', 'Two'], result)
2109
2111 Element = self.etree.Element
2112 SubElement = self.etree.SubElement
2113
2114 a = Element('a')
2115 b = SubElement(a, 'b')
2116 c = SubElement(a, 'c')
2117 d = SubElement(b, 'd')
2118 self.assertEqual(
2119 [],
2120 list(a.iterancestors()))
2121 self.assertEqual(
2122 [a],
2123 list(b.iterancestors()))
2124 self.assertEqual(
2125 [a],
2126 list(c.iterancestors()))
2127 self.assertEqual(
2128 [b, a],
2129 list(d.iterancestors()))
2130
2132 Element = self.etree.Element
2133 SubElement = self.etree.SubElement
2134
2135 a = Element('a')
2136 b = SubElement(a, 'b')
2137 c = SubElement(a, 'c')
2138 d = SubElement(b, 'd')
2139 self.assertEqual(
2140 [a],
2141 list(d.iterancestors('a')))
2142 self.assertEqual(
2143 [a],
2144 list(d.iterancestors(tag='a')))
2145
2146 self.assertEqual(
2147 [b, a],
2148 list(d.iterancestors('*')))
2149 self.assertEqual(
2150 [b, a],
2151 list(d.iterancestors(tag='*')))
2152
2154 Element = self.etree.Element
2155 SubElement = self.etree.SubElement
2156
2157 a = Element('a')
2158 b = SubElement(a, 'b')
2159 c = SubElement(a, 'c')
2160 d = SubElement(b, 'd')
2161 self.assertEqual(
2162 [b, a],
2163 list(d.iterancestors(tag=('a', 'b'))))
2164 self.assertEqual(
2165 [b, a],
2166 list(d.iterancestors('a', 'b')))
2167
2168 self.assertEqual(
2169 [],
2170 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
2171 self.assertEqual(
2172 [],
2173 list(d.iterancestors('w', 'x', 'y', 'z')))
2174
2175 self.assertEqual(
2176 [],
2177 list(d.iterancestors(tag=('d', 'x'))))
2178 self.assertEqual(
2179 [],
2180 list(d.iterancestors('d', 'x')))
2181
2182 self.assertEqual(
2183 [b, a],
2184 list(d.iterancestors(tag=('b', '*'))))
2185 self.assertEqual(
2186 [b, a],
2187 list(d.iterancestors('b', '*')))
2188
2189 self.assertEqual(
2190 [b],
2191 list(d.iterancestors(tag=('b', 'c'))))
2192 self.assertEqual(
2193 [b],
2194 list(d.iterancestors('b', 'c')))
2195
2197 Element = self.etree.Element
2198 SubElement = self.etree.SubElement
2199
2200 a = Element('a')
2201 b = SubElement(a, 'b')
2202 c = SubElement(a, 'c')
2203 d = SubElement(b, 'd')
2204 e = SubElement(c, 'e')
2205
2206 self.assertEqual(
2207 [b, d, c, e],
2208 list(a.iterdescendants()))
2209 self.assertEqual(
2210 [],
2211 list(d.iterdescendants()))
2212
2214 Element = self.etree.Element
2215 SubElement = self.etree.SubElement
2216
2217 a = Element('a')
2218 b = SubElement(a, 'b')
2219 c = SubElement(a, 'c')
2220 d = SubElement(b, 'd')
2221 e = SubElement(c, 'e')
2222
2223 self.assertEqual(
2224 [],
2225 list(a.iterdescendants('a')))
2226 self.assertEqual(
2227 [],
2228 list(a.iterdescendants(tag='a')))
2229
2230 a2 = SubElement(e, 'a')
2231 self.assertEqual(
2232 [a2],
2233 list(a.iterdescendants('a')))
2234
2235 self.assertEqual(
2236 [a2],
2237 list(c.iterdescendants('a')))
2238 self.assertEqual(
2239 [a2],
2240 list(c.iterdescendants(tag='a')))
2241
2243 Element = self.etree.Element
2244 SubElement = self.etree.SubElement
2245
2246 a = Element('a')
2247 b = SubElement(a, 'b')
2248 c = SubElement(a, 'c')
2249 d = SubElement(b, 'd')
2250 e = SubElement(c, 'e')
2251
2252 self.assertEqual(
2253 [b, e],
2254 list(a.iterdescendants(tag=('a', 'b', 'e'))))
2255 self.assertEqual(
2256 [b, e],
2257 list(a.iterdescendants('a', 'b', 'e')))
2258
2259 a2 = SubElement(e, 'a')
2260 self.assertEqual(
2261 [b, a2],
2262 list(a.iterdescendants(tag=('a', 'b'))))
2263 self.assertEqual(
2264 [b, a2],
2265 list(a.iterdescendants('a', 'b')))
2266
2267 self.assertEqual(
2268 [],
2269 list(c.iterdescendants(tag=('x', 'y', 'z'))))
2270 self.assertEqual(
2271 [],
2272 list(c.iterdescendants('x', 'y', 'z')))
2273
2274 self.assertEqual(
2275 [b, d, c, e, a2],
2276 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
2277 self.assertEqual(
2278 [b, d, c, e, a2],
2279 list(a.iterdescendants('x', 'y', 'z', '*')))
2280
2282 Element = self.etree.Element
2283 SubElement = self.etree.SubElement
2284
2285 a = Element('a')
2286 b = SubElement(a, 'b')
2287 c = SubElement(a, 'c')
2288 d = SubElement(b, 'd')
2289 self.assertEqual(
2290 a,
2291 a.getroottree().getroot())
2292 self.assertEqual(
2293 a,
2294 b.getroottree().getroot())
2295 self.assertEqual(
2296 a,
2297 d.getroottree().getroot())
2298
2300 Element = self.etree.Element
2301 SubElement = self.etree.SubElement
2302
2303 a = Element('a')
2304 b = SubElement(a, 'b')
2305 c = SubElement(a, 'c')
2306 self.assertEqual(
2307 None,
2308 a.getnext())
2309 self.assertEqual(
2310 c,
2311 b.getnext())
2312 self.assertEqual(
2313 None,
2314 c.getnext())
2315
2317 Element = self.etree.Element
2318 SubElement = self.etree.SubElement
2319
2320 a = Element('a')
2321 b = SubElement(a, 'b')
2322 c = SubElement(a, 'c')
2323 d = SubElement(b, 'd')
2324 self.assertEqual(
2325 None,
2326 a.getprevious())
2327 self.assertEqual(
2328 b,
2329 c.getprevious())
2330 self.assertEqual(
2331 None,
2332 b.getprevious())
2333
2335 Element = self.etree.Element
2336 SubElement = self.etree.SubElement
2337
2338 a = Element('a')
2339 b = SubElement(a, 'b')
2340 c = SubElement(a, 'c')
2341 d = SubElement(b, 'd')
2342 self.assertEqual(
2343 [],
2344 list(a.itersiblings()))
2345 self.assertEqual(
2346 [c],
2347 list(b.itersiblings()))
2348 self.assertEqual(
2349 [],
2350 list(c.itersiblings()))
2351 self.assertEqual(
2352 [b],
2353 list(c.itersiblings(preceding=True)))
2354 self.assertEqual(
2355 [],
2356 list(b.itersiblings(preceding=True)))
2357
2359 Element = self.etree.Element
2360 SubElement = self.etree.SubElement
2361
2362 a = Element('a')
2363 b = SubElement(a, 'b')
2364 c = SubElement(a, 'c')
2365 d = SubElement(b, 'd')
2366 self.assertEqual(
2367 [],
2368 list(a.itersiblings(tag='XXX')))
2369 self.assertEqual(
2370 [c],
2371 list(b.itersiblings(tag='c')))
2372 self.assertEqual(
2373 [c],
2374 list(b.itersiblings(tag='*')))
2375 self.assertEqual(
2376 [b],
2377 list(c.itersiblings(preceding=True, tag='b')))
2378 self.assertEqual(
2379 [],
2380 list(c.itersiblings(preceding=True, tag='c')))
2381
2383 Element = self.etree.Element
2384 SubElement = self.etree.SubElement
2385
2386 a = Element('a')
2387 b = SubElement(a, 'b')
2388 c = SubElement(a, 'c')
2389 d = SubElement(b, 'd')
2390 e = SubElement(a, 'e')
2391 self.assertEqual(
2392 [],
2393 list(a.itersiblings(tag=('XXX', 'YYY'))))
2394 self.assertEqual(
2395 [c, e],
2396 list(b.itersiblings(tag=('c', 'd', 'e'))))
2397 self.assertEqual(
2398 [b],
2399 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2400 self.assertEqual(
2401 [c, b],
2402 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2403
2405 parseid = self.etree.parseid
2406 XML = self.etree.XML
2407 xml_text = _bytes('''
2408 <!DOCTYPE document [
2409 <!ELEMENT document (h1,p)*>
2410 <!ELEMENT h1 (#PCDATA)>
2411 <!ATTLIST h1 myid ID #REQUIRED>
2412 <!ELEMENT p (#PCDATA)>
2413 <!ATTLIST p someid ID #REQUIRED>
2414 ]>
2415 <document>
2416 <h1 myid="chapter1">...</h1>
2417 <p id="note1" class="note">...</p>
2418 <p>Regular paragraph.</p>
2419 <p xml:id="xmlid">XML:ID paragraph.</p>
2420 <p someid="warn1" class="warning">...</p>
2421 </document>
2422 ''')
2423
2424 tree, dic = parseid(BytesIO(xml_text))
2425 root = tree.getroot()
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 <!DOCTYPE document [
2444 <!ELEMENT document (h1,p)*>
2445 <!ELEMENT h1 (#PCDATA)>
2446 <!ATTLIST h1 myid ID #REQUIRED>
2447 <!ELEMENT p (#PCDATA)>
2448 <!ATTLIST p someid ID #REQUIRED>
2449 ]>
2450 <document>
2451 <h1 myid="chapter1">...</h1>
2452 <p id="note1" class="note">...</p>
2453 <p>Regular paragraph.</p>
2454 <p xml:id="xmlid">XML:ID paragraph.</p>
2455 <p someid="warn1" class="warning">...</p>
2456 </document>
2457 ''')
2458
2459 root, dic = XMLDTDID(xml_text)
2460 root2 = XML(xml_text)
2461 self.assertEqual(self._writeElement(root),
2462 self._writeElement(root2))
2463 expected = {
2464 "chapter1" : root[0],
2465 "xmlid" : root[3],
2466 "warn1" : root[4]
2467 }
2468 self.assertTrue("chapter1" in dic)
2469 self.assertTrue("warn1" in dic)
2470 self.assertTrue("xmlid" in dic)
2471 self._checkIDDict(dic, expected)
2472
2474 XMLDTDID = self.etree.XMLDTDID
2475 XML = self.etree.XML
2476 xml_text = _bytes('''
2477 <document>
2478 <h1 myid="chapter1">...</h1>
2479 <p id="note1" class="note">...</p>
2480 <p>Regular paragraph.</p>
2481 <p someid="warn1" class="warning">...</p>
2482 </document>
2483 ''')
2484
2485 root, dic = XMLDTDID(xml_text)
2486 root2 = XML(xml_text)
2487 self.assertEqual(self._writeElement(root),
2488 self._writeElement(root2))
2489 expected = {}
2490 self._checkIDDict(dic, expected)
2491
2493 XMLDTDID = self.etree.XMLDTDID
2494 XML = self.etree.XML
2495 xml_text = _bytes('''
2496 <!DOCTYPE document [
2497 <!ELEMENT document (h1,p)*>
2498 <!ELEMENT h1 (#PCDATA)>
2499 <!ATTLIST h1 myid ID #REQUIRED>
2500 <!ELEMENT p (#PCDATA)>
2501 <!ATTLIST p someid ID #REQUIRED>
2502 ]>
2503 <document>
2504 <h1 myid="chapter1">...</h1>
2505 <p id="note1" class="note">...</p>
2506 <p>Regular paragraph.</p>
2507 <p xml:id="xmlid">XML:ID paragraph.</p>
2508 <p someid="warn1" class="warning">...</p>
2509 </document>
2510 ''')
2511
2512 parser = etree.XMLParser(collect_ids=False)
2513 root, dic = XMLDTDID(xml_text, parser=parser)
2514 root2 = XML(xml_text)
2515 self.assertEqual(self._writeElement(root),
2516 self._writeElement(root2))
2517 self.assertFalse(dic)
2518 self._checkIDDict(dic, {})
2519
2521 self.assertEqual(len(dic),
2522 len(expected))
2523 self.assertEqual(sorted(dic.items()),
2524 sorted(expected.items()))
2525 if sys.version_info < (3,):
2526 self.assertEqual(sorted(dic.iteritems()),
2527 sorted(expected.iteritems()))
2528 self.assertEqual(sorted(dic.keys()),
2529 sorted(expected.keys()))
2530 if sys.version_info < (3,):
2531 self.assertEqual(sorted(dic.iterkeys()),
2532 sorted(expected.iterkeys()))
2533 if sys.version_info < (3,):
2534 self.assertEqual(sorted(dic.values()),
2535 sorted(expected.values()))
2536 self.assertEqual(sorted(dic.itervalues()),
2537 sorted(expected.itervalues()))
2538
2540 etree = self.etree
2541
2542 r = {'foo': 'http://ns.infrae.com/foo'}
2543 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2544 self.assertEqual(
2545 'foo',
2546 e.prefix)
2547 self.assertEqual(
2548 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2549 self._writeElement(e))
2550
2552 etree = self.etree
2553
2554 r = {None: 'http://ns.infrae.com/foo'}
2555 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2556 self.assertEqual(
2557 None,
2558 e.prefix)
2559 self.assertEqual(
2560 '{http://ns.infrae.com/foo}bar',
2561 e.tag)
2562 self.assertEqual(
2563 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2564 self._writeElement(e))
2565
2567 etree = self.etree
2568
2569 r = {None: 'http://ns.infrae.com/foo', 'p': 'http://test/'}
2570 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2571 self.assertEqual(None, e.prefix)
2572 self.assertEqual('{http://ns.infrae.com/foo}bar', e.tag)
2573 self.assertEqual(
2574 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:p="http://test/"></bar>'),
2575 self._writeElement(e))
2576
2578 etree = self.etree
2579
2580 r = {None: 'http://ns.infrae.com/foo',
2581 'hoi': 'http://ns.infrae.com/hoi'}
2582 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2583 e.set('{http://ns.infrae.com/hoi}test', 'value')
2584 self.assertEqual(
2585 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2586 self._writeElement(e))
2587
2589 etree = self.etree
2590
2591 root = etree.Element('{http://test/ns}root',
2592 nsmap={None: 'http://test/ns'})
2593 sub = etree.Element('{http://test/ns}sub',
2594 nsmap={'test': 'http://test/ns'})
2595
2596 sub.attrib['{http://test/ns}attr'] = 'value'
2597 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2598 self.assertEqual(
2599 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2600 etree.tostring(sub))
2601
2602 root.append(sub)
2603 self.assertEqual(
2604 _bytes('<root xmlns="http://test/ns">'
2605 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2606 '</root>'),
2607 etree.tostring(root))
2608
2610 etree = self.etree
2611
2612 root = etree.Element('root')
2613 sub = etree.Element('{http://test/ns}sub',
2614 nsmap={'test': 'http://test/ns'})
2615
2616 sub.attrib['{http://test/ns}attr'] = 'value'
2617 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2618 self.assertEqual(
2619 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2620 etree.tostring(sub))
2621
2622 root.append(sub)
2623 self.assertEqual(
2624 _bytes('<root>'
2625 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2626 '</root>'),
2627 etree.tostring(root))
2628
2630 etree = self.etree
2631
2632 root = etree.Element('root')
2633 sub = etree.Element('{http://test/ns}sub',
2634 nsmap={None: 'http://test/ns'})
2635
2636 sub.attrib['{http://test/ns}attr'] = 'value'
2637 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2638 self.assertEqual(
2639 _bytes('<sub xmlns="http://test/ns" '
2640 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2641 etree.tostring(sub))
2642
2643 root.append(sub)
2644 self.assertEqual(
2645 _bytes('<root>'
2646 '<sub xmlns="http://test/ns"'
2647 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2648 '</root>'),
2649 etree.tostring(root))
2650
2652 etree = self.etree
2653
2654 root = etree.Element('{http://test/ns}root',
2655 nsmap={'test': 'http://test/ns',
2656 None: 'http://test/ns'})
2657 sub = etree.Element('{http://test/ns}sub',
2658 nsmap={None: 'http://test/ns'})
2659
2660 sub.attrib['{http://test/ns}attr'] = 'value'
2661 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2662 self.assertEqual(
2663 _bytes('<sub xmlns="http://test/ns" '
2664 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2665 etree.tostring(sub))
2666
2667 root.append(sub)
2668 self.assertEqual(
2669 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2670 '<test:sub test:attr="value"/>'
2671 '</test:root>'),
2672 etree.tostring(root))
2673
2675 etree = self.etree
2676 r = {None: 'http://ns.infrae.com/foo',
2677 'hoi': 'http://ns.infrae.com/hoi'}
2678 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2679 tree = etree.ElementTree(element=e)
2680 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2681 self.assertEqual(
2682 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2683 self._writeElement(e))
2684
2686 etree = self.etree
2687
2688 r = {None: 'http://ns.infrae.com/foo'}
2689 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2690 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2691
2692 e1.append(e2)
2693
2694 self.assertEqual(
2695 None,
2696 e1.prefix)
2697 self.assertEqual(
2698 None,
2699 e1[0].prefix)
2700 self.assertEqual(
2701 '{http://ns.infrae.com/foo}bar',
2702 e1.tag)
2703 self.assertEqual(
2704 '{http://ns.infrae.com/foo}bar',
2705 e1[0].tag)
2706
2708 etree = self.etree
2709
2710 r = {None: 'http://ns.infrae.com/BAR'}
2711 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2712 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2713
2714 e1.append(e2)
2715
2716 self.assertEqual(
2717 None,
2718 e1.prefix)
2719 self.assertNotEqual(
2720 None,
2721 e2.prefix)
2722 self.assertEqual(
2723 '{http://ns.infrae.com/BAR}bar',
2724 e1.tag)
2725 self.assertEqual(
2726 '{http://ns.infrae.com/foo}bar',
2727 e2.tag)
2728
2730 ns_href = "http://a.b.c"
2731 one = self.etree.fromstring(
2732 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2733 baz = one[0][0]
2734
2735 two = self.etree.fromstring(
2736 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2737 two.append(baz)
2738 del one # make sure the source document is deallocated
2739
2740 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2741 self.assertEqual(
2742 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2743 self.etree.tostring(two))
2744
2746 xml = _bytes(
2747 '<foo xmlns="F" xmlns:x="x">'
2748 '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">'
2749 '<ns:baz/>'
2750 '</bar></foo>'
2751 )
2752 root = self.etree.fromstring(xml)
2753 self.assertEqual(xml, self.etree.tostring(root))
2754 self.etree.cleanup_namespaces(root)
2755 self.assertEqual(
2756 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
2757 self.etree.tostring(root))
2758
2760 xml = _bytes(
2761 '<foo xmlns="F" xmlns:x="X" xmlns:a="A">'
2762 '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">'
2763 '<ns:baz a:test="attr"/>'
2764 '</bar></foo>'
2765 )
2766 root = self.etree.fromstring(xml)
2767 self.assertEqual(xml, self.etree.tostring(root))
2768 self.etree.cleanup_namespaces(root)
2769 self.assertEqual(
2770 _bytes('<foo xmlns="F" xmlns:a="A">'
2771 '<bar xmlns:ns="NS" xmlns="B">'
2772 '<ns:baz a:test="attr"/>'
2773 '</bar></foo>'),
2774 self.etree.tostring(root))
2775
2777 xml = ('<n12:foo ' +
2778 ' '.join('xmlns:n{n}="NS{n}"'.format(n=i) for i in range(100)) +
2779 '><n68:a/></n12:foo>').encode('utf8')
2780 root = self.etree.fromstring(xml)
2781 self.assertEqual(xml, self.etree.tostring(root))
2782 self.etree.cleanup_namespaces(root)
2783 self.assertEqual(
2784 b'<n12:foo xmlns:n12="NS12" xmlns:n68="NS68"><n68:a/></n12:foo>',
2785 self.etree.tostring(root))
2786
2788 xml = ('<root>' +
2789 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) +
2790 '<n64:x/>' + '</a>'*100 + '</root>').encode('utf8')
2791 root = self.etree.fromstring(xml)
2792 self.assertEqual(xml, self.etree.tostring(root))
2793 self.etree.cleanup_namespaces(root)
2794 self.assertEqual(
2795 b'<root>' + b'<a>'*64 + b'<a xmlns:n64="NS64">' + b'<a>'*35 +
2796 b'<n64:x/>' + b'</a>'*100 + b'</root>',
2797 self.etree.tostring(root))
2798
2800 xml = ('<root>' +
2801 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) +
2802 '<n64:x xmlns:a="A" a:attr="X"/>' +
2803 '</a>'*100 +
2804 '</root>').encode('utf8')
2805 root = self.etree.fromstring(xml)
2806 self.assertEqual(xml, self.etree.tostring(root))
2807 self.etree.cleanup_namespaces(root, top_nsmap={'n64': 'NS64'})
2808 self.assertEqual(
2809 b'<root xmlns:n64="NS64">' + b'<a>'*100 +
2810 b'<n64:x xmlns:a="A" a:attr="X"/>' + b'</a>'*100 + b'</root>',
2811 self.etree.tostring(root))
2812
2814 xml = ('<root xmlns:n64="NS64" xmlns:foo="FOO" xmlns:unused1="UNUSED" xmlns:no="NO">'
2815 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>'
2816 '<foo>foo:bar</foo>'
2817 '</root>').encode('utf8')
2818 root = self.etree.fromstring(xml)
2819 self.assertEqual(xml, self.etree.tostring(root))
2820 self.etree.cleanup_namespaces(root, keep_ns_prefixes=['foo'])
2821 self.assertEqual(
2822 b'<root xmlns:n64="NS64" xmlns:foo="FOO">'
2823 b'<a><n64:x xmlns:a="A" a:attr="X"/></a>'
2824 b'<foo>foo:bar</foo>'
2825 b'</root>',
2826 self.etree.tostring(root))
2827
2829 xml = ('<root xmlns:n64="NS64" xmlns:unused1="UNUSED" xmlns:no="NO">'
2830 '<sub xmlns:foo="FOO">'
2831 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>'
2832 '<foo>foo:bar</foo>'
2833 '</sub>'
2834 '</root>').encode('utf8')
2835 root = self.etree.fromstring(xml)
2836 self.assertEqual(xml, self.etree.tostring(root))
2837 self.etree.cleanup_namespaces(
2838 root,
2839 top_nsmap={'foo': 'FOO', 'unused1': 'UNUSED'},
2840 keep_ns_prefixes=['foo'])
2841 self.assertEqual(
2842 b'<root xmlns:n64="NS64" xmlns:foo="FOO">'
2843 b'<sub>'
2844 b'<a><n64:x xmlns:a="A" a:attr="X"/></a>'
2845 b'<foo>foo:bar</foo>'
2846 b'</sub>'
2847 b'</root>',
2848 self.etree.tostring(root))
2849
2851 etree = self.etree
2852
2853 r = {None: 'http://ns.infrae.com/foo',
2854 'hoi': 'http://ns.infrae.com/hoi'}
2855 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2856 self.assertEqual(
2857 r,
2858 e.nsmap)
2859
2861 etree = self.etree
2862
2863 re = {None: 'http://ns.infrae.com/foo',
2864 'hoi': 'http://ns.infrae.com/hoi'}
2865 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2866
2867 rs = {None: 'http://ns.infrae.com/honk',
2868 'top': 'http://ns.infrae.com/top'}
2869 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2870
2871 r = re.copy()
2872 r.update(rs)
2873 self.assertEqual(re, e.nsmap)
2874 self.assertEqual(r, s.nsmap)
2875
2877 etree = self.etree
2878 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2879 self.assertEqual({'hha': None}, el.nsmap)
2880
2882 Element = self.etree.Element
2883 SubElement = self.etree.SubElement
2884
2885 a = Element('a')
2886 b = SubElement(a, 'b')
2887 c = SubElement(a, 'c')
2888 d = SubElement(b, 'd')
2889 e = SubElement(c, 'e')
2890 f = SubElement(c, 'f')
2891
2892 self.assertEqual(
2893 [a, b],
2894 list(a.getiterator('a', 'b')))
2895 self.assertEqual(
2896 [],
2897 list(a.getiterator('x', 'y')))
2898 self.assertEqual(
2899 [a, f],
2900 list(a.getiterator('f', 'a')))
2901 self.assertEqual(
2902 [c, e, f],
2903 list(c.getiterator('c', '*', 'a')))
2904 self.assertEqual(
2905 [],
2906 list(a.getiterator( (), () )))
2907
2909 Element = self.etree.Element
2910 SubElement = self.etree.SubElement
2911
2912 a = Element('a')
2913 b = SubElement(a, 'b')
2914 c = SubElement(a, 'c')
2915 d = SubElement(b, 'd')
2916 e = SubElement(c, 'e')
2917 f = SubElement(c, 'f')
2918
2919 self.assertEqual(
2920 [a, b],
2921 list(a.getiterator( ('a', 'b') )))
2922 self.assertEqual(
2923 [],
2924 list(a.getiterator( ('x', 'y') )))
2925 self.assertEqual(
2926 [a, f],
2927 list(a.getiterator( ('f', 'a') )))
2928 self.assertEqual(
2929 [c, e, f],
2930 list(c.getiterator( ('c', '*', 'a') )))
2931 self.assertEqual(
2932 [],
2933 list(a.getiterator( () )))
2934
2936 Element = self.etree.Element
2937 SubElement = self.etree.SubElement
2938
2939 a = Element('{a}a')
2940 b = SubElement(a, '{a}b')
2941 c = SubElement(a, '{a}c')
2942 d = SubElement(b, '{b}d')
2943 e = SubElement(c, '{a}e')
2944 f = SubElement(c, '{b}f')
2945 g = SubElement(c, 'g')
2946
2947 self.assertEqual(
2948 [a],
2949 list(a.getiterator('{a}a')))
2950 self.assertEqual(
2951 [],
2952 list(a.getiterator('{b}a')))
2953 self.assertEqual(
2954 [],
2955 list(a.getiterator('a')))
2956 self.assertEqual(
2957 [a,b,d,c,e,f,g],
2958 list(a.getiterator('*')))
2959 self.assertEqual(
2960 [f],
2961 list(c.getiterator('{b}*')))
2962 self.assertEqual(
2963 [d, f],
2964 list(a.getiterator('{b}*')))
2965 self.assertEqual(
2966 [g],
2967 list(a.getiterator('g')))
2968 self.assertEqual(
2969 [g],
2970 list(a.getiterator('{}g')))
2971 self.assertEqual(
2972 [g],
2973 list(a.getiterator('{}*')))
2974
2976 Element = self.etree.Element
2977 SubElement = self.etree.SubElement
2978
2979 a = Element('{a}a')
2980 b = SubElement(a, '{nsA}b')
2981 c = SubElement(b, '{nsB}b')
2982 d = SubElement(a, 'b')
2983 e = SubElement(a, '{nsA}e')
2984 f = SubElement(e, '{nsB}e')
2985 g = SubElement(e, 'e')
2986
2987 self.assertEqual(
2988 [b, c, d],
2989 list(a.getiterator('{*}b')))
2990 self.assertEqual(
2991 [e, f, g],
2992 list(a.getiterator('{*}e')))
2993 self.assertEqual(
2994 [a, b, c, d, e, f, g],
2995 list(a.getiterator('{*}*')))
2996
2998 Element = self.etree.Element
2999 Entity = self.etree.Entity
3000 SubElement = self.etree.SubElement
3001
3002 a = Element('a')
3003 b = SubElement(a, 'b')
3004 entity_b = Entity("TEST-b")
3005 b.append(entity_b)
3006
3007 self.assertEqual(
3008 [entity_b],
3009 list(a.getiterator(Entity)))
3010
3011 entity_a = Entity("TEST-a")
3012 a.append(entity_a)
3013
3014 self.assertEqual(
3015 [entity_b, entity_a],
3016 list(a.getiterator(Entity)))
3017
3018 self.assertEqual(
3019 [entity_b],
3020 list(b.getiterator(Entity)))
3021
3023 Element = self.etree.Element
3024 Comment = self.etree.Comment
3025 PI = self.etree.PI
3026 SubElement = self.etree.SubElement
3027
3028 a = Element('a')
3029 b = SubElement(a, 'b')
3030 a.append(Comment("test"))
3031 a.append(PI("pi", "content"))
3032 c = SubElement(a, 'c')
3033
3034 self.assertEqual(
3035 [a, b, c],
3036 list(a.getiterator(Element)))
3037
3039 # ElementTree iterates over everything here
3040 Element = self.etree.Element
3041 Comment = self.etree.Comment
3042 PI = self.etree.PI
3043 SubElement = self.etree.SubElement
3044
3045 a = Element('a')
3046 b = SubElement(a, 'b')
3047 a.append(Comment("test"))
3048 a.append(PI("pi", "content"))
3049 c = SubElement(a, 'c')
3050
3051 self.assertEqual(
3052 [a, b, c],
3053 list(a.getiterator('*')))
3054
3056 a = etree.Element("a")
3057 b = etree.SubElement(a, "b")
3058 c = etree.SubElement(a, "c")
3059 d1 = etree.SubElement(c, "d")
3060 d2 = etree.SubElement(c, "d")
3061 c.text = d1.text = 'TEXT'
3062
3063 tree = etree.ElementTree(a)
3064 self.assertEqual('.', tree.getelementpath(a))
3065 self.assertEqual('c/d[1]', tree.getelementpath(d1))
3066 self.assertEqual('c/d[2]', tree.getelementpath(d2))
3067
3068 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
3069 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
3070
3071 tree = etree.ElementTree(c)
3072 self.assertEqual('.', tree.getelementpath(c))
3073 self.assertEqual('d[2]', tree.getelementpath(d2))
3074 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
3075
3076 tree = etree.ElementTree(b) # not a parent of a/c/d1/d2
3077 self.assertEqual('.', tree.getelementpath(b))
3078 self.assertRaises(ValueError, tree.getelementpath, a)
3079 self.assertRaises(ValueError, tree.getelementpath, c)
3080 self.assertRaises(ValueError, tree.getelementpath, d2)
3081
3083 a = etree.Element("{http://ns1/}a")
3084 b = etree.SubElement(a, "{http://ns1/}b")
3085 c = etree.SubElement(a, "{http://ns1/}c")
3086 d1 = etree.SubElement(c, "{http://ns1/}d")
3087 d2 = etree.SubElement(c, "{http://ns2/}d")
3088 d3 = etree.SubElement(c, "{http://ns1/}d")
3089
3090 tree = etree.ElementTree(a)
3091 self.assertEqual('.', tree.getelementpath(a))
3092 self.assertEqual('{http://ns1/}c/{http://ns1/}d[1]',
3093 tree.getelementpath(d1))
3094 self.assertEqual('{http://ns1/}c/{http://ns2/}d',
3095 tree.getelementpath(d2))
3096 self.assertEqual('{http://ns1/}c/{http://ns1/}d[2]',
3097 tree.getelementpath(d3))
3098
3099 self.assertEqual(a, tree.find(tree.getelementpath(a)))
3100 self.assertEqual(b, tree.find(tree.getelementpath(b)))
3101 self.assertEqual(c, tree.find(tree.getelementpath(c)))
3102 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
3103 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
3104 self.assertEqual(d3, tree.find(tree.getelementpath(d3)))
3105
3106 tree = etree.ElementTree(c)
3107 self.assertEqual('{http://ns1/}d[1]', tree.getelementpath(d1))
3108 self.assertEqual('{http://ns2/}d', tree.getelementpath(d2))
3109 self.assertEqual('{http://ns1/}d[2]', tree.getelementpath(d3))
3110 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
3111 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
3112 self.assertEqual(d3, tree.find(tree.getelementpath(d3)))
3113
3114 tree = etree.ElementTree(b) # not a parent of d1/d2
3115 self.assertRaises(ValueError, tree.getelementpath, d1)
3116 self.assertRaises(ValueError, tree.getelementpath, d2)
3117
3119 XML = self.etree.XML
3120 ElementTree = self.etree.ElementTree
3121 QName = self.etree.QName
3122 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
3123 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
3124
3126 XML = self.etree.XML
3127 ElementTree = self.etree.ElementTree
3128 QName = self.etree.QName
3129 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
3130 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
3131
3133 XML = self.etree.XML
3134 ElementTree = self.etree.ElementTree
3135 QName = self.etree.QName
3136 tree = ElementTree(XML(
3137 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
3138 self.assertEqual(len(list(tree.findall(QName("b")))), 2)
3139 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
3140
3142 XML = self.etree.XML
3143 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
3144 self.assertEqual(len(root.findall(".//{X}b")), 2)
3145 self.assertEqual(len(root.findall(".//{X}*")), 2)
3146 self.assertEqual(len(root.findall(".//b")), 3)
3147
3149 XML = self.etree.XML
3150 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
3151 nsmap = {'xx': 'X'}
3152 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
3153 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
3154 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
3155 nsmap = {'xx': 'Y'}
3156 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
3157 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
3158 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
3159
3161 XML = self.etree.XML
3162 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
3163 nsmap = {'xx': 'X'}
3164 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
3165 nsmap = {'xx': 'X', None: 'Y'}
3166 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 1)
3167 nsmap = {'xx': 'X', '': 'Y'}
3168 self.assertRaises(ValueError, root.findall, ".//xx:b", namespaces=nsmap)
3169
3171 XML = self.etree.XML
3172 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>'))
3173 self.assertRaises(SyntaxError, root.findall, '')
3174 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element
3175 self.assertRaises(SyntaxError, root.findall, './//')
3176
3178 etree = self.etree
3179 e = etree.Element('foo')
3180 for i in range(10):
3181 etree.SubElement(e, 'a%s' % i)
3182 for i in range(10):
3183 self.assertEqual(
3184 i,
3185 e.index(e[i]))
3186 self.assertEqual(
3187 3, e.index(e[3], 3))
3188 self.assertRaises(
3189 ValueError, e.index, e[3], 4)
3190 self.assertRaises(
3191 ValueError, e.index, e[3], 0, 2)
3192 self.assertRaises(
3193 ValueError, e.index, e[8], 0, -3)
3194 self.assertRaises(
3195 ValueError, e.index, e[8], -5, -3)
3196 self.assertEqual(
3197 8, e.index(e[8], 0, -1))
3198 self.assertEqual(
3199 8, e.index(e[8], -12, -1))
3200 self.assertEqual(
3201 0, e.index(e[0], -12, -1))
3202
3204 etree = self.etree
3205 e = etree.Element('foo')
3206 for i in range(10):
3207 el = etree.SubElement(e, 'a%s' % i)
3208 el.text = "text%d" % i
3209 el.tail = "tail%d" % i
3210
3211 child0 = e[0]
3212 child1 = e[1]
3213 child2 = e[2]
3214
3215 e.replace(e[0], e[1])
3216 self.assertEqual(
3217 9, len(e))
3218 self.assertEqual(
3219 child1, e[0])
3220 self.assertEqual(
3221 child1.text, "text1")
3222 self.assertEqual(
3223 child1.tail, "tail1")
3224 self.assertEqual(
3225 child0.tail, "tail0")
3226 self.assertEqual(
3227 child2, e[1])
3228
3229 e.replace(e[-1], e[0])
3230 self.assertEqual(
3231 child1, e[-1])
3232 self.assertEqual(
3233 child1.text, "text1")
3234 self.assertEqual(
3235 child1.tail, "tail1")
3236 self.assertEqual(
3237 child2, e[0])
3238
3240 etree = self.etree
3241 e = etree.Element('foo')
3242 for i in range(10):
3243 etree.SubElement(e, 'a%s' % i)
3244
3245 new_element = etree.Element("test")
3246 new_element.text = "TESTTEXT"
3247 new_element.tail = "TESTTAIL"
3248 child1 = e[1]
3249 e.replace(e[0], new_element)
3250 self.assertEqual(
3251 new_element, e[0])
3252 self.assertEqual(
3253 "TESTTEXT",
3254 e[0].text)
3255 self.assertEqual(
3256 "TESTTAIL",
3257 e[0].tail)
3258 self.assertEqual(
3259 child1, e[1])
3260
3262 Element = self.etree.Element
3263 SubElement = self.etree.SubElement
3264
3265 a = Element('a')
3266
3267 e = Element('e')
3268 f = Element('f')
3269 g = Element('g')
3270
3271 s = [e, f, g]
3272 a[::-1] = s
3273 self.assertEqual(
3274 [g, f, e],
3275 list(a))
3276
3278 Element = self.etree.Element
3279 SubElement = self.etree.SubElement
3280
3281 a = Element('a')
3282 b = SubElement(a, 'b')
3283 c = SubElement(a, 'c')
3284 d = SubElement(a, 'd')
3285 e = SubElement(a, 'e')
3286
3287 x = Element('x')
3288 y = Element('y')
3289
3290 a[1::2] = [x, y]
3291 self.assertEqual(
3292 [b, x, d, y],
3293 list(a))
3294
3296 Element = self.etree.Element
3297 SubElement = self.etree.SubElement
3298
3299 a = Element('a')
3300 b = SubElement(a, 'b')
3301 c = SubElement(a, 'c')
3302 d = SubElement(a, 'd')
3303 e = SubElement(a, 'e')
3304
3305 x = Element('x')
3306 y = Element('y')
3307
3308 a[1::-1] = [x, y]
3309 self.assertEqual(
3310 [y, x, d, e],
3311 list(a))
3312
3314 Element = self.etree.Element
3315 SubElement = self.etree.SubElement
3316
3317 a = Element('a')
3318 b = SubElement(a, 'b')
3319 c = SubElement(a, 'c')
3320 d = SubElement(a, 'd')
3321 e = SubElement(a, 'e')
3322
3323 x = Element('x')
3324 y = Element('y')
3325
3326 a[::-2] = [x, y]
3327 self.assertEqual(
3328 [b, y, d, x],
3329 list(a))
3330
3332 Element = self.etree.Element
3333 SubElement = self.etree.SubElement
3334 try:
3335 slice
3336 except NameError:
3337 print("slice() not found")
3338 return
3339
3340 a = Element('a')
3341 b = SubElement(a, 'b')
3342 c = SubElement(a, 'c')
3343 d = SubElement(a, 'd')
3344 e = SubElement(a, 'e')
3345
3346 x = Element('x')
3347 y = Element('y')
3348 z = Element('z')
3349
3350 self.assertRaises(
3351 ValueError,
3352 operator.setitem, a, slice(1,None,2), [x, y, z])
3353
3354 self.assertEqual(
3355 [b, c, d, e],
3356 list(a))
3357
3359 XML = self.etree.XML
3360 root = XML(_bytes('''<?xml version="1.0"?>
3361 <root><test>
3362
3363 <bla/></test>
3364 </root>
3365 '''))
3366
3367 self.assertEqual(
3368 [2, 2, 4],
3369 [ el.sourceline for el in root.getiterator() ])
3370
3372 XML = self.etree.XML
3373 root = XML(_bytes(
3374 '<?xml version="1.0"?>\n'
3375 '<root>' + '\n' * 65536 +
3376 '<p>' + '\n' * 65536 + '</p>\n' +
3377 '<br/>\n'
3378 '</root>'))
3379
3380 if self.etree.LIBXML_VERSION >= (2, 9):
3381 expected = [2, 131074, 131076]
3382 else:
3383 expected = [2, 65535, 65535]
3384
3385 self.assertEqual(expected, [el.sourceline for el in root.iter()])
3386
3388 parse = self.etree.parse
3389 tree = parse(fileInTestDir('include/test_xinclude.xml'))
3390
3391 self.assertEqual(
3392 [1, 2, 3],
3393 [ el.sourceline for el in tree.getiterator() ])
3394
3396 iterparse = self.etree.iterparse
3397 lines = [ el.sourceline for (event, el) in
3398 iterparse(fileInTestDir('include/test_xinclude.xml')) ]
3399
3400 self.assertEqual(
3401 [2, 3, 1],
3402 lines)
3403
3405 iterparse = self.etree.iterparse
3406 lines = [ el.sourceline for (event, el) in
3407 iterparse(fileInTestDir('include/test_xinclude.xml'),
3408 events=("start",)) ]
3409
3410 self.assertEqual(
3411 [1, 2, 3],
3412 lines)
3413
3415 Element = self.etree.Element
3416 SubElement = self.etree.SubElement
3417 el = Element("test")
3418 self.assertEqual(None, el.sourceline)
3419
3420 child = SubElement(el, "test")
3421 self.assertEqual(None, el.sourceline)
3422 self.assertEqual(None, child.sourceline)
3423
3425 etree = self.etree
3426 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3427 docinfo = root.getroottree().docinfo
3428 self.assertEqual(docinfo.URL, "http://no/such/url")
3429
3431 etree = self.etree
3432 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3433 docinfo = root.getroottree().docinfo
3434 self.assertEqual(docinfo.URL, "http://no/such/url")
3435 docinfo.URL = "https://secret/url"
3436 self.assertEqual(docinfo.URL, "https://secret/url")
3437
3439 etree = self.etree
3440 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
3441 docinfo = tree.docinfo
3442 self.assertEqual(docinfo.URL, "http://no/such/url")
3443
3445 etree = self.etree
3446 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3447 base_url="http://no/such/url")
3448 docinfo = tree.docinfo
3449 self.assertEqual(docinfo.URL, "http://no/such/url")
3450
3452 etree = self.etree
3453 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
3454 docinfo = root.getroottree().docinfo
3455 self.assertEqual(docinfo.URL, "http://no/such/url")
3456
3458 etree = self.etree
3459 xml_header = '<?xml version="1.0" encoding="ascii"?>'
3460 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3461 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3462 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
3463
3464 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3465
3466 tree = etree.parse(BytesIO(xml))
3467 docinfo = tree.docinfo
3468 self.assertEqual(docinfo.encoding, "ascii")
3469 self.assertEqual(docinfo.xml_version, "1.0")
3470 self.assertEqual(docinfo.public_id, pub_id)
3471 self.assertEqual(docinfo.system_url, sys_id)
3472 self.assertEqual(docinfo.root_name, 'html')
3473 self.assertEqual(docinfo.doctype, doctype_string)
3474
3476 etree = self.etree
3477 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
3478 sys_id = "some.dtd"
3479 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
3480 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3481
3482 tree = etree.parse(BytesIO(xml))
3483 docinfo = tree.docinfo
3484 self.assertEqual(docinfo.encoding, "UTF-8")
3485 self.assertEqual(docinfo.xml_version, "1.0")
3486 self.assertEqual(docinfo.public_id, None)
3487 self.assertEqual(docinfo.system_url, sys_id)
3488 self.assertEqual(docinfo.root_name, 'html')
3489 self.assertEqual(docinfo.doctype, doctype_string)
3490
3492 etree = self.etree
3493 xml = _bytes('<html><body></body></html>')
3494 tree = etree.parse(BytesIO(xml))
3495 docinfo = tree.docinfo
3496 self.assertEqual(docinfo.encoding, "UTF-8")
3497 self.assertEqual(docinfo.xml_version, "1.0")
3498 self.assertEqual(docinfo.public_id, None)
3499 self.assertEqual(docinfo.system_url, None)
3500 self.assertEqual(docinfo.root_name, 'html')
3501 self.assertEqual(docinfo.doctype, '')
3502
3504 etree = self.etree
3505 xml = _bytes('<!DOCTYPE root><root></root>')
3506 tree = etree.parse(BytesIO(xml))
3507 docinfo = tree.docinfo
3508 self.assertEqual(docinfo.encoding, "UTF-8")
3509 self.assertEqual(docinfo.xml_version, "1.0")
3510 self.assertEqual(docinfo.public_id, None)
3511 self.assertEqual(docinfo.system_url, None)
3512 self.assertEqual(docinfo.root_name, 'root')
3513 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
3514
3516 etree = self.etree
3517 xml = _bytes('<!DOCTYPE root>\n<root/>')
3518 tree = etree.parse(BytesIO(xml))
3519 self.assertEqual(xml, etree.tostring(tree))
3520
3522 etree = self.etree
3523 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3524 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3525 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
3526
3527 xml = _bytes('<!DOCTYPE root>\n<root/>')
3528 tree = etree.parse(BytesIO(xml))
3529 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
3530 etree.tostring(tree, doctype=doctype_string))
3531
3533 etree = self.etree
3534 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3535 self.assertEqual(root.base, "http://no/such/url")
3536 self.assertEqual(
3537 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3538 root.base = "https://secret/url"
3539 self.assertEqual(root.base, "https://secret/url")
3540 self.assertEqual(
3541 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3542 "https://secret/url")
3543
3545 etree = self.etree
3546 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3547 self.assertEqual(root.base, "http://no/such/url")
3548 self.assertEqual(
3549 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3550 root.set('{http://www.w3.org/XML/1998/namespace}base',
3551 "https://secret/url")
3552 self.assertEqual(root.base, "https://secret/url")
3553 self.assertEqual(
3554 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3555 "https://secret/url")
3556
3558 etree = self.etree
3559 root = etree.HTML(_bytes("<html><body></body></html>"),
3560 base_url="http://no/such/url")
3561 self.assertEqual(root.base, "http://no/such/url")
3562
3564 etree = self.etree
3565 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
3566 self.assertEqual(root.base, "http://no/such/url")
3567
3569 # parse from a file object that returns unicode strings
3570 f = LargeFileLikeUnicode()
3571 tree = self.etree.parse(f)
3572 root = tree.getroot()
3573 self.assertTrue(root.tag.endswith('root'))
3574
3576 # check that DTDs that go in also go back out
3577 xml = _bytes('''\
3578 <!DOCTYPE test SYSTEM "test.dtd" [
3579 <!ENTITY entity "tasty">
3580 <!ELEMENT test (a)>
3581 <!ELEMENT a (#PCDATA)>
3582 ]>
3583 <test><a>test-test</a></test>\
3584 ''')
3585 tree = self.etree.parse(BytesIO(xml))
3586 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
3587 xml.replace(_bytes(" "), _bytes("")))
3588
3590 Element = self.etree.Element
3591
3592 a = Element('a')
3593 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3594 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3595
3596 self.assertRaises(ValueError, Element, 'ha\0ho')
3597
3599 Element = self.etree.Element
3600
3601 a = Element('a')
3602 self.assertRaises(ValueError, setattr, a, "text",
3603 _str('ha\0ho'))
3604 self.assertRaises(ValueError, setattr, a, "tail",
3605 _str('ha\0ho'))
3606
3607 self.assertRaises(ValueError, Element,
3608 _str('ha\0ho'))
3609
3611 Element = self.etree.Element
3612
3613 a = Element('a')
3614 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3615 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3616
3617 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3618 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3619
3620 self.assertRaises(ValueError, Element, 'ha\x07ho')
3621 self.assertRaises(ValueError, Element, 'ha\x02ho')
3622
3624 Element = self.etree.Element
3625
3626 a = Element('a')
3627 self.assertRaises(ValueError, setattr, a, "text",
3628 _str('ha\x07ho'))
3629 self.assertRaises(ValueError, setattr, a, "text",
3630 _str('ha\x02ho'))
3631
3632 self.assertRaises(ValueError, setattr, a, "tail",
3633 _str('ha\x07ho'))
3634 self.assertRaises(ValueError, setattr, a, "tail",
3635 _str('ha\x02ho'))
3636
3637 self.assertRaises(ValueError, Element,
3638 _str('ha\x07ho'))
3639 self.assertRaises(ValueError, Element,
3640 _str('ha\x02ho'))
3641
3643 Element = self.etree.Element
3644
3645 a = Element('a')
3646 self.assertRaises(ValueError, setattr, a, "text",
3647 _str('ha\u1234\x07ho'))
3648 self.assertRaises(ValueError, setattr, a, "text",
3649 _str('ha\u1234\x02ho'))
3650
3651 self.assertRaises(ValueError, setattr, a, "tail",
3652 _str('ha\u1234\x07ho'))
3653 self.assertRaises(ValueError, setattr, a, "tail",
3654 _str('ha\u1234\x02ho'))
3655
3656 self.assertRaises(ValueError, Element,
3657 _str('ha\u1234\x07ho'))
3658 self.assertRaises(ValueError, Element,
3659 _str('ha\u1234\x02ho'))
3660
3662 # ElementTree fails to serialize this
3663 tostring = self.etree.tostring
3664 Element = self.etree.Element
3665 SubElement = self.etree.SubElement
3666
3667 a = Element('a')
3668 b = SubElement(a, 'b')
3669 c = SubElement(a, 'c')
3670
3671 result = tostring(a, encoding='UTF-16')
3672 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3673 canonicalize(result))
3674
3676 # ElementTree raises an AssertionError here
3677 tostring = self.etree.tostring
3678 self.assertRaises(TypeError, self.etree.tostring, None)
3679
3681 tostring = self.etree.tostring
3682 Element = self.etree.Element
3683 SubElement = self.etree.SubElement
3684
3685 a = Element('a')
3686 b = SubElement(a, 'b')
3687 c = SubElement(a, 'c')
3688
3689 result = tostring(a)
3690 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3691
3692 result = tostring(a, pretty_print=False)
3693 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3694
3695 result = tostring(a, pretty_print=True)
3696 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3697
3699 tostring = self.etree.tostring
3700 Element = self.etree.Element
3701 SubElement = self.etree.SubElement
3702
3703 a = Element('a')
3704 a.tail = "aTAIL"
3705 b = SubElement(a, 'b')
3706 b.tail = "bTAIL"
3707 c = SubElement(a, 'c')
3708
3709 result = tostring(a)
3710 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3711
3712 result = tostring(a, with_tail=False)
3713 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>"))
3714
3715 result = tostring(a, with_tail=True)
3716 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3717
3719 tostring = self.etree.tostring
3720 html = self.etree.fromstring(
3721 '<html><body>'
3722 '<div><p>Some text<i>\r\n</i></p></div>\r\n'
3723 '</body></html>',
3724 parser=self.etree.HTMLParser())
3725 self.assertEqual(html.tag, 'html')
3726 div = html.find('.//div')
3727 self.assertEqual(div.tail, '\r\n')
3728 result = tostring(div, method='html')
3729 self.assertEqual(
3730 result,
3731 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3732 result = tostring(div, method='html', with_tail=True)
3733 self.assertEqual(
3734 result,
3735 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3736 result = tostring(div, method='html', with_tail=False)
3737 self.assertEqual(
3738 result,
3739 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3740
3742 tostring = self.etree.tostring
3743 XML = self.etree.XML
3744 ElementTree = self.etree.ElementTree
3745 Element = self.etree.Element
3746
3747 tree = Element("root").getroottree()
3748 self.assertEqual(None, tree.docinfo.standalone)
3749
3750 tree = XML(_bytes("<root/>")).getroottree()
3751 self.assertEqual(None, tree.docinfo.standalone)
3752
3753 tree = XML(_bytes(
3754 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
3755 )).getroottree()
3756 self.assertEqual(True, tree.docinfo.standalone)
3757
3758 tree = XML(_bytes(
3759 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
3760 )).getroottree()
3761 self.assertEqual(False, tree.docinfo.standalone)
3762
3764 tostring = self.etree.tostring
3765 XML = self.etree.XML
3766 ElementTree = self.etree.ElementTree
3767
3768 root = XML(_bytes("<root/>"))
3769
3770 tree = ElementTree(root)
3771 self.assertEqual(None, tree.docinfo.standalone)
3772
3773 result = tostring(root, xml_declaration=True, encoding="ASCII")
3774 self.assertEqual(result, _bytes(
3775 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3776
3777 result = tostring(root, xml_declaration=True, encoding="ASCII",
3778 standalone=True)
3779 self.assertEqual(result, _bytes(
3780 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3781
3782 tree = ElementTree(XML(result))
3783 self.assertEqual(True, tree.docinfo.standalone)
3784
3785 result = tostring(root, xml_declaration=True, encoding="ASCII",
3786 standalone=False)
3787 self.assertEqual(result, _bytes(
3788 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3789
3790 tree = ElementTree(XML(result))
3791 self.assertEqual(False, tree.docinfo.standalone)
3792
3794 tostring = self.etree.tostring
3795 XML = self.etree.XML
3796 ElementTree = self.etree.ElementTree
3797
3798 root = XML(_bytes(
3799 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
3800
3801 tree = ElementTree(root)
3802 self.assertEqual(True, tree.docinfo.standalone)
3803
3804 result = tostring(root, xml_declaration=True, encoding="ASCII")
3805 self.assertEqual(result, _bytes(
3806 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3807
3808 result = tostring(root, xml_declaration=True, encoding="ASCII",
3809 standalone=True)
3810 self.assertEqual(result, _bytes(
3811 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3812
3814 tostring = self.etree.tostring
3815 Element = self.etree.Element
3816 SubElement = self.etree.SubElement
3817
3818 a = Element('a')
3819 a.text = "A"
3820 a.tail = "tail"
3821 b = SubElement(a, 'b')
3822 b.text = "B"
3823 b.tail = _str("Søk på nettet")
3824 c = SubElement(a, 'c')
3825 c.text = "C"
3826
3827 result = tostring(a, method="text", encoding="UTF-16")
3828
3829 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3830 result)
3831
3833 tostring = self.etree.tostring
3834 Element = self.etree.Element
3835 SubElement = self.etree.SubElement
3836
3837 a = Element('a')
3838 a.text = _str('Søk på nettetA')
3839 a.tail = "tail"
3840 b = SubElement(a, 'b')
3841 b.text = "B"
3842 b.tail = _str('Søk på nettetB')
3843 c = SubElement(a, 'c')
3844 c.text = "C"
3845
3846 self.assertRaises(UnicodeEncodeError,
3847 tostring, a, method="text")
3848
3849 self.assertEqual(
3850 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3851 tostring(a, encoding="UTF-8", method="text"))
3852
3854 tounicode = self.etree.tounicode
3855 Element = self.etree.Element
3856 SubElement = self.etree.SubElement
3857
3858 a = Element('a')
3859 b = SubElement(a, 'b')
3860 c = SubElement(a, 'c')
3861
3862 self.assertTrue(isinstance(tounicode(a), _unicode))
3863 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3864 canonicalize(tounicode(a)))
3865
3867 tounicode = self.etree.tounicode
3868 Element = self.etree.Element
3869 SubElement = self.etree.SubElement
3870
3871 a = Element('a')
3872 b = SubElement(a, 'b')
3873 c = SubElement(a, 'c')
3874 d = SubElement(c, 'd')
3875 self.assertTrue(isinstance(tounicode(b), _unicode))
3876 self.assertTrue(isinstance(tounicode(c), _unicode))
3877 self.assertEqual(_bytes('<b></b>'),
3878 canonicalize(tounicode(b)))
3879 self.assertEqual(_bytes('<c><d></d></c>'),
3880 canonicalize(tounicode(c)))
3881
3885
3887 tounicode = self.etree.tounicode
3888 Element = self.etree.Element
3889 SubElement = self.etree.SubElement
3890
3891 a = Element('a')
3892 b = SubElement(a, 'b')
3893 c = SubElement(a, 'c')
3894 d = SubElement(c, 'd')
3895 b.tail = 'Foo'
3896
3897 self.assertTrue(isinstance(tounicode(b), _unicode))
3898 self.assertTrue(tounicode(b) == '<b/>Foo' or
3899 tounicode(b) == '<b />Foo')
3900
3902 tounicode = self.etree.tounicode
3903 Element = self.etree.Element
3904 SubElement = self.etree.SubElement
3905
3906 a = Element('a')
3907 b = SubElement(a, 'b')
3908 c = SubElement(a, 'c')
3909
3910 result = tounicode(a)
3911 self.assertEqual(result, "<a><b/><c/></a>")
3912
3913 result = tounicode(a, pretty_print=False)
3914 self.assertEqual(result, "<a><b/><c/></a>")
3915
3916 result = tounicode(a, pretty_print=True)
3917 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
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
3928 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode))
3929 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3930 canonicalize(tostring(a, encoding=_unicode)))
3931
3933 tostring = self.etree.tostring
3934 Element = self.etree.Element
3935 SubElement = self.etree.SubElement
3936
3937 a = Element('a')
3938 b = SubElement(a, 'b')
3939 c = SubElement(a, 'c')
3940 d = SubElement(c, 'd')
3941 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3942 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3943 self.assertEqual(_bytes('<b></b>'),
3944 canonicalize(tostring(b, encoding=_unicode)))
3945 self.assertEqual(_bytes('<c><d></d></c>'),
3946 canonicalize(tostring(c, encoding=_unicode)))
3947
3949 tostring = self.etree.tostring
3950 self.assertRaises(TypeError, self.etree.tostring,
3951 None, encoding=_unicode)
3952
3954 tostring = self.etree.tostring
3955 Element = self.etree.Element
3956 SubElement = self.etree.SubElement
3957
3958 a = Element('a')
3959 b = SubElement(a, 'b')
3960 c = SubElement(a, 'c')
3961 d = SubElement(c, 'd')
3962 b.tail = 'Foo'
3963
3964 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3965 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or
3966 tostring(b, encoding=_unicode) == '<b />Foo')
3967
3969 tostring = self.etree.tostring
3970 Element = self.etree.Element
3971 SubElement = self.etree.SubElement
3972
3973 a = Element('a')
3974 b = SubElement(a, 'b')
3975 c = SubElement(a, 'c')
3976
3977 result = tostring(a, encoding=_unicode)
3978 self.assertEqual(result, "<a><b/><c/></a>")
3979
3980 result = tostring(a, encoding=_unicode, pretty_print=False)
3981 self.assertEqual(result, "<a><b/><c/></a>")
3982
3983 result = tostring(a, encoding=_unicode, pretty_print=True)
3984 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3985
3987 root = etree.Element('parent')
3988 etree.SubElement(root, 'child')
3989
3990 self.assertEqual(len(root), 1)
3991 self.assertEqual(root[0].tag, 'child')
3992
3993 # in PyPy, GC used to kill the Python proxy instance without cleanup
3994 gc.collect()
3995 self.assertEqual(len(root), 1)
3996 self.assertEqual(root[0].tag, 'child')
3997
4001
4002 el1 = SubEl()
4003 el2 = SubEl()
4004 self.assertEqual('SubEl', el1.tag)
4005 self.assertEqual('SubEl', el2.tag)
4006 el1.other = el2
4007 el2.other = el1
4008
4009 del el1, el2
4010 gc.collect()
4011 # not really testing anything here, but it shouldn't crash
4012
4014 root = etree.Element('parent')
4015 c1 = etree.SubElement(root, 'child1')
4016 c2 = etree.SubElement(root, 'child2')
4017
4018 root.remove(c1)
4019 root.remove(c2)
4020 c1.addnext(c2)
4021 del c1
4022 # trigger deallocation attempt of c1
4023 c2.getprevious()
4024 # make sure it wasn't deallocated
4025 self.assertEqual('child1', c2.getprevious().tag)
4026
4028 root = etree.Element('parent')
4029 c1 = etree.SubElement(root, 'child1')
4030 c2 = etree.SubElement(root, 'child2')
4031
4032 root.remove(c1)
4033 root.remove(c2)
4034 c1.addnext(c2)
4035 c1.tail = 'abc'
4036 c2.tail = 'xyz'
4037 del c1
4038 # trigger deallocation attempt of c1
4039 c2.getprevious()
4040 # make sure it wasn't deallocated
4041 self.assertEqual('child1', c2.getprevious().tag)
4042 self.assertEqual('abc', c2.getprevious().tail)
4043
4044 # helper methods
4045
4047 """Write out element for comparison.
4048 """
4049 ElementTree = self.etree.ElementTree
4050 f = BytesIO()
4051 tree = ElementTree(element=element)
4052 tree.write(f, encoding=encoding, compression=compression)
4053 data = f.getvalue()
4054 if compression:
4055 data = zlib.decompress(data)
4056 return canonicalize(data)
4057
4061 filename = fileInTestDir('test_broken.xml')
4062 root = etree.XML(_bytes('''\
4063 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
4064 <xi:include href="%s" parse="text"/>
4065 </doc>
4066 ''' % path2url(filename)))
4067 old_text = root.text
4068 content = read_file(filename)
4069 old_tail = root[0].tail
4070
4071 self.include( etree.ElementTree(root) )
4072 self.assertEqual(old_text + content + old_tail,
4073 root.text)
4074
4076 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
4077 self.assertNotEqual(
4078 'a',
4079 tree.getroot()[1].tag)
4080 # process xincludes
4081 self.include( tree )
4082 # check whether we find it replaced with included data
4083 self.assertEqual(
4084 'a',
4085 tree.getroot()[1].tag)
4086
4088 class res(etree.Resolver):
4089 include_text = read_file(fileInTestDir('test.xml'))
4090 called = {}
4091 def resolve(self, url, id, context):
4092 if url.endswith(".dtd"):
4093 self.called["dtd"] = True
4094 return self.resolve_filename(
4095 fileInTestDir('test.dtd'), context)
4096 elif url.endswith("test_xinclude.xml"):
4097 self.called["input"] = True
4098 return None # delegate to default resolver
4099 else:
4100 self.called["include"] = True
4101 return self.resolve_string(self.include_text, context)
4102
4103 res_instance = res()
4104 parser = etree.XMLParser(load_dtd = True)
4105 parser.resolvers.add(res_instance)
4106
4107 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
4108 parser = parser)
4109
4110 self.include(tree)
4111
4112 called = list(res_instance.called.items())
4113 called.sort()
4114 self.assertEqual(
4115 [("dtd", True), ("include", True), ("input", True)],
4116 called)
4117
4119 data = textwrap.dedent('''
4120 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
4121 <foo/>
4122 <xi:include href="./test.xml" />
4123 </doc>
4124 ''')
4125
4126 class Resolver(etree.Resolver):
4127 called = {}
4128
4129 def resolve(self, url, id, context):
4130 if url.endswith("test_xinclude.xml"):
4131 assert not self.called.get("input")
4132 self.called["input"] = True
4133 return None # delegate to default resolver
4134 elif url.endswith('/test5.xml'):
4135 assert not self.called.get("DONE")
4136 self.called["DONE"] = True
4137 return self.resolve_string('<DONE/>', context)
4138 else:
4139 _, filename = url.rsplit('/', 1)
4140 assert not self.called.get(filename)
4141 self.called[filename] = True
4142 next_data = data.replace(
4143 'test.xml', 'test%d.xml' % len(self.called))
4144 return self.resolve_string(next_data, context)
4145
4146 res_instance = Resolver()
4147 parser = etree.XMLParser(load_dtd=True)
4148 parser.resolvers.add(res_instance)
4149
4150 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
4151 parser=parser)
4152
4153 self.include(tree)
4154
4155 called = list(res_instance.called.items())
4156 called.sort()
4157 self.assertEqual(
4158 [("DONE", True), ("input", True), ("test.xml", True),
4159 ("test2.xml", True), ("test3.xml", True), ("test4.xml", True)],
4160 called)
4161
4166
4172
4176 tree = self.parse(_bytes('<a><b/></a>'))
4177 f = BytesIO()
4178 tree.write_c14n(f)
4179 s = f.getvalue()
4180 self.assertEqual(_bytes('<a><b></b></a>'),
4181 s)
4182
4184 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4185 f = BytesIO()
4186 tree.write_c14n(f, compression=9)
4187 with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile:
4188 s = gzfile.read()
4189 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
4190 s)
4191
4193 tree = self.parse(_bytes('<a><b/></a>'))
4194 with tmpfile() as filename:
4195 tree.write_c14n(filename)
4196 data = read_file(filename, 'rb')
4197 self.assertEqual(_bytes('<a><b></b></a>'),
4198 data)
4199
4201 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4202 with tmpfile() as filename:
4203 tree.write_c14n(filename, compression=9)
4204 with closing(gzip.open(filename, 'rb')) as f:
4205 data = f.read()
4206 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
4207 data)
4208
4210 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
4211 f = BytesIO()
4212 tree.write_c14n(f)
4213 s = f.getvalue()
4214 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
4215 s)
4216 f = BytesIO()
4217 tree.write_c14n(f, with_comments=True)
4218 s = f.getvalue()
4219 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
4220 s)
4221 f = BytesIO()
4222 tree.write_c14n(f, with_comments=False)
4223 s = f.getvalue()
4224 self.assertEqual(_bytes('<a><b></b></a>'),
4225 s)
4226
4228 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
4229 s = etree.tostring(tree, method='c14n')
4230 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
4231 s)
4232 s = etree.tostring(tree, method='c14n', with_comments=True)
4233 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
4234 s)
4235 s = etree.tostring(tree, method='c14n', with_comments=False)
4236 self.assertEqual(_bytes('<a><b></b></a>'),
4237 s)
4238
4240 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
4241 s = etree.tostring(tree.getroot(), method='c14n')
4242 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
4243 s)
4244 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
4245 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
4246 s)
4247 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
4248 self.assertEqual(_bytes('<a><b></b></a>'),
4249 s)
4250
4252 tree = self.parse(_bytes(
4253 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4254 f = BytesIO()
4255 tree.write_c14n(f)
4256 s = f.getvalue()
4257 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4258 s)
4259 f = BytesIO()
4260 tree.write_c14n(f, exclusive=False)
4261 s = f.getvalue()
4262 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4263 s)
4264 f = BytesIO()
4265 tree.write_c14n(f, exclusive=True)
4266 s = f.getvalue()
4267 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4268 s)
4269
4270 f = BytesIO()
4271 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
4272 s = f.getvalue()
4273 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
4274 s)
4275
4277 tree = self.parse(_bytes(
4278 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4279 s = etree.tostring(tree, method='c14n')
4280 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4281 s)
4282 s = etree.tostring(tree, method='c14n', exclusive=False)
4283 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4284 s)
4285 s = etree.tostring(tree, method='c14n', exclusive=True)
4286 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4287 s)
4288
4289 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
4290 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
4291 s)
4292
4294 tree = self.parse(_bytes(
4295 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4296 s = etree.tostring(tree.getroot(), method='c14n')
4297 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4298 s)
4299 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
4300 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4301 s)
4302 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
4303 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4304 s)
4305
4306 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
4307 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
4308 s)
4309 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
4310 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
4311 s)
4312
4313 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
4314 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
4315 s)
4316
4318 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
4319 tree = self.parse(_bytes(
4320 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4321
4322 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
4323 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4324 s)
4325
4329 tree = self.parse(_bytes('<a><b/></a>'))
4330 f = BytesIO()
4331 tree.write(f)
4332 s = f.getvalue()
4333 self.assertEqual(_bytes('<a><b/></a>'),
4334 s)
4335
4337 tree = self.parse(_bytes('<a><b/></a>'))
4338 f = BytesIO()
4339 tree.write(f, doctype='HUHU')
4340 s = f.getvalue()
4341 self.assertEqual(_bytes('HUHU\n<a><b/></a>'),
4342 s)
4343
4345 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4346 f = BytesIO()
4347 tree.write(f, compression=9)
4348 with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile:
4349 s = gzfile.read()
4350 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4351 s)
4352
4354 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4355 f = BytesIO()
4356 tree.write(f, compression=9, doctype='<!DOCTYPE a>')
4357 with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile:
4358 s = gzfile.read()
4359 self.assertEqual(_bytes('<!DOCTYPE a>\n<a>'+'<b/>'*200+'</a>'),
4360 s)
4361
4363 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4364 f = BytesIO()
4365 tree.write(f, compression=0)
4366 s0 = f.getvalue()
4367
4368 f = BytesIO()
4369 tree.write(f)
4370 self.assertEqual(f.getvalue(), s0)
4371
4372 f = BytesIO()
4373 tree.write(f, compression=1)
4374 s = f.getvalue()
4375 self.assertTrue(len(s) <= len(s0))
4376 with closing(gzip.GzipFile(fileobj=BytesIO(s))) as gzfile:
4377 s1 = gzfile.read()
4378
4379 f = BytesIO()
4380 tree.write(f, compression=9)
4381 s = f.getvalue()
4382 self.assertTrue(len(s) <= len(s0))
4383 with closing(gzip.GzipFile(fileobj=BytesIO(s))) as gzfile:
4384 s9 = gzfile.read()
4385
4386 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4387 s0)
4388 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4389 s1)
4390 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4391 s9)
4392
4394 tree = self.parse(_bytes('<a><b/></a>'))
4395 with tmpfile() as filename:
4396 tree.write(filename)
4397 data = read_file(filename, 'rb')
4398 self.assertEqual(_bytes('<a><b/></a>'),
4399 data)
4400
4402 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4403 with tmpfile() as filename:
4404 tree.write(filename, compression=9)
4405 with closing(gzip.open(filename, 'rb')) as f:
4406 data = f.read()
4407 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4408 data)
4409
4411 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4412 with tmpfile() as filename:
4413 tree.write(filename, compression=9)
4414 data = etree.tostring(etree.parse(filename))
4415 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4416 data)
4417
4426
4429 etree = etree
4430
4432 parse = self.etree.parse
4433 f = BytesIO('<a><b></c></b></a>')
4434 self.etree.clear_error_log()
4435 try:
4436 parse(f)
4437 logs = None
4438 except SyntaxError:
4439 e = sys.exc_info()[1]
4440 logs = e.error_log
4441 f.close()
4442 self.assertTrue([ log for log in logs
4443 if 'mismatch' in log.message ])
4444 self.assertTrue([ log for log in logs
4445 if 'PARSER' in log.domain_name])
4446 self.assertTrue([ log for log in logs
4447 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
4448 self.assertTrue([ log for log in logs
4449 if 1 == log.line ])
4450 self.assertTrue([ log for log in logs
4451 if 15 == log.column ])
4452
4463
4464 self.etree.use_global_python_log(Logger())
4465 f = BytesIO('<a><b></c></b></a>')
4466 try:
4467 parse(f)
4468 except SyntaxError:
4469 pass
4470 f.close()
4471
4472 self.assertTrue([ message for message in messages
4473 if 'mismatch' in message ])
4474 self.assertTrue([ message for message in messages
4475 if ':PARSER:' in message])
4476 self.assertTrue([ message for message in messages
4477 if ':ERR_TAG_NAME_MISMATCH:' in message ])
4478 self.assertTrue([ message for message in messages
4479 if ':1:15:' in message ])
4480
4495 def close(self):
4496 return 'close()'
4497
4498 parser = self.etree.XMLPullParser(target=Target())
4499 events = parser.read_events()
4500
4501 parser.feed('<root><element>')
4502 self.assertFalse(list(events))
4503 self.assertFalse(list(events))
4504 parser.feed('</element><child>')
4505 self.assertEqual([('end', 'end(element)')], list(events))
4506 parser.feed('</child>')
4507 self.assertEqual([('end', 'end(child)')], list(events))
4508 parser.feed('</root>')
4509 self.assertEqual([('end', 'end(root)')], list(events))
4510 self.assertFalse(list(events))
4511 self.assertEqual('close()', parser.close())
4512
4517 def end(self, tag):
4518 return 'end(%s)' % tag
4519 def close(self):
4520 return 'close()'
4521
4522 parser = self.etree.XMLPullParser(
4523 ['start', 'end'], target=Target())
4524 events = parser.read_events()
4525
4526 parser.feed('<root><element>')
4527 self.assertEqual(
4528 [('start', 'start(root)'), ('start', 'start(element)')],
4529 list(events))
4530 self.assertFalse(list(events))
4531 parser.feed('</element><child>')
4532 self.assertEqual(
4533 [('end', 'end(element)'), ('start', 'start(child)')],
4534 list(events))
4535 parser.feed('</child>')
4536 self.assertEqual(
4537 [('end', 'end(child)')],
4538 list(events))
4539 parser.feed('</root>')
4540 self.assertEqual(
4541 [('end', 'end(root)')],
4542 list(events))
4543 self.assertFalse(list(events))
4544 self.assertEqual('close()', parser.close())
4545
4547 parser = self.etree.XMLPullParser(
4548 ['start', 'end'], target=etree.TreeBuilder())
4549 events = parser.read_events()
4550
4551 parser.feed('<root><element>')
4552 self.assert_event_tags(
4553 events, [('start', 'root'), ('start', 'element')])
4554 self.assertFalse(list(events))
4555 parser.feed('</element><child>')
4556 self.assert_event_tags(
4557 events, [('end', 'element'), ('start', 'child')])
4558 parser.feed('</child>')
4559 self.assert_event_tags(
4560 events, [('end', 'child')])
4561 parser.feed('</root>')
4562 self.assert_event_tags(
4563 events, [('end', 'root')])
4564 self.assertFalse(list(events))
4565 root = parser.close()
4566 self.assertEqual('root', root.tag)
4567
4569 class Target(etree.TreeBuilder):
4570 def end(self, tag):
4571 el = super(Target, self).end(tag)
4572 el.tag += '-huhu'
4573 return el
4574
4575 parser = self.etree.XMLPullParser(
4576 ['start', 'end'], target=Target())
4577 events = parser.read_events()
4578
4579 parser.feed('<root><element>')
4580 self.assert_event_tags(
4581 events, [('start', 'root'), ('start', 'element')])
4582 self.assertFalse(list(events))
4583 parser.feed('</element><child>')
4584 self.assert_event_tags(
4585 events, [('end', 'element-huhu'), ('start', 'child')])
4586 parser.feed('</child>')
4587 self.assert_event_tags(
4588 events, [('end', 'child-huhu')])
4589 parser.feed('</root>')
4590 self.assert_event_tags(
4591 events, [('end', 'root-huhu')])
4592 self.assertFalse(list(events))
4593 root = parser.close()
4594 self.assertEqual('root-huhu', root.tag)
4595
4598 suite = unittest.TestSuite()
4599 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
4600 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
4601 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
4602 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
4603 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
4604 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
4605 suite.addTests([unittest.makeSuite(XMLPullParserTest)])
4606
4607 # add original doctests from ElementTree selftest modules
4608 from . import selftest, selftest2
4609 suite.addTests(doctest.DocTestSuite(selftest))
4610 suite.addTests(doctest.DocTestSuite(selftest2))
4611
4612 # add doctests
4613 suite.addTests(doctest.DocTestSuite(etree))
4614 suite.addTests(
4615 [make_doctest('../../../doc/tutorial.txt')])
4616 if sys.version_info >= (2,6):
4617 # now requires the 'with' statement
4618 suite.addTests(
4619 [make_doctest('../../../doc/api.txt')])
4620 suite.addTests(
4621 [make_doctest('../../../doc/FAQ.txt')])
4622 suite.addTests(
4623 [make_doctest('../../../doc/parsing.txt')])
4624 suite.addTests(
4625 [make_doctest('../../../doc/resolvers.txt')])
4626 return suite
4627
4628
4629 if __name__ == '__main__':
4630 print('to test use test.py %s' % __file__)
4631
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Wed Mar 21 20:38:29 2018 | http://epydoc.sourceforge.net |