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