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