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