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