| 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 SubElement = self.etree.SubElement
1449 tostring = self.etree.tostring
1450
1451 root = Element("root")
1452 child = SubElement(root, 'child')
1453 child.tail = CDATA('test')
1454
1455 self.assertEqual('test', child.tail)
1456 self.assertEqual(_bytes('<root><child/><![CDATA[test]]></root>'),
1457 tostring(root))
1458
1459 root = Element("root")
1460 root.tail = CDATA('test')
1461
1462 self.assertEqual('test', root.tail)
1463 self.assertEqual(_bytes('<root/><![CDATA[test]]>'),
1464 tostring(root))
1465
1467 CDATA = self.etree.CDATA
1468 Element = self.etree.Element
1469 root = Element("root")
1470
1471 root.text = CDATA("test")
1472 self.assertEqual('test', root.text)
1473
1474 root.text = CDATA(_str("test"))
1475 self.assertEqual('test', root.text)
1476
1477 self.assertRaises(TypeError, CDATA, 1)
1478
1480 CDATA = self.etree.CDATA
1481 Element = self.etree.Element
1482
1483 root = Element("root")
1484 cdata = CDATA('test')
1485
1486 self.assertRaises(TypeError,
1487 root.set, 'attr', cdata)
1488 self.assertRaises(TypeError,
1489 operator.setitem, root.attrib, 'attr', cdata)
1490
1492 tostring = self.etree.tostring
1493 parser = self.etree.XMLParser(strip_cdata=False)
1494 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1495
1496 self.assertEqual('test', root.text)
1497 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1498 tostring(root))
1499
1501 tostring = self.etree.tostring
1502 parser = self.etree.XMLParser(strip_cdata=False)
1503 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1504 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1505 tostring(root))
1506
1507 self.assertEqual(['test'], root.xpath('//text()'))
1508
1509 # TypeError in etree, AssertionError in ElementTree;
1511 Element = self.etree.Element
1512 SubElement = self.etree.SubElement
1513
1514 a = Element('a')
1515 b = SubElement(a, 'b')
1516
1517 self.assertRaises(TypeError,
1518 a.__setitem__, 0, 'foo')
1519
1521 Element = self.etree.Element
1522 root = Element('root')
1523 # raises AssertionError in ElementTree
1524 self.assertRaises(TypeError, root.append, None)
1525 self.assertRaises(TypeError, root.extend, [None])
1526 self.assertRaises(TypeError, root.extend, [Element('one'), None])
1527 self.assertEqual('one', root[0].tag)
1528
1530 Element = self.etree.Element
1531 SubElement = self.etree.SubElement
1532 root = Element('root')
1533 self.assertRaises(ValueError, root.append, root)
1534 child = SubElement(root, 'child')
1535 self.assertRaises(ValueError, child.append, root)
1536 child2 = SubElement(child, 'child2')
1537 self.assertRaises(ValueError, child2.append, root)
1538 self.assertRaises(ValueError, child2.append, child)
1539 self.assertEqual('child2', root[0][0].tag)
1540
1542 Element = self.etree.Element
1543 SubElement = self.etree.SubElement
1544 root = Element('root')
1545 SubElement(root, 'a')
1546 SubElement(root, 'b')
1547
1548 self.assertEqual(['a', 'b'],
1549 [c.tag for c in root])
1550 root[1].addnext(root[0])
1551 self.assertEqual(['b', 'a'],
1552 [c.tag for c in root])
1553
1555 Element = self.etree.Element
1556 SubElement = self.etree.SubElement
1557 root = Element('root')
1558 SubElement(root, 'a')
1559 SubElement(root, 'b')
1560
1561 self.assertEqual(['a', 'b'],
1562 [c.tag for c in root])
1563 root[0].addprevious(root[1])
1564 self.assertEqual(['b', 'a'],
1565 [c.tag for c in root])
1566
1568 Element = self.etree.Element
1569 SubElement = self.etree.SubElement
1570 root = Element('root')
1571 a = SubElement(root, 'a')
1572 b = SubElement(a, 'b')
1573 # appending parent as sibling is forbidden
1574 self.assertRaises(ValueError, b.addnext, a)
1575 self.assertEqual(['a'], [c.tag for c in root])
1576 self.assertEqual(['b'], [c.tag for c in a])
1577
1579 Element = self.etree.Element
1580 SubElement = self.etree.SubElement
1581 root = Element('root')
1582 a = SubElement(root, 'a')
1583 b = SubElement(a, 'b')
1584 # appending parent as sibling is forbidden
1585 self.assertRaises(ValueError, b.addprevious, a)
1586 self.assertEqual(['a'], [c.tag for c in root])
1587 self.assertEqual(['b'], [c.tag for c in a])
1588
1590 Element = self.etree.Element
1591 SubElement = self.etree.SubElement
1592 root = Element('root')
1593 a = SubElement(root, 'a')
1594 b = SubElement(a, 'b')
1595 c = SubElement(b, 'c')
1596 # appending parent as sibling is forbidden
1597 self.assertRaises(ValueError, c.addnext, a)
1598
1600 Element = self.etree.Element
1601 SubElement = self.etree.SubElement
1602 root = Element('root')
1603 a = SubElement(root, 'a')
1604 b = SubElement(a, 'b')
1605 c = SubElement(b, 'c')
1606 # appending parent as sibling is forbidden
1607 self.assertRaises(ValueError, c.addprevious, a)
1608
1610 Element = self.etree.Element
1611 SubElement = self.etree.SubElement
1612 root = Element('root')
1613 a = SubElement(root, 'a')
1614 b = SubElement(root, 'b')
1615 a.addprevious(a)
1616 self.assertEqual('a', root[0].tag)
1617 self.assertEqual('b', root[1].tag)
1618 b.addprevious(b)
1619 self.assertEqual('a', root[0].tag)
1620 self.assertEqual('b', root[1].tag)
1621 b.addprevious(a)
1622 self.assertEqual('a', root[0].tag)
1623 self.assertEqual('b', root[1].tag)
1624
1626 Element = self.etree.Element
1627 SubElement = self.etree.SubElement
1628 root = Element('root')
1629 a = SubElement(root, 'a')
1630 b = SubElement(root, 'b')
1631 a.addnext(a)
1632 self.assertEqual('a', root[0].tag)
1633 self.assertEqual('b', root[1].tag)
1634 b.addnext(b)
1635 self.assertEqual('a', root[0].tag)
1636 self.assertEqual('b', root[1].tag)
1637 a.addnext(b)
1638 self.assertEqual('a', root[0].tag)
1639 self.assertEqual('b', root[1].tag)
1640
1642 Element = self.etree.Element
1643 a = Element('a')
1644 b = Element('b')
1645 self.assertRaises(TypeError, a.addnext, b)
1646
1648 Element = self.etree.Element
1649 SubElement = self.etree.SubElement
1650 PI = self.etree.PI
1651 root = Element('root')
1652 SubElement(root, 'a')
1653 pi = PI('TARGET', 'TEXT')
1654 pi.tail = "TAIL"
1655
1656 self.assertEqual(_bytes('<root><a></a></root>'),
1657 self._writeElement(root))
1658 root[0].addprevious(pi)
1659 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
1660 self._writeElement(root))
1661
1663 Element = self.etree.Element
1664 PI = self.etree.PI
1665 root = Element('root')
1666 pi = PI('TARGET', 'TEXT')
1667 pi.tail = "TAIL"
1668
1669 self.assertEqual(_bytes('<root></root>'),
1670 self._writeElement(root))
1671 root.addprevious(pi)
1672 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'),
1673 self._writeElement(root))
1674
1676 Element = self.etree.Element
1677 SubElement = self.etree.SubElement
1678 PI = self.etree.PI
1679 root = Element('root')
1680 SubElement(root, 'a')
1681 pi = PI('TARGET', 'TEXT')
1682 pi.tail = "TAIL"
1683
1684 self.assertEqual(_bytes('<root><a></a></root>'),
1685 self._writeElement(root))
1686 root[0].addnext(pi)
1687 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
1688 self._writeElement(root))
1689
1691 Element = self.etree.Element
1692 PI = self.etree.PI
1693 root = Element('root')
1694 pi = PI('TARGET', 'TEXT')
1695 pi.tail = "TAIL"
1696
1697 self.assertEqual(_bytes('<root></root>'),
1698 self._writeElement(root))
1699 root.addnext(pi)
1700 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'),
1701 self._writeElement(root))
1702
1704 Element = self.etree.Element
1705 SubElement = self.etree.SubElement
1706 Comment = self.etree.Comment
1707 root = Element('root')
1708 SubElement(root, 'a')
1709 comment = Comment('TEXT ')
1710 comment.tail = "TAIL"
1711
1712 self.assertEqual(_bytes('<root><a></a></root>'),
1713 self._writeElement(root))
1714 root[0].addnext(comment)
1715 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
1716 self._writeElement(root))
1717
1719 Element = self.etree.Element
1720 Comment = self.etree.Comment
1721 root = Element('root')
1722 comment = Comment('TEXT ')
1723 comment.tail = "TAIL"
1724
1725 self.assertEqual(_bytes('<root></root>'),
1726 self._writeElement(root))
1727 root.addnext(comment)
1728 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'),
1729 self._writeElement(root))
1730
1732 Element = self.etree.Element
1733 SubElement = self.etree.SubElement
1734 Comment = self.etree.Comment
1735 root = Element('root')
1736 SubElement(root, 'a')
1737 comment = Comment('TEXT ')
1738 comment.tail = "TAIL"
1739
1740 self.assertEqual(_bytes('<root><a></a></root>'),
1741 self._writeElement(root))
1742 root[0].addprevious(comment)
1743 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
1744 self._writeElement(root))
1745
1747 Element = self.etree.Element
1748 Comment = self.etree.Comment
1749 root = Element('root')
1750 comment = Comment('TEXT ')
1751 comment.tail = "TAIL"
1752
1753 self.assertEqual(_bytes('<root></root>'),
1754 self._writeElement(root))
1755 root.addprevious(comment)
1756 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'),
1757 self._writeElement(root))
1758
1759 # ET's Elements have items() and key(), but not values()
1761 XML = self.etree.XML
1762
1763 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
1764 values = root.values()
1765 values.sort()
1766 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1767
1768 # gives error in ElementTree
1770 Element = self.etree.Element
1771 Comment = self.etree.Comment
1772
1773 a = Element('a')
1774 a.append(Comment())
1775 self.assertEqual(
1776 _bytes('<a><!----></a>'),
1777 self._writeElement(a))
1778
1779 # ElementTree ignores comments
1781 ElementTree = self.etree.ElementTree
1782 tostring = self.etree.tostring
1783
1784 xml = _bytes('<a><b/><!----><c/></a>')
1785 f = BytesIO(xml)
1786 doc = ElementTree(file=f)
1787 a = doc.getroot()
1788 self.assertEqual(
1789 '',
1790 a[1].text)
1791 self.assertEqual(
1792 xml,
1793 tostring(a))
1794
1795 # ElementTree ignores comments
1797 ElementTree = self.etree.ElementTree
1798
1799 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
1800 doc = ElementTree(file=f)
1801 a = doc.getroot()
1802 self.assertEqual(
1803 ' hoi ',
1804 a[1].text)
1805
1806 # does not raise an exception in ElementTree
1808 Element = self.etree.Element
1809 Comment = self.etree.Comment
1810
1811 c = Comment()
1812 el = Element('myel')
1813
1814 self.assertRaises(TypeError, c.append, el)
1815 self.assertRaises(TypeError, c.insert, 0, el)
1816 self.assertRaises(TypeError, c.set, "myattr", "test")
1817
1819 c = self.etree.Comment()
1820 self.assertEqual(0, len(c.attrib))
1821
1822 self.assertFalse(c.attrib.__contains__('nope'))
1823 self.assertFalse('nope' in c.attrib)
1824 self.assertFalse('nope' in c.attrib.keys())
1825 self.assertFalse('nope' in c.attrib.values())
1826 self.assertFalse(('nope', 'huhu') in c.attrib.items())
1827
1828 self.assertEqual([], list(c.attrib))
1829 self.assertEqual([], list(c.attrib.keys()))
1830 self.assertEqual([], list(c.attrib.items()))
1831 self.assertEqual([], list(c.attrib.values()))
1832 self.assertEqual([], list(c.attrib.iterkeys()))
1833 self.assertEqual([], list(c.attrib.iteritems()))
1834 self.assertEqual([], list(c.attrib.itervalues()))
1835
1836 self.assertEqual('HUHU', c.attrib.pop('nope', 'HUHU'))
1837 self.assertRaises(KeyError, c.attrib.pop, 'nope')
1838
1839 self.assertRaises(KeyError, c.attrib.__getitem__, 'only')
1840 self.assertRaises(KeyError, c.attrib.__getitem__, 'names')
1841 self.assertRaises(KeyError, c.attrib.__getitem__, 'nope')
1842 self.assertRaises(KeyError, c.attrib.__setitem__, 'nope', 'yep')
1843 self.assertRaises(KeyError, c.attrib.__delitem__, 'nope')
1844
1845 # test passing 'None' to dump()
1848
1850 ElementTree = self.etree.ElementTree
1851
1852 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
1853 doc = ElementTree(file=f)
1854 a = doc.getroot()
1855 self.assertEqual(
1856 None,
1857 a.prefix)
1858 self.assertEqual(
1859 'foo',
1860 a[0].prefix)
1861
1863 ElementTree = self.etree.ElementTree
1864
1865 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
1866 doc = ElementTree(file=f)
1867 a = doc.getroot()
1868 self.assertEqual(
1869 None,
1870 a.prefix)
1871 self.assertEqual(
1872 None,
1873 a[0].prefix)
1874
1876 Element = self.etree.Element
1877 SubElement = self.etree.SubElement
1878
1879 a = Element('a')
1880 b = SubElement(a, 'b')
1881 c = SubElement(a, 'c')
1882 d = SubElement(b, 'd')
1883 self.assertEqual(
1884 None,
1885 a.getparent())
1886 self.assertEqual(
1887 a,
1888 b.getparent())
1889 self.assertEqual(
1890 b.getparent(),
1891 c.getparent())
1892 self.assertEqual(
1893 b,
1894 d.getparent())
1895
1897 XML = self.etree.XML
1898
1899 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
1900 result = []
1901 for el in root.iterchildren():
1902 result.append(el.tag)
1903 self.assertEqual(['one', 'two', 'three'], result)
1904
1906 XML = self.etree.XML
1907
1908 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
1909 result = []
1910 for el in root.iterchildren(reversed=True):
1911 result.append(el.tag)
1912 self.assertEqual(['three', 'two', 'one'], result)
1913
1915 XML = self.etree.XML
1916
1917 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1918 result = []
1919 for el in root.iterchildren(tag='two'):
1920 result.append(el.text)
1921 self.assertEqual(['Two', 'Bla'], result)
1922
1924 XML = self.etree.XML
1925
1926 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1927 result = []
1928 for el in root.iterchildren('two'):
1929 result.append(el.text)
1930 self.assertEqual(['Two', 'Bla'], result)
1931
1933 XML = self.etree.XML
1934
1935 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1936 result = []
1937 for el in root.iterchildren(reversed=True, tag='two'):
1938 result.append(el.text)
1939 self.assertEqual(['Bla', 'Two'], result)
1940
1942 XML = self.etree.XML
1943
1944 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1945 result = []
1946 for el in root.iterchildren(tag=['two', 'three']):
1947 result.append(el.text)
1948 self.assertEqual(['Two', 'Bla', None], result)
1949
1951 XML = self.etree.XML
1952
1953 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1954 result = []
1955 for el in root.iterchildren('two', 'three'):
1956 result.append(el.text)
1957 self.assertEqual(['Two', 'Bla', None], result)
1958
1960 XML = self.etree.XML
1961
1962 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1963 result = []
1964 for el in root.iterchildren(reversed=True, tag=['two', 'three']):
1965 result.append(el.text)
1966 self.assertEqual([None, 'Bla', 'Two'], result)
1967
1969 Element = self.etree.Element
1970 SubElement = self.etree.SubElement
1971
1972 a = Element('a')
1973 b = SubElement(a, 'b')
1974 c = SubElement(a, 'c')
1975 d = SubElement(b, 'd')
1976 self.assertEqual(
1977 [],
1978 list(a.iterancestors()))
1979 self.assertEqual(
1980 [a],
1981 list(b.iterancestors()))
1982 self.assertEqual(
1983 [a],
1984 list(c.iterancestors()))
1985 self.assertEqual(
1986 [b, a],
1987 list(d.iterancestors()))
1988
1990 Element = self.etree.Element
1991 SubElement = self.etree.SubElement
1992
1993 a = Element('a')
1994 b = SubElement(a, 'b')
1995 c = SubElement(a, 'c')
1996 d = SubElement(b, 'd')
1997 self.assertEqual(
1998 [a],
1999 list(d.iterancestors('a')))
2000 self.assertEqual(
2001 [a],
2002 list(d.iterancestors(tag='a')))
2003
2004 self.assertEqual(
2005 [b, a],
2006 list(d.iterancestors('*')))
2007 self.assertEqual(
2008 [b, a],
2009 list(d.iterancestors(tag='*')))
2010
2012 Element = self.etree.Element
2013 SubElement = self.etree.SubElement
2014
2015 a = Element('a')
2016 b = SubElement(a, 'b')
2017 c = SubElement(a, 'c')
2018 d = SubElement(b, 'd')
2019 self.assertEqual(
2020 [b, a],
2021 list(d.iterancestors(tag=('a', 'b'))))
2022 self.assertEqual(
2023 [b, a],
2024 list(d.iterancestors('a', 'b')))
2025
2026 self.assertEqual(
2027 [],
2028 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
2029 self.assertEqual(
2030 [],
2031 list(d.iterancestors('w', 'x', 'y', 'z')))
2032
2033 self.assertEqual(
2034 [],
2035 list(d.iterancestors(tag=('d', 'x'))))
2036 self.assertEqual(
2037 [],
2038 list(d.iterancestors('d', 'x')))
2039
2040 self.assertEqual(
2041 [b, a],
2042 list(d.iterancestors(tag=('b', '*'))))
2043 self.assertEqual(
2044 [b, a],
2045 list(d.iterancestors('b', '*')))
2046
2047 self.assertEqual(
2048 [b],
2049 list(d.iterancestors(tag=('b', 'c'))))
2050 self.assertEqual(
2051 [b],
2052 list(d.iterancestors('b', 'c')))
2053
2055 Element = self.etree.Element
2056 SubElement = self.etree.SubElement
2057
2058 a = Element('a')
2059 b = SubElement(a, 'b')
2060 c = SubElement(a, 'c')
2061 d = SubElement(b, 'd')
2062 e = SubElement(c, 'e')
2063
2064 self.assertEqual(
2065 [b, d, c, e],
2066 list(a.iterdescendants()))
2067 self.assertEqual(
2068 [],
2069 list(d.iterdescendants()))
2070
2072 Element = self.etree.Element
2073 SubElement = self.etree.SubElement
2074
2075 a = Element('a')
2076 b = SubElement(a, 'b')
2077 c = SubElement(a, 'c')
2078 d = SubElement(b, 'd')
2079 e = SubElement(c, 'e')
2080
2081 self.assertEqual(
2082 [],
2083 list(a.iterdescendants('a')))
2084 self.assertEqual(
2085 [],
2086 list(a.iterdescendants(tag='a')))
2087
2088 a2 = SubElement(e, 'a')
2089 self.assertEqual(
2090 [a2],
2091 list(a.iterdescendants('a')))
2092
2093 self.assertEqual(
2094 [a2],
2095 list(c.iterdescendants('a')))
2096 self.assertEqual(
2097 [a2],
2098 list(c.iterdescendants(tag='a')))
2099
2101 Element = self.etree.Element
2102 SubElement = self.etree.SubElement
2103
2104 a = Element('a')
2105 b = SubElement(a, 'b')
2106 c = SubElement(a, 'c')
2107 d = SubElement(b, 'd')
2108 e = SubElement(c, 'e')
2109
2110 self.assertEqual(
2111 [b, e],
2112 list(a.iterdescendants(tag=('a', 'b', 'e'))))
2113 self.assertEqual(
2114 [b, e],
2115 list(a.iterdescendants('a', 'b', 'e')))
2116
2117 a2 = SubElement(e, 'a')
2118 self.assertEqual(
2119 [b, a2],
2120 list(a.iterdescendants(tag=('a', 'b'))))
2121 self.assertEqual(
2122 [b, a2],
2123 list(a.iterdescendants('a', 'b')))
2124
2125 self.assertEqual(
2126 [],
2127 list(c.iterdescendants(tag=('x', 'y', 'z'))))
2128 self.assertEqual(
2129 [],
2130 list(c.iterdescendants('x', 'y', 'z')))
2131
2132 self.assertEqual(
2133 [b, d, c, e, a2],
2134 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
2135 self.assertEqual(
2136 [b, d, c, e, a2],
2137 list(a.iterdescendants('x', 'y', 'z', '*')))
2138
2140 Element = self.etree.Element
2141 SubElement = self.etree.SubElement
2142
2143 a = Element('a')
2144 b = SubElement(a, 'b')
2145 c = SubElement(a, 'c')
2146 d = SubElement(b, 'd')
2147 self.assertEqual(
2148 a,
2149 a.getroottree().getroot())
2150 self.assertEqual(
2151 a,
2152 b.getroottree().getroot())
2153 self.assertEqual(
2154 a,
2155 d.getroottree().getroot())
2156
2158 Element = self.etree.Element
2159 SubElement = self.etree.SubElement
2160
2161 a = Element('a')
2162 b = SubElement(a, 'b')
2163 c = SubElement(a, 'c')
2164 self.assertEqual(
2165 None,
2166 a.getnext())
2167 self.assertEqual(
2168 c,
2169 b.getnext())
2170 self.assertEqual(
2171 None,
2172 c.getnext())
2173
2175 Element = self.etree.Element
2176 SubElement = self.etree.SubElement
2177
2178 a = Element('a')
2179 b = SubElement(a, 'b')
2180 c = SubElement(a, 'c')
2181 d = SubElement(b, 'd')
2182 self.assertEqual(
2183 None,
2184 a.getprevious())
2185 self.assertEqual(
2186 b,
2187 c.getprevious())
2188 self.assertEqual(
2189 None,
2190 b.getprevious())
2191
2193 Element = self.etree.Element
2194 SubElement = self.etree.SubElement
2195
2196 a = Element('a')
2197 b = SubElement(a, 'b')
2198 c = SubElement(a, 'c')
2199 d = SubElement(b, 'd')
2200 self.assertEqual(
2201 [],
2202 list(a.itersiblings()))
2203 self.assertEqual(
2204 [c],
2205 list(b.itersiblings()))
2206 self.assertEqual(
2207 [],
2208 list(c.itersiblings()))
2209 self.assertEqual(
2210 [b],
2211 list(c.itersiblings(preceding=True)))
2212 self.assertEqual(
2213 [],
2214 list(b.itersiblings(preceding=True)))
2215
2217 Element = self.etree.Element
2218 SubElement = self.etree.SubElement
2219
2220 a = Element('a')
2221 b = SubElement(a, 'b')
2222 c = SubElement(a, 'c')
2223 d = SubElement(b, 'd')
2224 self.assertEqual(
2225 [],
2226 list(a.itersiblings(tag='XXX')))
2227 self.assertEqual(
2228 [c],
2229 list(b.itersiblings(tag='c')))
2230 self.assertEqual(
2231 [c],
2232 list(b.itersiblings(tag='*')))
2233 self.assertEqual(
2234 [b],
2235 list(c.itersiblings(preceding=True, tag='b')))
2236 self.assertEqual(
2237 [],
2238 list(c.itersiblings(preceding=True, tag='c')))
2239
2241 Element = self.etree.Element
2242 SubElement = self.etree.SubElement
2243
2244 a = Element('a')
2245 b = SubElement(a, 'b')
2246 c = SubElement(a, 'c')
2247 d = SubElement(b, 'd')
2248 e = SubElement(a, 'e')
2249 self.assertEqual(
2250 [],
2251 list(a.itersiblings(tag=('XXX', 'YYY'))))
2252 self.assertEqual(
2253 [c, e],
2254 list(b.itersiblings(tag=('c', 'd', 'e'))))
2255 self.assertEqual(
2256 [b],
2257 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
2258 self.assertEqual(
2259 [c, b],
2260 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2261
2263 parseid = self.etree.parseid
2264 XML = self.etree.XML
2265 xml_text = _bytes('''
2266 <!DOCTYPE document [
2267 <!ELEMENT document (h1,p)*>
2268 <!ELEMENT h1 (#PCDATA)>
2269 <!ATTLIST h1 myid ID #REQUIRED>
2270 <!ELEMENT p (#PCDATA)>
2271 <!ATTLIST p someid ID #REQUIRED>
2272 ]>
2273 <document>
2274 <h1 myid="chapter1">...</h1>
2275 <p id="note1" class="note">...</p>
2276 <p>Regular paragraph.</p>
2277 <p xml:id="xmlid">XML:ID paragraph.</p>
2278 <p someid="warn1" class="warning">...</p>
2279 </document>
2280 ''')
2281
2282 tree, dic = parseid(BytesIO(xml_text))
2283 root = tree.getroot()
2284 root2 = XML(xml_text)
2285 self.assertEqual(self._writeElement(root),
2286 self._writeElement(root2))
2287 expected = {
2288 "chapter1" : root[0],
2289 "xmlid" : root[3],
2290 "warn1" : root[4]
2291 }
2292 self.assertTrue("chapter1" in dic)
2293 self.assertTrue("warn1" in dic)
2294 self.assertTrue("xmlid" in dic)
2295 self._checkIDDict(dic, expected)
2296
2298 XMLDTDID = self.etree.XMLDTDID
2299 XML = self.etree.XML
2300 xml_text = _bytes('''
2301 <!DOCTYPE document [
2302 <!ELEMENT document (h1,p)*>
2303 <!ELEMENT h1 (#PCDATA)>
2304 <!ATTLIST h1 myid ID #REQUIRED>
2305 <!ELEMENT p (#PCDATA)>
2306 <!ATTLIST p someid ID #REQUIRED>
2307 ]>
2308 <document>
2309 <h1 myid="chapter1">...</h1>
2310 <p id="note1" class="note">...</p>
2311 <p>Regular paragraph.</p>
2312 <p xml:id="xmlid">XML:ID paragraph.</p>
2313 <p someid="warn1" class="warning">...</p>
2314 </document>
2315 ''')
2316
2317 root, dic = XMLDTDID(xml_text)
2318 root2 = XML(xml_text)
2319 self.assertEqual(self._writeElement(root),
2320 self._writeElement(root2))
2321 expected = {
2322 "chapter1" : root[0],
2323 "xmlid" : root[3],
2324 "warn1" : root[4]
2325 }
2326 self.assertTrue("chapter1" in dic)
2327 self.assertTrue("warn1" in dic)
2328 self.assertTrue("xmlid" in dic)
2329 self._checkIDDict(dic, expected)
2330
2332 XMLDTDID = self.etree.XMLDTDID
2333 XML = self.etree.XML
2334 xml_text = _bytes('''
2335 <document>
2336 <h1 myid="chapter1">...</h1>
2337 <p id="note1" class="note">...</p>
2338 <p>Regular paragraph.</p>
2339 <p someid="warn1" class="warning">...</p>
2340 </document>
2341 ''')
2342
2343 root, dic = XMLDTDID(xml_text)
2344 root2 = XML(xml_text)
2345 self.assertEqual(self._writeElement(root),
2346 self._writeElement(root2))
2347 expected = {}
2348 self._checkIDDict(dic, expected)
2349
2351 XMLDTDID = self.etree.XMLDTDID
2352 XML = self.etree.XML
2353 xml_text = _bytes('''
2354 <!DOCTYPE document [
2355 <!ELEMENT document (h1,p)*>
2356 <!ELEMENT h1 (#PCDATA)>
2357 <!ATTLIST h1 myid ID #REQUIRED>
2358 <!ELEMENT p (#PCDATA)>
2359 <!ATTLIST p someid ID #REQUIRED>
2360 ]>
2361 <document>
2362 <h1 myid="chapter1">...</h1>
2363 <p id="note1" class="note">...</p>
2364 <p>Regular paragraph.</p>
2365 <p xml:id="xmlid">XML:ID paragraph.</p>
2366 <p someid="warn1" class="warning">...</p>
2367 </document>
2368 ''')
2369
2370 parser = etree.XMLParser(collect_ids=False)
2371 root, dic = XMLDTDID(xml_text, parser=parser)
2372 root2 = XML(xml_text)
2373 self.assertEqual(self._writeElement(root),
2374 self._writeElement(root2))
2375 self.assertFalse(dic)
2376 self._checkIDDict(dic, {})
2377
2379 self.assertEqual(len(dic),
2380 len(expected))
2381 self.assertEqual(sorted(dic.items()),
2382 sorted(expected.items()))
2383 if sys.version_info < (3,):
2384 self.assertEqual(sorted(dic.iteritems()),
2385 sorted(expected.iteritems()))
2386 self.assertEqual(sorted(dic.keys()),
2387 sorted(expected.keys()))
2388 if sys.version_info < (3,):
2389 self.assertEqual(sorted(dic.iterkeys()),
2390 sorted(expected.iterkeys()))
2391 if sys.version_info < (3,):
2392 self.assertEqual(sorted(dic.values()),
2393 sorted(expected.values()))
2394 self.assertEqual(sorted(dic.itervalues()),
2395 sorted(expected.itervalues()))
2396
2398 etree = self.etree
2399
2400 r = {'foo': 'http://ns.infrae.com/foo'}
2401 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2402 self.assertEqual(
2403 'foo',
2404 e.prefix)
2405 self.assertEqual(
2406 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2407 self._writeElement(e))
2408
2410 etree = self.etree
2411
2412 r = {None: 'http://ns.infrae.com/foo'}
2413 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2414 self.assertEqual(
2415 None,
2416 e.prefix)
2417 self.assertEqual(
2418 '{http://ns.infrae.com/foo}bar',
2419 e.tag)
2420 self.assertEqual(
2421 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2422 self._writeElement(e))
2423
2425 etree = self.etree
2426
2427 r = {None: 'http://ns.infrae.com/foo',
2428 'hoi': 'http://ns.infrae.com/hoi'}
2429 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2430 e.set('{http://ns.infrae.com/hoi}test', 'value')
2431 self.assertEqual(
2432 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2433 self._writeElement(e))
2434
2436 etree = self.etree
2437
2438 root = etree.Element('{http://test/ns}root',
2439 nsmap={None: 'http://test/ns'})
2440 sub = etree.Element('{http://test/ns}sub',
2441 nsmap={'test': 'http://test/ns'})
2442
2443 sub.attrib['{http://test/ns}attr'] = 'value'
2444 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2445 self.assertEqual(
2446 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2447 etree.tostring(sub))
2448
2449 root.append(sub)
2450 self.assertEqual(
2451 _bytes('<root xmlns="http://test/ns">'
2452 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2453 '</root>'),
2454 etree.tostring(root))
2455
2457 etree = self.etree
2458
2459 root = etree.Element('root')
2460 sub = etree.Element('{http://test/ns}sub',
2461 nsmap={'test': 'http://test/ns'})
2462
2463 sub.attrib['{http://test/ns}attr'] = 'value'
2464 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2465 self.assertEqual(
2466 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2467 etree.tostring(sub))
2468
2469 root.append(sub)
2470 self.assertEqual(
2471 _bytes('<root>'
2472 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2473 '</root>'),
2474 etree.tostring(root))
2475
2477 etree = self.etree
2478
2479 root = etree.Element('root')
2480 sub = etree.Element('{http://test/ns}sub',
2481 nsmap={None: 'http://test/ns'})
2482
2483 sub.attrib['{http://test/ns}attr'] = 'value'
2484 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2485 self.assertEqual(
2486 _bytes('<sub xmlns="http://test/ns" '
2487 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2488 etree.tostring(sub))
2489
2490 root.append(sub)
2491 self.assertEqual(
2492 _bytes('<root>'
2493 '<sub xmlns="http://test/ns"'
2494 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2495 '</root>'),
2496 etree.tostring(root))
2497
2499 etree = self.etree
2500
2501 root = etree.Element('{http://test/ns}root',
2502 nsmap={'test': 'http://test/ns',
2503 None: 'http://test/ns'})
2504 sub = etree.Element('{http://test/ns}sub',
2505 nsmap={None: 'http://test/ns'})
2506
2507 sub.attrib['{http://test/ns}attr'] = 'value'
2508 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2509 self.assertEqual(
2510 _bytes('<sub xmlns="http://test/ns" '
2511 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2512 etree.tostring(sub))
2513
2514 root.append(sub)
2515 self.assertEqual(
2516 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2517 '<test:sub test:attr="value"/>'
2518 '</test:root>'),
2519 etree.tostring(root))
2520
2522 etree = self.etree
2523 r = {None: 'http://ns.infrae.com/foo',
2524 'hoi': 'http://ns.infrae.com/hoi'}
2525 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2526 tree = etree.ElementTree(element=e)
2527 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2528 self.assertEqual(
2529 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2530 self._writeElement(e))
2531
2533 etree = self.etree
2534
2535 r = {None: 'http://ns.infrae.com/foo'}
2536 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2537 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2538
2539 e1.append(e2)
2540
2541 self.assertEqual(
2542 None,
2543 e1.prefix)
2544 self.assertEqual(
2545 None,
2546 e1[0].prefix)
2547 self.assertEqual(
2548 '{http://ns.infrae.com/foo}bar',
2549 e1.tag)
2550 self.assertEqual(
2551 '{http://ns.infrae.com/foo}bar',
2552 e1[0].tag)
2553
2555 etree = self.etree
2556
2557 r = {None: 'http://ns.infrae.com/BAR'}
2558 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2559 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2560
2561 e1.append(e2)
2562
2563 self.assertEqual(
2564 None,
2565 e1.prefix)
2566 self.assertNotEqual(
2567 None,
2568 e2.prefix)
2569 self.assertEqual(
2570 '{http://ns.infrae.com/BAR}bar',
2571 e1.tag)
2572 self.assertEqual(
2573 '{http://ns.infrae.com/foo}bar',
2574 e2.tag)
2575
2577 ns_href = "http://a.b.c"
2578 one = self.etree.fromstring(
2579 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2580 baz = one[0][0]
2581
2582 two = self.etree.fromstring(
2583 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2584 two.append(baz)
2585 del one # make sure the source document is deallocated
2586
2587 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2588 self.assertEqual(
2589 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2590 self.etree.tostring(two))
2591
2593 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>')
2594 root = self.etree.fromstring(xml)
2595 self.assertEqual(xml,
2596 self.etree.tostring(root))
2597 self.etree.cleanup_namespaces(root)
2598 self.assertEqual(
2599 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
2600 self.etree.tostring(root))
2601
2603 etree = self.etree
2604
2605 r = {None: 'http://ns.infrae.com/foo',
2606 'hoi': 'http://ns.infrae.com/hoi'}
2607 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2608 self.assertEqual(
2609 r,
2610 e.nsmap)
2611
2613 etree = self.etree
2614
2615 re = {None: 'http://ns.infrae.com/foo',
2616 'hoi': 'http://ns.infrae.com/hoi'}
2617 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2618
2619 rs = {None: 'http://ns.infrae.com/honk',
2620 'top': 'http://ns.infrae.com/top'}
2621 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2622
2623 r = re.copy()
2624 r.update(rs)
2625 self.assertEqual(re, e.nsmap)
2626 self.assertEqual(r, s.nsmap)
2627
2629 etree = self.etree
2630 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2631 self.assertEqual({'hha': None}, el.nsmap)
2632
2634 Element = self.etree.Element
2635 SubElement = self.etree.SubElement
2636
2637 a = Element('a')
2638 b = SubElement(a, 'b')
2639 c = SubElement(a, 'c')
2640 d = SubElement(b, 'd')
2641 e = SubElement(c, 'e')
2642 f = SubElement(c, 'f')
2643
2644 self.assertEqual(
2645 [a, b],
2646 list(a.getiterator('a', 'b')))
2647 self.assertEqual(
2648 [],
2649 list(a.getiterator('x', 'y')))
2650 self.assertEqual(
2651 [a, f],
2652 list(a.getiterator('f', 'a')))
2653 self.assertEqual(
2654 [c, e, f],
2655 list(c.getiterator('c', '*', 'a')))
2656 self.assertEqual(
2657 [],
2658 list(a.getiterator( (), () )))
2659
2661 Element = self.etree.Element
2662 SubElement = self.etree.SubElement
2663
2664 a = Element('a')
2665 b = SubElement(a, 'b')
2666 c = SubElement(a, 'c')
2667 d = SubElement(b, 'd')
2668 e = SubElement(c, 'e')
2669 f = SubElement(c, 'f')
2670
2671 self.assertEqual(
2672 [a, b],
2673 list(a.getiterator( ('a', 'b') )))
2674 self.assertEqual(
2675 [],
2676 list(a.getiterator( ('x', 'y') )))
2677 self.assertEqual(
2678 [a, f],
2679 list(a.getiterator( ('f', 'a') )))
2680 self.assertEqual(
2681 [c, e, f],
2682 list(c.getiterator( ('c', '*', 'a') )))
2683 self.assertEqual(
2684 [],
2685 list(a.getiterator( () )))
2686
2688 Element = self.etree.Element
2689 SubElement = self.etree.SubElement
2690
2691 a = Element('{a}a')
2692 b = SubElement(a, '{a}b')
2693 c = SubElement(a, '{a}c')
2694 d = SubElement(b, '{b}d')
2695 e = SubElement(c, '{a}e')
2696 f = SubElement(c, '{b}f')
2697 g = SubElement(c, 'g')
2698
2699 self.assertEqual(
2700 [a],
2701 list(a.getiterator('{a}a')))
2702 self.assertEqual(
2703 [],
2704 list(a.getiterator('{b}a')))
2705 self.assertEqual(
2706 [],
2707 list(a.getiterator('a')))
2708 self.assertEqual(
2709 [a,b,d,c,e,f,g],
2710 list(a.getiterator('*')))
2711 self.assertEqual(
2712 [f],
2713 list(c.getiterator('{b}*')))
2714 self.assertEqual(
2715 [d, f],
2716 list(a.getiterator('{b}*')))
2717 self.assertEqual(
2718 [g],
2719 list(a.getiterator('g')))
2720 self.assertEqual(
2721 [g],
2722 list(a.getiterator('{}g')))
2723 self.assertEqual(
2724 [g],
2725 list(a.getiterator('{}*')))
2726
2728 Element = self.etree.Element
2729 SubElement = self.etree.SubElement
2730
2731 a = Element('{a}a')
2732 b = SubElement(a, '{nsA}b')
2733 c = SubElement(b, '{nsB}b')
2734 d = SubElement(a, 'b')
2735 e = SubElement(a, '{nsA}e')
2736 f = SubElement(e, '{nsB}e')
2737 g = SubElement(e, 'e')
2738
2739 self.assertEqual(
2740 [b, c, d],
2741 list(a.getiterator('{*}b')))
2742 self.assertEqual(
2743 [e, f, g],
2744 list(a.getiterator('{*}e')))
2745 self.assertEqual(
2746 [a, b, c, d, e, f, g],
2747 list(a.getiterator('{*}*')))
2748
2750 Element = self.etree.Element
2751 Entity = self.etree.Entity
2752 SubElement = self.etree.SubElement
2753
2754 a = Element('a')
2755 b = SubElement(a, 'b')
2756 entity_b = Entity("TEST-b")
2757 b.append(entity_b)
2758
2759 self.assertEqual(
2760 [entity_b],
2761 list(a.getiterator(Entity)))
2762
2763 entity_a = Entity("TEST-a")
2764 a.append(entity_a)
2765
2766 self.assertEqual(
2767 [entity_b, entity_a],
2768 list(a.getiterator(Entity)))
2769
2770 self.assertEqual(
2771 [entity_b],
2772 list(b.getiterator(Entity)))
2773
2775 Element = self.etree.Element
2776 Comment = self.etree.Comment
2777 PI = self.etree.PI
2778 SubElement = self.etree.SubElement
2779
2780 a = Element('a')
2781 b = SubElement(a, 'b')
2782 a.append(Comment("test"))
2783 a.append(PI("pi", "content"))
2784 c = SubElement(a, 'c')
2785
2786 self.assertEqual(
2787 [a, b, c],
2788 list(a.getiterator(Element)))
2789
2791 # ElementTree iterates over everything here
2792 Element = self.etree.Element
2793 Comment = self.etree.Comment
2794 PI = self.etree.PI
2795 SubElement = self.etree.SubElement
2796
2797 a = Element('a')
2798 b = SubElement(a, 'b')
2799 a.append(Comment("test"))
2800 a.append(PI("pi", "content"))
2801 c = SubElement(a, 'c')
2802
2803 self.assertEqual(
2804 [a, b, c],
2805 list(a.getiterator('*')))
2806
2808 a = etree.Element("a")
2809 b = etree.SubElement(a, "b")
2810 c = etree.SubElement(a, "c")
2811 d1 = etree.SubElement(c, "d")
2812 d2 = etree.SubElement(c, "d")
2813 c.text = d1.text = 'TEXT'
2814
2815 tree = etree.ElementTree(a)
2816 self.assertEqual('.', tree.getelementpath(a))
2817 self.assertEqual('c/d[1]', tree.getelementpath(d1))
2818 self.assertEqual('c/d[2]', tree.getelementpath(d2))
2819
2820 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
2821 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
2822
2823 tree = etree.ElementTree(c)
2824 self.assertEqual('.', tree.getelementpath(c))
2825 self.assertEqual('d[2]', tree.getelementpath(d2))
2826 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
2827
2828 tree = etree.ElementTree(b) # not a parent of a/c/d1/d2
2829 self.assertEqual('.', tree.getelementpath(b))
2830 self.assertRaises(ValueError, tree.getelementpath, a)
2831 self.assertRaises(ValueError, tree.getelementpath, c)
2832 self.assertRaises(ValueError, tree.getelementpath, d2)
2833
2835 a = etree.Element("{http://ns1/}a")
2836 b = etree.SubElement(a, "{http://ns1/}b")
2837 c = etree.SubElement(a, "{http://ns1/}c")
2838 d1 = etree.SubElement(c, "{http://ns1/}d")
2839 d2 = etree.SubElement(c, "{http://ns2/}d")
2840 d3 = etree.SubElement(c, "{http://ns1/}d")
2841
2842 tree = etree.ElementTree(a)
2843 self.assertEqual('.', tree.getelementpath(a))
2844 self.assertEqual('{http://ns1/}c/{http://ns1/}d[1]',
2845 tree.getelementpath(d1))
2846 self.assertEqual('{http://ns1/}c/{http://ns2/}d',
2847 tree.getelementpath(d2))
2848 self.assertEqual('{http://ns1/}c/{http://ns1/}d[2]',
2849 tree.getelementpath(d3))
2850
2851 self.assertEqual(a, tree.find(tree.getelementpath(a)))
2852 self.assertEqual(b, tree.find(tree.getelementpath(b)))
2853 self.assertEqual(c, tree.find(tree.getelementpath(c)))
2854 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
2855 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
2856 self.assertEqual(d3, tree.find(tree.getelementpath(d3)))
2857
2858 tree = etree.ElementTree(c)
2859 self.assertEqual('{http://ns1/}d[1]', tree.getelementpath(d1))
2860 self.assertEqual('{http://ns2/}d', tree.getelementpath(d2))
2861 self.assertEqual('{http://ns1/}d[2]', tree.getelementpath(d3))
2862 self.assertEqual(d1, tree.find(tree.getelementpath(d1)))
2863 self.assertEqual(d2, tree.find(tree.getelementpath(d2)))
2864 self.assertEqual(d3, tree.find(tree.getelementpath(d3)))
2865
2866 tree = etree.ElementTree(b) # not a parent of d1/d2
2867 self.assertRaises(ValueError, tree.getelementpath, d1)
2868 self.assertRaises(ValueError, tree.getelementpath, d2)
2869
2871 XML = self.etree.XML
2872 ElementTree = self.etree.ElementTree
2873 QName = self.etree.QName
2874 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
2875 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
2876
2878 XML = self.etree.XML
2879 ElementTree = self.etree.ElementTree
2880 QName = self.etree.QName
2881 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
2882 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
2883
2885 XML = self.etree.XML
2886 ElementTree = self.etree.ElementTree
2887 QName = self.etree.QName
2888 tree = ElementTree(XML(
2889 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
2890 self.assertEqual(len(list(tree.findall(QName("b")))), 2)
2891 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
2892
2894 XML = self.etree.XML
2895 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2896 self.assertEqual(len(root.findall(".//{X}b")), 2)
2897 self.assertEqual(len(root.findall(".//{X}*")), 2)
2898 self.assertEqual(len(root.findall(".//b")), 3)
2899
2901 XML = self.etree.XML
2902 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2903 nsmap = {'xx': 'X'}
2904 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2905 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2906 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2907 nsmap = {'xx': 'Y'}
2908 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2909 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2910 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2911
2913 XML = self.etree.XML
2914 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>'))
2915 self.assertRaises(SyntaxError, root.findall, '')
2916 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element
2917 self.assertRaises(SyntaxError, root.findall, './//')
2918
2920 etree = self.etree
2921 e = etree.Element('foo')
2922 for i in range(10):
2923 etree.SubElement(e, 'a%s' % i)
2924 for i in range(10):
2925 self.assertEqual(
2926 i,
2927 e.index(e[i]))
2928 self.assertEqual(
2929 3, e.index(e[3], 3))
2930 self.assertRaises(
2931 ValueError, e.index, e[3], 4)
2932 self.assertRaises(
2933 ValueError, e.index, e[3], 0, 2)
2934 self.assertRaises(
2935 ValueError, e.index, e[8], 0, -3)
2936 self.assertRaises(
2937 ValueError, e.index, e[8], -5, -3)
2938 self.assertEqual(
2939 8, e.index(e[8], 0, -1))
2940 self.assertEqual(
2941 8, e.index(e[8], -12, -1))
2942 self.assertEqual(
2943 0, e.index(e[0], -12, -1))
2944
2946 etree = self.etree
2947 e = etree.Element('foo')
2948 for i in range(10):
2949 el = etree.SubElement(e, 'a%s' % i)
2950 el.text = "text%d" % i
2951 el.tail = "tail%d" % i
2952
2953 child0 = e[0]
2954 child1 = e[1]
2955 child2 = e[2]
2956
2957 e.replace(e[0], e[1])
2958 self.assertEqual(
2959 9, len(e))
2960 self.assertEqual(
2961 child1, e[0])
2962 self.assertEqual(
2963 child1.text, "text1")
2964 self.assertEqual(
2965 child1.tail, "tail1")
2966 self.assertEqual(
2967 child0.tail, "tail0")
2968 self.assertEqual(
2969 child2, e[1])
2970
2971 e.replace(e[-1], e[0])
2972 self.assertEqual(
2973 child1, e[-1])
2974 self.assertEqual(
2975 child1.text, "text1")
2976 self.assertEqual(
2977 child1.tail, "tail1")
2978 self.assertEqual(
2979 child2, e[0])
2980
2982 etree = self.etree
2983 e = etree.Element('foo')
2984 for i in range(10):
2985 etree.SubElement(e, 'a%s' % i)
2986
2987 new_element = etree.Element("test")
2988 new_element.text = "TESTTEXT"
2989 new_element.tail = "TESTTAIL"
2990 child1 = e[1]
2991 e.replace(e[0], new_element)
2992 self.assertEqual(
2993 new_element, e[0])
2994 self.assertEqual(
2995 "TESTTEXT",
2996 e[0].text)
2997 self.assertEqual(
2998 "TESTTAIL",
2999 e[0].tail)
3000 self.assertEqual(
3001 child1, e[1])
3002
3004 Element = self.etree.Element
3005 SubElement = self.etree.SubElement
3006
3007 a = Element('a')
3008
3009 e = Element('e')
3010 f = Element('f')
3011 g = Element('g')
3012
3013 s = [e, f, g]
3014 a[::-1] = s
3015 self.assertEqual(
3016 [g, f, e],
3017 list(a))
3018
3020 Element = self.etree.Element
3021 SubElement = self.etree.SubElement
3022
3023 a = Element('a')
3024 b = SubElement(a, 'b')
3025 c = SubElement(a, 'c')
3026 d = SubElement(a, 'd')
3027 e = SubElement(a, 'e')
3028
3029 x = Element('x')
3030 y = Element('y')
3031
3032 a[1::2] = [x, y]
3033 self.assertEqual(
3034 [b, x, d, y],
3035 list(a))
3036
3038 Element = self.etree.Element
3039 SubElement = self.etree.SubElement
3040
3041 a = Element('a')
3042 b = SubElement(a, 'b')
3043 c = SubElement(a, 'c')
3044 d = SubElement(a, 'd')
3045 e = SubElement(a, 'e')
3046
3047 x = Element('x')
3048 y = Element('y')
3049
3050 a[1::-1] = [x, y]
3051 self.assertEqual(
3052 [y, x, d, e],
3053 list(a))
3054
3056 Element = self.etree.Element
3057 SubElement = self.etree.SubElement
3058
3059 a = Element('a')
3060 b = SubElement(a, 'b')
3061 c = SubElement(a, 'c')
3062 d = SubElement(a, 'd')
3063 e = SubElement(a, 'e')
3064
3065 x = Element('x')
3066 y = Element('y')
3067
3068 a[::-2] = [x, y]
3069 self.assertEqual(
3070 [b, y, d, x],
3071 list(a))
3072
3074 Element = self.etree.Element
3075 SubElement = self.etree.SubElement
3076 try:
3077 slice
3078 except NameError:
3079 print("slice() not found")
3080 return
3081
3082 a = Element('a')
3083 b = SubElement(a, 'b')
3084 c = SubElement(a, 'c')
3085 d = SubElement(a, 'd')
3086 e = SubElement(a, 'e')
3087
3088 x = Element('x')
3089 y = Element('y')
3090 z = Element('z')
3091
3092 self.assertRaises(
3093 ValueError,
3094 operator.setitem, a, slice(1,None,2), [x, y, z])
3095
3096 self.assertEqual(
3097 [b, c, d, e],
3098 list(a))
3099
3101 XML = self.etree.XML
3102 root = XML(_bytes('''<?xml version="1.0"?>
3103 <root><test>
3104
3105 <bla/></test>
3106 </root>
3107 '''))
3108
3109 self.assertEqual(
3110 [2, 2, 4],
3111 [ el.sourceline for el in root.getiterator() ])
3112
3114 XML = self.etree.XML
3115 root = XML(_bytes(
3116 '<?xml version="1.0"?>\n'
3117 '<root>' + '\n' * 65536 +
3118 '<p>' + '\n' * 65536 + '</p>\n' +
3119 '<br/>\n'
3120 '</root>'))
3121
3122 if self.etree.LIBXML_VERSION >= (2, 9):
3123 expected = [2, 131074, 131076]
3124 else:
3125 expected = [2, 65535, 65535]
3126
3127 self.assertEqual(expected, [el.sourceline for el in root.iter()])
3128
3130 parse = self.etree.parse
3131 tree = parse(fileInTestDir('include/test_xinclude.xml'))
3132
3133 self.assertEqual(
3134 [1, 2, 3],
3135 [ el.sourceline for el in tree.getiterator() ])
3136
3138 iterparse = self.etree.iterparse
3139 lines = [ el.sourceline for (event, el) in
3140 iterparse(fileInTestDir('include/test_xinclude.xml')) ]
3141
3142 self.assertEqual(
3143 [2, 3, 1],
3144 lines)
3145
3147 iterparse = self.etree.iterparse
3148 lines = [ el.sourceline for (event, el) in
3149 iterparse(fileInTestDir('include/test_xinclude.xml'),
3150 events=("start",)) ]
3151
3152 self.assertEqual(
3153 [1, 2, 3],
3154 lines)
3155
3157 Element = self.etree.Element
3158 SubElement = self.etree.SubElement
3159 el = Element("test")
3160 self.assertEqual(None, el.sourceline)
3161
3162 child = SubElement(el, "test")
3163 self.assertEqual(None, el.sourceline)
3164 self.assertEqual(None, child.sourceline)
3165
3167 etree = self.etree
3168 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3169 docinfo = root.getroottree().docinfo
3170 self.assertEqual(docinfo.URL, "http://no/such/url")
3171
3173 etree = self.etree
3174 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3175 docinfo = root.getroottree().docinfo
3176 self.assertEqual(docinfo.URL, "http://no/such/url")
3177 docinfo.URL = "https://secret/url"
3178 self.assertEqual(docinfo.URL, "https://secret/url")
3179
3181 etree = self.etree
3182 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
3183 docinfo = tree.docinfo
3184 self.assertEqual(docinfo.URL, "http://no/such/url")
3185
3187 etree = self.etree
3188 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3189 base_url="http://no/such/url")
3190 docinfo = tree.docinfo
3191 self.assertEqual(docinfo.URL, "http://no/such/url")
3192
3194 etree = self.etree
3195 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
3196 docinfo = root.getroottree().docinfo
3197 self.assertEqual(docinfo.URL, "http://no/such/url")
3198
3200 etree = self.etree
3201 xml_header = '<?xml version="1.0" encoding="ascii"?>'
3202 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3203 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3204 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
3205
3206 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3207
3208 tree = etree.parse(BytesIO(xml))
3209 docinfo = tree.docinfo
3210 self.assertEqual(docinfo.encoding, "ascii")
3211 self.assertEqual(docinfo.xml_version, "1.0")
3212 self.assertEqual(docinfo.public_id, pub_id)
3213 self.assertEqual(docinfo.system_url, sys_id)
3214 self.assertEqual(docinfo.root_name, 'html')
3215 self.assertEqual(docinfo.doctype, doctype_string)
3216
3218 etree = self.etree
3219 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
3220 sys_id = "some.dtd"
3221 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
3222 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
3223
3224 tree = etree.parse(BytesIO(xml))
3225 docinfo = tree.docinfo
3226 self.assertEqual(docinfo.encoding, "UTF-8")
3227 self.assertEqual(docinfo.xml_version, "1.0")
3228 self.assertEqual(docinfo.public_id, None)
3229 self.assertEqual(docinfo.system_url, sys_id)
3230 self.assertEqual(docinfo.root_name, 'html')
3231 self.assertEqual(docinfo.doctype, doctype_string)
3232
3234 etree = self.etree
3235 xml = _bytes('<html><body></body></html>')
3236 tree = etree.parse(BytesIO(xml))
3237 docinfo = tree.docinfo
3238 self.assertEqual(docinfo.encoding, "UTF-8")
3239 self.assertEqual(docinfo.xml_version, "1.0")
3240 self.assertEqual(docinfo.public_id, None)
3241 self.assertEqual(docinfo.system_url, None)
3242 self.assertEqual(docinfo.root_name, 'html')
3243 self.assertEqual(docinfo.doctype, '')
3244
3246 etree = self.etree
3247 xml = _bytes('<!DOCTYPE root><root></root>')
3248 tree = etree.parse(BytesIO(xml))
3249 docinfo = tree.docinfo
3250 self.assertEqual(docinfo.encoding, "UTF-8")
3251 self.assertEqual(docinfo.xml_version, "1.0")
3252 self.assertEqual(docinfo.public_id, None)
3253 self.assertEqual(docinfo.system_url, None)
3254 self.assertEqual(docinfo.root_name, 'root')
3255 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
3256
3258 etree = self.etree
3259 xml = _bytes('<!DOCTYPE root>\n<root/>')
3260 tree = etree.parse(BytesIO(xml))
3261 self.assertEqual(xml, etree.tostring(tree))
3262
3264 etree = self.etree
3265 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3266 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3267 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
3268
3269 xml = _bytes('<!DOCTYPE root>\n<root/>')
3270 tree = etree.parse(BytesIO(xml))
3271 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
3272 etree.tostring(tree, doctype=doctype_string))
3273
3275 etree = self.etree
3276 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3277 self.assertEqual(root.base, "http://no/such/url")
3278 self.assertEqual(
3279 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3280 root.base = "https://secret/url"
3281 self.assertEqual(root.base, "https://secret/url")
3282 self.assertEqual(
3283 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3284 "https://secret/url")
3285
3287 etree = self.etree
3288 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3289 self.assertEqual(root.base, "http://no/such/url")
3290 self.assertEqual(
3291 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3292 root.set('{http://www.w3.org/XML/1998/namespace}base',
3293 "https://secret/url")
3294 self.assertEqual(root.base, "https://secret/url")
3295 self.assertEqual(
3296 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3297 "https://secret/url")
3298
3300 etree = self.etree
3301 root = etree.HTML(_bytes("<html><body></body></html>"),
3302 base_url="http://no/such/url")
3303 self.assertEqual(root.base, "http://no/such/url")
3304
3306 etree = self.etree
3307 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
3308 self.assertEqual(root.base, "http://no/such/url")
3309
3311 # parse from a file object that returns unicode strings
3312 f = LargeFileLikeUnicode()
3313 tree = self.etree.parse(f)
3314 root = tree.getroot()
3315 self.assertTrue(root.tag.endswith('root'))
3316
3318 # check that DTDs that go in also go back out
3319 xml = _bytes('''\
3320 <!DOCTYPE test SYSTEM "test.dtd" [
3321 <!ENTITY entity "tasty">
3322 <!ELEMENT test (a)>
3323 <!ELEMENT a (#PCDATA)>
3324 ]>
3325 <test><a>test-test</a></test>\
3326 ''')
3327 tree = self.etree.parse(BytesIO(xml))
3328 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
3329 xml.replace(_bytes(" "), _bytes("")))
3330
3332 Element = self.etree.Element
3333
3334 a = Element('a')
3335 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3336 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3337
3338 self.assertRaises(ValueError, Element, 'ha\0ho')
3339
3341 Element = self.etree.Element
3342
3343 a = Element('a')
3344 self.assertRaises(ValueError, setattr, a, "text",
3345 _str('ha\0ho'))
3346 self.assertRaises(ValueError, setattr, a, "tail",
3347 _str('ha\0ho'))
3348
3349 self.assertRaises(ValueError, Element,
3350 _str('ha\0ho'))
3351
3353 Element = self.etree.Element
3354
3355 a = Element('a')
3356 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3357 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3358
3359 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3360 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3361
3362 self.assertRaises(ValueError, Element, 'ha\x07ho')
3363 self.assertRaises(ValueError, Element, 'ha\x02ho')
3364
3366 Element = self.etree.Element
3367
3368 a = Element('a')
3369 self.assertRaises(ValueError, setattr, a, "text",
3370 _str('ha\x07ho'))
3371 self.assertRaises(ValueError, setattr, a, "text",
3372 _str('ha\x02ho'))
3373
3374 self.assertRaises(ValueError, setattr, a, "tail",
3375 _str('ha\x07ho'))
3376 self.assertRaises(ValueError, setattr, a, "tail",
3377 _str('ha\x02ho'))
3378
3379 self.assertRaises(ValueError, Element,
3380 _str('ha\x07ho'))
3381 self.assertRaises(ValueError, Element,
3382 _str('ha\x02ho'))
3383
3385 Element = self.etree.Element
3386
3387 a = Element('a')
3388 self.assertRaises(ValueError, setattr, a, "text",
3389 _str('ha\u1234\x07ho'))
3390 self.assertRaises(ValueError, setattr, a, "text",
3391 _str('ha\u1234\x02ho'))
3392
3393 self.assertRaises(ValueError, setattr, a, "tail",
3394 _str('ha\u1234\x07ho'))
3395 self.assertRaises(ValueError, setattr, a, "tail",
3396 _str('ha\u1234\x02ho'))
3397
3398 self.assertRaises(ValueError, Element,
3399 _str('ha\u1234\x07ho'))
3400 self.assertRaises(ValueError, Element,
3401 _str('ha\u1234\x02ho'))
3402
3404 # ElementTree fails to serialize this
3405 tostring = self.etree.tostring
3406 Element = self.etree.Element
3407 SubElement = self.etree.SubElement
3408
3409 a = Element('a')
3410 b = SubElement(a, 'b')
3411 c = SubElement(a, 'c')
3412
3413 result = tostring(a, encoding='UTF-16')
3414 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3415 canonicalize(result))
3416
3418 # ElementTree raises an AssertionError here
3419 tostring = self.etree.tostring
3420 self.assertRaises(TypeError, self.etree.tostring, None)
3421
3423 tostring = self.etree.tostring
3424 Element = self.etree.Element
3425 SubElement = self.etree.SubElement
3426
3427 a = Element('a')
3428 b = SubElement(a, 'b')
3429 c = SubElement(a, 'c')
3430
3431 result = tostring(a)
3432 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3433
3434 result = tostring(a, pretty_print=False)
3435 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3436
3437 result = tostring(a, pretty_print=True)
3438 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3439
3441 tostring = self.etree.tostring
3442 Element = self.etree.Element
3443 SubElement = self.etree.SubElement
3444
3445 a = Element('a')
3446 a.tail = "aTAIL"
3447 b = SubElement(a, 'b')
3448 b.tail = "bTAIL"
3449 c = SubElement(a, 'c')
3450
3451 result = tostring(a)
3452 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3453
3454 result = tostring(a, with_tail=False)
3455 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>"))
3456
3457 result = tostring(a, with_tail=True)
3458 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3459
3461 tostring = self.etree.tostring
3462 html = self.etree.fromstring(
3463 '<html><body>'
3464 '<div><p>Some text<i>\r\n</i></p></div>\r\n'
3465 '</body></html>',
3466 parser=self.etree.HTMLParser())
3467 self.assertEqual(html.tag, 'html')
3468 div = html.find('.//div')
3469 self.assertEqual(div.tail, '\r\n')
3470 result = tostring(div, method='html')
3471 self.assertEqual(
3472 result,
3473 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3474 result = tostring(div, method='html', with_tail=True)
3475 self.assertEqual(
3476 result,
3477 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3478 result = tostring(div, method='html', with_tail=False)
3479 self.assertEqual(
3480 result,
3481 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3482
3484 tostring = self.etree.tostring
3485 XML = self.etree.XML
3486 ElementTree = self.etree.ElementTree
3487 Element = self.etree.Element
3488
3489 tree = Element("root").getroottree()
3490 self.assertEqual(None, tree.docinfo.standalone)
3491
3492 tree = XML(_bytes("<root/>")).getroottree()
3493 self.assertEqual(None, tree.docinfo.standalone)
3494
3495 tree = XML(_bytes(
3496 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
3497 )).getroottree()
3498 self.assertEqual(True, tree.docinfo.standalone)
3499
3500 tree = XML(_bytes(
3501 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
3502 )).getroottree()
3503 self.assertEqual(False, tree.docinfo.standalone)
3504
3506 tostring = self.etree.tostring
3507 XML = self.etree.XML
3508 ElementTree = self.etree.ElementTree
3509
3510 root = XML(_bytes("<root/>"))
3511
3512 tree = ElementTree(root)
3513 self.assertEqual(None, tree.docinfo.standalone)
3514
3515 result = tostring(root, xml_declaration=True, encoding="ASCII")
3516 self.assertEqual(result, _bytes(
3517 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3518
3519 result = tostring(root, xml_declaration=True, encoding="ASCII",
3520 standalone=True)
3521 self.assertEqual(result, _bytes(
3522 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3523
3524 tree = ElementTree(XML(result))
3525 self.assertEqual(True, tree.docinfo.standalone)
3526
3527 result = tostring(root, xml_declaration=True, encoding="ASCII",
3528 standalone=False)
3529 self.assertEqual(result, _bytes(
3530 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3531
3532 tree = ElementTree(XML(result))
3533 self.assertEqual(False, tree.docinfo.standalone)
3534
3536 tostring = self.etree.tostring
3537 XML = self.etree.XML
3538 ElementTree = self.etree.ElementTree
3539
3540 root = XML(_bytes(
3541 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
3542
3543 tree = ElementTree(root)
3544 self.assertEqual(True, tree.docinfo.standalone)
3545
3546 result = tostring(root, xml_declaration=True, encoding="ASCII")
3547 self.assertEqual(result, _bytes(
3548 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3549
3550 result = tostring(root, xml_declaration=True, encoding="ASCII",
3551 standalone=True)
3552 self.assertEqual(result, _bytes(
3553 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3554
3556 tostring = self.etree.tostring
3557 Element = self.etree.Element
3558 SubElement = self.etree.SubElement
3559
3560 a = Element('a')
3561 a.text = "A"
3562 a.tail = "tail"
3563 b = SubElement(a, 'b')
3564 b.text = "B"
3565 b.tail = _str("Søk på nettet")
3566 c = SubElement(a, 'c')
3567 c.text = "C"
3568
3569 result = tostring(a, method="text", encoding="UTF-16")
3570
3571 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3572 result)
3573
3575 tostring = self.etree.tostring
3576 Element = self.etree.Element
3577 SubElement = self.etree.SubElement
3578
3579 a = Element('a')
3580 a.text = _str('Søk på nettetA')
3581 a.tail = "tail"
3582 b = SubElement(a, 'b')
3583 b.text = "B"
3584 b.tail = _str('Søk på nettetB')
3585 c = SubElement(a, 'c')
3586 c.text = "C"
3587
3588 self.assertRaises(UnicodeEncodeError,
3589 tostring, a, method="text")
3590
3591 self.assertEqual(
3592 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3593 tostring(a, encoding="UTF-8", method="text"))
3594
3596 tounicode = self.etree.tounicode
3597 Element = self.etree.Element
3598 SubElement = self.etree.SubElement
3599
3600 a = Element('a')
3601 b = SubElement(a, 'b')
3602 c = SubElement(a, 'c')
3603
3604 self.assertTrue(isinstance(tounicode(a), _unicode))
3605 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3606 canonicalize(tounicode(a)))
3607
3609 tounicode = self.etree.tounicode
3610 Element = self.etree.Element
3611 SubElement = self.etree.SubElement
3612
3613 a = Element('a')
3614 b = SubElement(a, 'b')
3615 c = SubElement(a, 'c')
3616 d = SubElement(c, 'd')
3617 self.assertTrue(isinstance(tounicode(b), _unicode))
3618 self.assertTrue(isinstance(tounicode(c), _unicode))
3619 self.assertEqual(_bytes('<b></b>'),
3620 canonicalize(tounicode(b)))
3621 self.assertEqual(_bytes('<c><d></d></c>'),
3622 canonicalize(tounicode(c)))
3623
3627
3629 tounicode = self.etree.tounicode
3630 Element = self.etree.Element
3631 SubElement = self.etree.SubElement
3632
3633 a = Element('a')
3634 b = SubElement(a, 'b')
3635 c = SubElement(a, 'c')
3636 d = SubElement(c, 'd')
3637 b.tail = 'Foo'
3638
3639 self.assertTrue(isinstance(tounicode(b), _unicode))
3640 self.assertTrue(tounicode(b) == '<b/>Foo' or
3641 tounicode(b) == '<b />Foo')
3642
3644 tounicode = self.etree.tounicode
3645 Element = self.etree.Element
3646 SubElement = self.etree.SubElement
3647
3648 a = Element('a')
3649 b = SubElement(a, 'b')
3650 c = SubElement(a, 'c')
3651
3652 result = tounicode(a)
3653 self.assertEqual(result, "<a><b/><c/></a>")
3654
3655 result = tounicode(a, pretty_print=False)
3656 self.assertEqual(result, "<a><b/><c/></a>")
3657
3658 result = tounicode(a, pretty_print=True)
3659 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3660
3662 tostring = self.etree.tostring
3663 Element = self.etree.Element
3664 SubElement = self.etree.SubElement
3665
3666 a = Element('a')
3667 b = SubElement(a, 'b')
3668 c = SubElement(a, 'c')
3669
3670 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode))
3671 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3672 canonicalize(tostring(a, encoding=_unicode)))
3673
3675 tostring = self.etree.tostring
3676 Element = self.etree.Element
3677 SubElement = self.etree.SubElement
3678
3679 a = Element('a')
3680 b = SubElement(a, 'b')
3681 c = SubElement(a, 'c')
3682 d = SubElement(c, 'd')
3683 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3684 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3685 self.assertEqual(_bytes('<b></b>'),
3686 canonicalize(tostring(b, encoding=_unicode)))
3687 self.assertEqual(_bytes('<c><d></d></c>'),
3688 canonicalize(tostring(c, encoding=_unicode)))
3689
3691 tostring = self.etree.tostring
3692 self.assertRaises(TypeError, self.etree.tostring,
3693 None, encoding=_unicode)
3694
3696 tostring = self.etree.tostring
3697 Element = self.etree.Element
3698 SubElement = self.etree.SubElement
3699
3700 a = Element('a')
3701 b = SubElement(a, 'b')
3702 c = SubElement(a, 'c')
3703 d = SubElement(c, 'd')
3704 b.tail = 'Foo'
3705
3706 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3707 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or
3708 tostring(b, encoding=_unicode) == '<b />Foo')
3709
3711 tostring = self.etree.tostring
3712 Element = self.etree.Element
3713 SubElement = self.etree.SubElement
3714
3715 a = Element('a')
3716 b = SubElement(a, 'b')
3717 c = SubElement(a, 'c')
3718
3719 result = tostring(a, encoding=_unicode)
3720 self.assertEqual(result, "<a><b/><c/></a>")
3721
3722 result = tostring(a, encoding=_unicode, pretty_print=False)
3723 self.assertEqual(result, "<a><b/><c/></a>")
3724
3725 result = tostring(a, encoding=_unicode, pretty_print=True)
3726 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3727
3729 root = etree.Element('parent')
3730 etree.SubElement(root, 'child')
3731
3732 self.assertEqual(len(root), 1)
3733 self.assertEqual(root[0].tag, 'child')
3734
3735 # in PyPy, GC used to kill the Python proxy instance without cleanup
3736 gc.collect()
3737 self.assertEqual(len(root), 1)
3738 self.assertEqual(root[0].tag, 'child')
3739
3743
3744 el1 = SubEl()
3745 el2 = SubEl()
3746 self.assertEqual('SubEl', el1.tag)
3747 self.assertEqual('SubEl', el2.tag)
3748 el1.other = el2
3749 el2.other = el1
3750
3751 del el1, el2
3752 gc.collect()
3753 # not really testing anything here, but it shouldn't crash
3754
3756 root = etree.Element('parent')
3757 c1 = etree.SubElement(root, 'child1')
3758 c2 = etree.SubElement(root, 'child2')
3759
3760 root.remove(c1)
3761 root.remove(c2)
3762 c1.addnext(c2)
3763 del c1
3764 # trigger deallocation attempt of c1
3765 c2.getprevious()
3766 # make sure it wasn't deallocated
3767 self.assertEqual('child1', c2.getprevious().tag)
3768
3770 root = etree.Element('parent')
3771 c1 = etree.SubElement(root, 'child1')
3772 c2 = etree.SubElement(root, 'child2')
3773
3774 root.remove(c1)
3775 root.remove(c2)
3776 c1.addnext(c2)
3777 c1.tail = 'abc'
3778 c2.tail = 'xyz'
3779 del c1
3780 # trigger deallocation attempt of c1
3781 c2.getprevious()
3782 # make sure it wasn't deallocated
3783 self.assertEqual('child1', c2.getprevious().tag)
3784 self.assertEqual('abc', c2.getprevious().tail)
3785
3786 # helper methods
3787
3789 """Write out element for comparison.
3790 """
3791 ElementTree = self.etree.ElementTree
3792 f = BytesIO()
3793 tree = ElementTree(element=element)
3794 tree.write(f, encoding=encoding, compression=compression)
3795 data = f.getvalue()
3796 if compression:
3797 data = zlib.decompress(data)
3798 return canonicalize(data)
3799
3800
3803 filename = fileInTestDir('test_broken.xml')
3804 root = etree.XML(_bytes('''\
3805 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3806 <xi:include href="%s" parse="text"/>
3807 </doc>
3808 ''' % path2url(filename)))
3809 old_text = root.text
3810 content = read_file(filename)
3811 old_tail = root[0].tail
3812
3813 self.include( etree.ElementTree(root) )
3814 self.assertEqual(old_text + content + old_tail,
3815 root.text)
3816
3818 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
3819 self.assertNotEqual(
3820 'a',
3821 tree.getroot()[1].tag)
3822 # process xincludes
3823 self.include( tree )
3824 # check whether we find it replaced with included data
3825 self.assertEqual(
3826 'a',
3827 tree.getroot()[1].tag)
3828
3830 class res(etree.Resolver):
3831 include_text = read_file(fileInTestDir('test.xml'))
3832 called = {}
3833 def resolve(self, url, id, context):
3834 if url.endswith(".dtd"):
3835 self.called["dtd"] = True
3836 return self.resolve_filename(
3837 fileInTestDir('test.dtd'), context)
3838 elif url.endswith("test_xinclude.xml"):
3839 self.called["input"] = True
3840 return None # delegate to default resolver
3841 else:
3842 self.called["include"] = True
3843 return self.resolve_string(self.include_text, context)
3844
3845 res_instance = res()
3846 parser = etree.XMLParser(load_dtd = True)
3847 parser.resolvers.add(res_instance)
3848
3849 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3850 parser = parser)
3851
3852 self.include(tree)
3853
3854 called = list(res_instance.called.items())
3855 called.sort()
3856 self.assertEqual(
3857 [("dtd", True), ("include", True), ("input", True)],
3858 called)
3859
3861 data = textwrap.dedent('''
3862 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3863 <foo/>
3864 <xi:include href="./test.xml" />
3865 </doc>
3866 ''')
3867
3868 class Resolver(etree.Resolver):
3869 called = {}
3870
3871 def resolve(self, url, id, context):
3872 if url.endswith("test_xinclude.xml"):
3873 assert not self.called.get("input")
3874 self.called["input"] = True
3875 return None # delegate to default resolver
3876 elif url.endswith('/test5.xml'):
3877 assert not self.called.get("DONE")
3878 self.called["DONE"] = True
3879 return self.resolve_string('<DONE/>', context)
3880 else:
3881 _, filename = url.rsplit('/', 1)
3882 assert not self.called.get(filename)
3883 self.called[filename] = True
3884 next_data = data.replace(
3885 'test.xml', 'test%d.xml' % len(self.called))
3886 return self.resolve_string(next_data, context)
3887
3888 res_instance = Resolver()
3889 parser = etree.XMLParser(load_dtd=True)
3890 parser.resolvers.add(res_instance)
3891
3892 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3893 parser=parser)
3894
3895 self.include(tree)
3896
3897 called = list(res_instance.called.items())
3898 called.sort()
3899 self.assertEqual(
3900 [("DONE", True), ("input", True), ("test.xml", True),
3901 ("test2.xml", True), ("test3.xml", True), ("test4.xml", True)],
3902 called)
3903
3904
3908
3909
3914
3915
3918 tree = self.parse(_bytes('<a><b/></a>'))
3919 f = BytesIO()
3920 tree.write_c14n(f)
3921 s = f.getvalue()
3922 self.assertEqual(_bytes('<a><b></b></a>'),
3923 s)
3924
3926 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3927 f = BytesIO()
3928 tree.write_c14n(f, compression=9)
3929 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3930 try:
3931 s = gzfile.read()
3932 finally:
3933 gzfile.close()
3934 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3935 s)
3936
3938 tree = self.parse(_bytes('<a><b/></a>'))
3939 handle, filename = tempfile.mkstemp()
3940 try:
3941 tree.write_c14n(filename)
3942 data = read_file(filename, 'rb')
3943 finally:
3944 os.close(handle)
3945 os.remove(filename)
3946 self.assertEqual(_bytes('<a><b></b></a>'),
3947 data)
3948
3950 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3951 handle, filename = tempfile.mkstemp()
3952 try:
3953 tree.write_c14n(filename, compression=9)
3954 f = gzip.open(filename, 'rb')
3955 try:
3956 data = f.read()
3957 finally:
3958 f.close()
3959 finally:
3960 os.close(handle)
3961 os.remove(filename)
3962 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3963 data)
3964
3966 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3967 f = BytesIO()
3968 tree.write_c14n(f)
3969 s = f.getvalue()
3970 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3971 s)
3972 f = BytesIO()
3973 tree.write_c14n(f, with_comments=True)
3974 s = f.getvalue()
3975 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3976 s)
3977 f = BytesIO()
3978 tree.write_c14n(f, with_comments=False)
3979 s = f.getvalue()
3980 self.assertEqual(_bytes('<a><b></b></a>'),
3981 s)
3982
3984 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3985 s = etree.tostring(tree, method='c14n')
3986 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3987 s)
3988 s = etree.tostring(tree, method='c14n', with_comments=True)
3989 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3990 s)
3991 s = etree.tostring(tree, method='c14n', with_comments=False)
3992 self.assertEqual(_bytes('<a><b></b></a>'),
3993 s)
3994
3996 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3997 s = etree.tostring(tree.getroot(), method='c14n')
3998 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
3999 s)
4000 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
4001 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
4002 s)
4003 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
4004 self.assertEqual(_bytes('<a><b></b></a>'),
4005 s)
4006
4008 tree = self.parse(_bytes(
4009 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4010 f = BytesIO()
4011 tree.write_c14n(f)
4012 s = f.getvalue()
4013 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4014 s)
4015 f = BytesIO()
4016 tree.write_c14n(f, exclusive=False)
4017 s = f.getvalue()
4018 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4019 s)
4020 f = BytesIO()
4021 tree.write_c14n(f, exclusive=True)
4022 s = f.getvalue()
4023 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4024 s)
4025
4026 f = BytesIO()
4027 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
4028 s = f.getvalue()
4029 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
4030 s)
4031
4033 tree = self.parse(_bytes(
4034 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4035 s = etree.tostring(tree, method='c14n')
4036 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4037 s)
4038 s = etree.tostring(tree, method='c14n', exclusive=False)
4039 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4040 s)
4041 s = etree.tostring(tree, method='c14n', exclusive=True)
4042 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4043 s)
4044
4045 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
4046 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
4047 s)
4048
4050 tree = self.parse(_bytes(
4051 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4052 s = etree.tostring(tree.getroot(), method='c14n')
4053 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4054 s)
4055 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
4056 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4057 s)
4058 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
4059 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
4060 s)
4061
4062 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
4063 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
4064 s)
4065 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
4066 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
4067 s)
4068
4069 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
4070 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
4071 s)
4072
4074 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
4075 tree = self.parse(_bytes(
4076 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
4077
4078 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
4079 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
4080 s)
4081
4082
4085 tree = self.parse(_bytes('<a><b/></a>'))
4086 f = BytesIO()
4087 tree.write(f)
4088 s = f.getvalue()
4089 self.assertEqual(_bytes('<a><b/></a>'),
4090 s)
4091
4093 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4094 f = BytesIO()
4095 tree.write(f, compression=9)
4096 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
4097 try:
4098 s = gzfile.read()
4099 finally:
4100 gzfile.close()
4101 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4102 s)
4103
4105 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4106 f = BytesIO()
4107 tree.write(f, compression=0)
4108 s0 = f.getvalue()
4109
4110 f = BytesIO()
4111 tree.write(f)
4112 self.assertEqual(f.getvalue(), s0)
4113
4114 f = BytesIO()
4115 tree.write(f, compression=1)
4116 s = f.getvalue()
4117 self.assertTrue(len(s) <= len(s0))
4118 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
4119 try:
4120 s1 = gzfile.read()
4121 finally:
4122 gzfile.close()
4123
4124 f = BytesIO()
4125 tree.write(f, compression=9)
4126 s = f.getvalue()
4127 self.assertTrue(len(s) <= len(s0))
4128 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
4129 try:
4130 s9 = gzfile.read()
4131 finally:
4132 gzfile.close()
4133
4134 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4135 s0)
4136 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4137 s1)
4138 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4139 s9)
4140
4142 tree = self.parse(_bytes('<a><b/></a>'))
4143 handle, filename = tempfile.mkstemp()
4144 try:
4145 tree.write(filename)
4146 data = read_file(filename, 'rb')
4147 finally:
4148 os.close(handle)
4149 os.remove(filename)
4150 self.assertEqual(_bytes('<a><b/></a>'),
4151 data)
4152
4154 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4155 handle, filename = tempfile.mkstemp()
4156 try:
4157 tree.write(filename, compression=9)
4158 f = gzip.open(filename, 'rb')
4159 try:
4160 data = f.read()
4161 finally:
4162 f.close()
4163 finally:
4164 os.close(handle)
4165 os.remove(filename)
4166 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4167 data)
4168
4170 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4171 handle, filename = tempfile.mkstemp()
4172 try:
4173 tree.write(filename, compression=9)
4174 data = etree.tostring(etree.parse(filename))
4175 finally:
4176 os.close(handle)
4177 os.remove(filename)
4178 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4179 data)
4180
4182 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
4183 handle, filename = tempfile.mkstemp()
4184 try:
4185 tree.write(filename, compression=9)
4186 data = etree.tostring(etree.parse(
4187 gzip.GzipFile(filename)))
4188 finally:
4189 os.close(handle)
4190 os.remove(filename)
4191 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
4192 data)
4193
4195 etree = etree
4196
4198 parse = self.etree.parse
4199 f = BytesIO('<a><b></c></b></a>')
4200 self.etree.clear_error_log()
4201 try:
4202 parse(f)
4203 logs = None
4204 except SyntaxError:
4205 e = sys.exc_info()[1]
4206 logs = e.error_log
4207 f.close()
4208 self.assertTrue([ log for log in logs
4209 if 'mismatch' in log.message ])
4210 self.assertTrue([ log for log in logs
4211 if 'PARSER' in log.domain_name])
4212 self.assertTrue([ log for log in logs
4213 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
4214 self.assertTrue([ log for log in logs
4215 if 1 == log.line ])
4216 self.assertTrue([ log for log in logs
4217 if 15 == log.column ])
4218
4229
4230 self.etree.use_global_python_log(Logger())
4231 f = BytesIO('<a><b></c></b></a>')
4232 try:
4233 parse(f)
4234 except SyntaxError:
4235 pass
4236 f.close()
4237
4238 self.assertTrue([ message for message in messages
4239 if 'mismatch' in message ])
4240 self.assertTrue([ message for message in messages
4241 if ':PARSER:' in message])
4242 self.assertTrue([ message for message in messages
4243 if ':ERR_TAG_NAME_MISMATCH:' in message ])
4244 self.assertTrue([ message for message in messages
4245 if ':1:15:' in message ])
4246
4247
4261 def close(self):
4262 return 'close()'
4263
4264 parser = self.etree.XMLPullParser(target=Target())
4265 events = parser.read_events()
4266
4267 parser.feed('<root><element>')
4268 self.assertFalse(list(events))
4269 self.assertFalse(list(events))
4270 parser.feed('</element><child>')
4271 self.assertEqual([('end', 'end(element)')], list(events))
4272 parser.feed('</child>')
4273 self.assertEqual([('end', 'end(child)')], list(events))
4274 parser.feed('</root>')
4275 self.assertEqual([('end', 'end(root)')], list(events))
4276 self.assertFalse(list(events))
4277 self.assertEqual('close()', parser.close())
4278
4283 def end(self, tag):
4284 return 'end(%s)' % tag
4285 def close(self):
4286 return 'close()'
4287
4288 parser = self.etree.XMLPullParser(
4289 ['start', 'end'], target=Target())
4290 events = parser.read_events()
4291
4292 parser.feed('<root><element>')
4293 self.assertEqual(
4294 [('start', 'start(root)'), ('start', 'start(element)')],
4295 list(events))
4296 self.assertFalse(list(events))
4297 parser.feed('</element><child>')
4298 self.assertEqual(
4299 [('end', 'end(element)'), ('start', 'start(child)')],
4300 list(events))
4301 parser.feed('</child>')
4302 self.assertEqual(
4303 [('end', 'end(child)')],
4304 list(events))
4305 parser.feed('</root>')
4306 self.assertEqual(
4307 [('end', 'end(root)')],
4308 list(events))
4309 self.assertFalse(list(events))
4310 self.assertEqual('close()', parser.close())
4311
4313 parser = self.etree.XMLPullParser(
4314 ['start', 'end'], target=etree.TreeBuilder())
4315 events = parser.read_events()
4316
4317 parser.feed('<root><element>')
4318 self.assert_event_tags(
4319 events, [('start', 'root'), ('start', 'element')])
4320 self.assertFalse(list(events))
4321 parser.feed('</element><child>')
4322 self.assert_event_tags(
4323 events, [('end', 'element'), ('start', 'child')])
4324 parser.feed('</child>')
4325 self.assert_event_tags(
4326 events, [('end', 'child')])
4327 parser.feed('</root>')
4328 self.assert_event_tags(
4329 events, [('end', 'root')])
4330 self.assertFalse(list(events))
4331 root = parser.close()
4332 self.assertEqual('root', root.tag)
4333
4335 class Target(etree.TreeBuilder):
4336 def end(self, tag):
4337 el = super(Target, self).end(tag)
4338 el.tag += '-huhu'
4339 return el
4340
4341 parser = self.etree.XMLPullParser(
4342 ['start', 'end'], target=Target())
4343 events = parser.read_events()
4344
4345 parser.feed('<root><element>')
4346 self.assert_event_tags(
4347 events, [('start', 'root'), ('start', 'element')])
4348 self.assertFalse(list(events))
4349 parser.feed('</element><child>')
4350 self.assert_event_tags(
4351 events, [('end', 'element-huhu'), ('start', 'child')])
4352 parser.feed('</child>')
4353 self.assert_event_tags(
4354 events, [('end', 'child-huhu')])
4355 parser.feed('</root>')
4356 self.assert_event_tags(
4357 events, [('end', 'root-huhu')])
4358 self.assertFalse(list(events))
4359 root = parser.close()
4360 self.assertEqual('root-huhu', root.tag)
4361
4362
4364 suite = unittest.TestSuite()
4365 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
4366 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
4367 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
4368 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
4369 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
4370 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
4371 suite.addTests([unittest.makeSuite(XMLPullParserTest)])
4372 suite.addTests(doctest.DocTestSuite(etree))
4373 suite.addTests(
4374 [make_doctest('../../../doc/tutorial.txt')])
4375 if sys.version_info >= (2,6):
4376 # now requires the 'with' statement
4377 suite.addTests(
4378 [make_doctest('../../../doc/api.txt')])
4379 suite.addTests(
4380 [make_doctest('../../../doc/FAQ.txt')])
4381 suite.addTests(
4382 [make_doctest('../../../doc/parsing.txt')])
4383 suite.addTests(
4384 [make_doctest('../../../doc/resolvers.txt')])
4385 return suite
4386
4387 if __name__ == '__main__':
4388 print('to test use test.py %s' % __file__)
4389
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Apr 25 16:24:39 2015 | http://epydoc.sourceforge.net |