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