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