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