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