| 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 parse = self.etree.parse
2920 tree = parse(fileInTestDir('include/test_xinclude.xml'))
2921
2922 self.assertEqual(
2923 [1, 2, 3],
2924 [ el.sourceline for el in tree.getiterator() ])
2925
2927 iterparse = self.etree.iterparse
2928 lines = [ el.sourceline for (event, el) in
2929 iterparse(fileInTestDir('include/test_xinclude.xml')) ]
2930
2931 self.assertEqual(
2932 [2, 3, 1],
2933 lines)
2934
2936 iterparse = self.etree.iterparse
2937 lines = [ el.sourceline for (event, el) in
2938 iterparse(fileInTestDir('include/test_xinclude.xml'),
2939 events=("start",)) ]
2940
2941 self.assertEqual(
2942 [1, 2, 3],
2943 lines)
2944
2946 Element = self.etree.Element
2947 SubElement = self.etree.SubElement
2948 el = Element("test")
2949 self.assertEqual(None, el.sourceline)
2950
2951 child = SubElement(el, "test")
2952 self.assertEqual(None, el.sourceline)
2953 self.assertEqual(None, child.sourceline)
2954
2956 etree = self.etree
2957 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2958 docinfo = root.getroottree().docinfo
2959 self.assertEqual(docinfo.URL, "http://no/such/url")
2960
2962 etree = self.etree
2963 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2964 docinfo = root.getroottree().docinfo
2965 self.assertEqual(docinfo.URL, "http://no/such/url")
2966 docinfo.URL = "https://secret/url"
2967 self.assertEqual(docinfo.URL, "https://secret/url")
2968
2970 etree = self.etree
2971 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
2972 docinfo = tree.docinfo
2973 self.assertEqual(docinfo.URL, "http://no/such/url")
2974
2976 etree = self.etree
2977 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
2978 base_url="http://no/such/url")
2979 docinfo = tree.docinfo
2980 self.assertEqual(docinfo.URL, "http://no/such/url")
2981
2983 etree = self.etree
2984 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
2985 docinfo = root.getroottree().docinfo
2986 self.assertEqual(docinfo.URL, "http://no/such/url")
2987
2989 etree = self.etree
2990 xml_header = '<?xml version="1.0" encoding="ascii"?>'
2991 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2992 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2993 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
2994
2995 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2996
2997 tree = etree.parse(BytesIO(xml))
2998 docinfo = tree.docinfo
2999 self.assertEqual(docinfo.encoding, "ascii")
3000 self.assertEqual(docinfo.xml_version, "1.0")
3001 self.assertEqual(docinfo.public_id, pub_id)
3002 self.assertEqual(docinfo.system_url, sys_id)
3003 self.assertEqual(docinfo.root_name, 'html')
3004 self.assertEqual(docinfo.doctype, doctype_string)
3005
3007 etree = self.etree
3008 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
3009 sys_id = "some.dtd"
3010 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
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, "UTF-8")
3016 self.assertEqual(docinfo.xml_version, "1.0")
3017 self.assertEqual(docinfo.public_id, None)
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 = _bytes('<html><body></body></html>')
3025 tree = etree.parse(BytesIO(xml))
3026 docinfo = tree.docinfo
3027 self.assertEqual(docinfo.encoding, "UTF-8")
3028 self.assertEqual(docinfo.xml_version, "1.0")
3029 self.assertEqual(docinfo.public_id, None)
3030 self.assertEqual(docinfo.system_url, None)
3031 self.assertEqual(docinfo.root_name, 'html')
3032 self.assertEqual(docinfo.doctype, '')
3033
3035 etree = self.etree
3036 xml = _bytes('<!DOCTYPE root><root></root>')
3037 tree = etree.parse(BytesIO(xml))
3038 docinfo = tree.docinfo
3039 self.assertEqual(docinfo.encoding, "UTF-8")
3040 self.assertEqual(docinfo.xml_version, "1.0")
3041 self.assertEqual(docinfo.public_id, None)
3042 self.assertEqual(docinfo.system_url, None)
3043 self.assertEqual(docinfo.root_name, 'root')
3044 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
3045
3047 etree = self.etree
3048 xml = _bytes('<!DOCTYPE root>\n<root/>')
3049 tree = etree.parse(BytesIO(xml))
3050 self.assertEqual(xml, etree.tostring(tree))
3051
3053 etree = self.etree
3054 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
3055 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
3056 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
3057
3058 xml = _bytes('<!DOCTYPE root>\n<root/>')
3059 tree = etree.parse(BytesIO(xml))
3060 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
3061 etree.tostring(tree, doctype=doctype_string))
3062
3064 etree = self.etree
3065 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3066 self.assertEqual(root.base, "http://no/such/url")
3067 self.assertEqual(
3068 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3069 root.base = "https://secret/url"
3070 self.assertEqual(root.base, "https://secret/url")
3071 self.assertEqual(
3072 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3073 "https://secret/url")
3074
3076 etree = self.etree
3077 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
3078 self.assertEqual(root.base, "http://no/such/url")
3079 self.assertEqual(
3080 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
3081 root.set('{http://www.w3.org/XML/1998/namespace}base',
3082 "https://secret/url")
3083 self.assertEqual(root.base, "https://secret/url")
3084 self.assertEqual(
3085 root.get('{http://www.w3.org/XML/1998/namespace}base'),
3086 "https://secret/url")
3087
3089 etree = self.etree
3090 root = etree.HTML(_bytes("<html><body></body></html>"),
3091 base_url="http://no/such/url")
3092 self.assertEqual(root.base, "http://no/such/url")
3093
3095 etree = self.etree
3096 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
3097 self.assertEqual(root.base, "http://no/such/url")
3098
3100 # parse from a file object that returns unicode strings
3101 f = LargeFileLikeUnicode()
3102 tree = self.etree.parse(f)
3103 root = tree.getroot()
3104 self.assertTrue(root.tag.endswith('root'))
3105
3107 # check that DTDs that go in also go back out
3108 xml = _bytes('''\
3109 <!DOCTYPE test SYSTEM "test.dtd" [
3110 <!ENTITY entity "tasty">
3111 <!ELEMENT test (a)>
3112 <!ELEMENT a (#PCDATA)>
3113 ]>
3114 <test><a>test-test</a></test>\
3115 ''')
3116 tree = self.etree.parse(BytesIO(xml))
3117 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
3118 xml.replace(_bytes(" "), _bytes("")))
3119
3121 Element = self.etree.Element
3122
3123 a = Element('a')
3124 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
3125 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
3126
3127 self.assertRaises(ValueError, Element, 'ha\0ho')
3128
3130 Element = self.etree.Element
3131
3132 a = Element('a')
3133 self.assertRaises(ValueError, setattr, a, "text",
3134 _str('ha\0ho'))
3135 self.assertRaises(ValueError, setattr, a, "tail",
3136 _str('ha\0ho'))
3137
3138 self.assertRaises(ValueError, Element,
3139 _str('ha\0ho'))
3140
3142 Element = self.etree.Element
3143
3144 a = Element('a')
3145 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
3146 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
3147
3148 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
3149 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
3150
3151 self.assertRaises(ValueError, Element, 'ha\x07ho')
3152 self.assertRaises(ValueError, Element, 'ha\x02ho')
3153
3155 Element = self.etree.Element
3156
3157 a = Element('a')
3158 self.assertRaises(ValueError, setattr, a, "text",
3159 _str('ha\x07ho'))
3160 self.assertRaises(ValueError, setattr, a, "text",
3161 _str('ha\x02ho'))
3162
3163 self.assertRaises(ValueError, setattr, a, "tail",
3164 _str('ha\x07ho'))
3165 self.assertRaises(ValueError, setattr, a, "tail",
3166 _str('ha\x02ho'))
3167
3168 self.assertRaises(ValueError, Element,
3169 _str('ha\x07ho'))
3170 self.assertRaises(ValueError, Element,
3171 _str('ha\x02ho'))
3172
3174 Element = self.etree.Element
3175
3176 a = Element('a')
3177 self.assertRaises(ValueError, setattr, a, "text",
3178 _str('ha\u1234\x07ho'))
3179 self.assertRaises(ValueError, setattr, a, "text",
3180 _str('ha\u1234\x02ho'))
3181
3182 self.assertRaises(ValueError, setattr, a, "tail",
3183 _str('ha\u1234\x07ho'))
3184 self.assertRaises(ValueError, setattr, a, "tail",
3185 _str('ha\u1234\x02ho'))
3186
3187 self.assertRaises(ValueError, Element,
3188 _str('ha\u1234\x07ho'))
3189 self.assertRaises(ValueError, Element,
3190 _str('ha\u1234\x02ho'))
3191
3193 # ElementTree fails to serialize this
3194 tostring = self.etree.tostring
3195 Element = self.etree.Element
3196 SubElement = self.etree.SubElement
3197
3198 a = Element('a')
3199 b = SubElement(a, 'b')
3200 c = SubElement(a, 'c')
3201
3202 result = tostring(a, encoding='UTF-16')
3203 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3204 canonicalize(result))
3205
3207 # ElementTree raises an AssertionError here
3208 tostring = self.etree.tostring
3209 self.assertRaises(TypeError, self.etree.tostring, None)
3210
3212 tostring = self.etree.tostring
3213 Element = self.etree.Element
3214 SubElement = self.etree.SubElement
3215
3216 a = Element('a')
3217 b = SubElement(a, 'b')
3218 c = SubElement(a, 'c')
3219
3220 result = tostring(a)
3221 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3222
3223 result = tostring(a, pretty_print=False)
3224 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3225
3226 result = tostring(a, pretty_print=True)
3227 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3228
3230 tostring = self.etree.tostring
3231 Element = self.etree.Element
3232 SubElement = self.etree.SubElement
3233
3234 a = Element('a')
3235 a.tail = "aTAIL"
3236 b = SubElement(a, 'b')
3237 b.tail = "bTAIL"
3238 c = SubElement(a, 'c')
3239
3240 result = tostring(a)
3241 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3242
3243 result = tostring(a, with_tail=False)
3244 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>"))
3245
3246 result = tostring(a, with_tail=True)
3247 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3248
3250 tostring = self.etree.tostring
3251 html = self.etree.fromstring(
3252 '<html><body>'
3253 '<div><p>Some text<i>\r\n</i></p></div>\r\n'
3254 '</body></html>',
3255 parser=self.etree.HTMLParser())
3256 self.assertEqual(html.tag, 'html')
3257 div = html.find('.//div')
3258 self.assertEqual(div.tail, '\r\n')
3259 result = tostring(div, method='html')
3260 self.assertEqual(
3261 result,
3262 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3263 result = tostring(div, method='html', with_tail=True)
3264 self.assertEqual(
3265 result,
3266 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n"))
3267 result = tostring(div, method='html', with_tail=False)
3268 self.assertEqual(
3269 result,
3270 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3271
3273 tostring = self.etree.tostring
3274 XML = self.etree.XML
3275 ElementTree = self.etree.ElementTree
3276 Element = self.etree.Element
3277
3278 tree = Element("root").getroottree()
3279 self.assertEqual(None, tree.docinfo.standalone)
3280
3281 tree = XML(_bytes("<root/>")).getroottree()
3282 self.assertEqual(None, tree.docinfo.standalone)
3283
3284 tree = XML(_bytes(
3285 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
3286 )).getroottree()
3287 self.assertEqual(True, tree.docinfo.standalone)
3288
3289 tree = XML(_bytes(
3290 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
3291 )).getroottree()
3292 self.assertEqual(False, tree.docinfo.standalone)
3293
3295 tostring = self.etree.tostring
3296 XML = self.etree.XML
3297 ElementTree = self.etree.ElementTree
3298
3299 root = XML(_bytes("<root/>"))
3300
3301 tree = ElementTree(root)
3302 self.assertEqual(None, tree.docinfo.standalone)
3303
3304 result = tostring(root, xml_declaration=True, encoding="ASCII")
3305 self.assertEqual(result, _bytes(
3306 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3307
3308 result = tostring(root, xml_declaration=True, encoding="ASCII",
3309 standalone=True)
3310 self.assertEqual(result, _bytes(
3311 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3312
3313 tree = ElementTree(XML(result))
3314 self.assertEqual(True, tree.docinfo.standalone)
3315
3316 result = tostring(root, xml_declaration=True, encoding="ASCII",
3317 standalone=False)
3318 self.assertEqual(result, _bytes(
3319 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3320
3321 tree = ElementTree(XML(result))
3322 self.assertEqual(False, tree.docinfo.standalone)
3323
3325 tostring = self.etree.tostring
3326 XML = self.etree.XML
3327 ElementTree = self.etree.ElementTree
3328
3329 root = XML(_bytes(
3330 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
3331
3332 tree = ElementTree(root)
3333 self.assertEqual(True, tree.docinfo.standalone)
3334
3335 result = tostring(root, xml_declaration=True, encoding="ASCII")
3336 self.assertEqual(result, _bytes(
3337 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3338
3339 result = tostring(root, xml_declaration=True, encoding="ASCII",
3340 standalone=True)
3341 self.assertEqual(result, _bytes(
3342 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3343
3345 tostring = self.etree.tostring
3346 Element = self.etree.Element
3347 SubElement = self.etree.SubElement
3348
3349 a = Element('a')
3350 a.text = "A"
3351 a.tail = "tail"
3352 b = SubElement(a, 'b')
3353 b.text = "B"
3354 b.tail = _str("Søk på nettet")
3355 c = SubElement(a, 'c')
3356 c.text = "C"
3357
3358 result = tostring(a, method="text", encoding="UTF-16")
3359
3360 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3361 result)
3362
3364 tostring = self.etree.tostring
3365 Element = self.etree.Element
3366 SubElement = self.etree.SubElement
3367
3368 a = Element('a')
3369 a.text = _str('Søk på nettetA')
3370 a.tail = "tail"
3371 b = SubElement(a, 'b')
3372 b.text = "B"
3373 b.tail = _str('Søk på nettetB')
3374 c = SubElement(a, 'c')
3375 c.text = "C"
3376
3377 self.assertRaises(UnicodeEncodeError,
3378 tostring, a, method="text")
3379
3380 self.assertEqual(
3381 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3382 tostring(a, encoding="UTF-8", method="text"))
3383
3385 tounicode = self.etree.tounicode
3386 Element = self.etree.Element
3387 SubElement = self.etree.SubElement
3388
3389 a = Element('a')
3390 b = SubElement(a, 'b')
3391 c = SubElement(a, 'c')
3392
3393 self.assertTrue(isinstance(tounicode(a), _unicode))
3394 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3395 canonicalize(tounicode(a)))
3396
3398 tounicode = self.etree.tounicode
3399 Element = self.etree.Element
3400 SubElement = self.etree.SubElement
3401
3402 a = Element('a')
3403 b = SubElement(a, 'b')
3404 c = SubElement(a, 'c')
3405 d = SubElement(c, 'd')
3406 self.assertTrue(isinstance(tounicode(b), _unicode))
3407 self.assertTrue(isinstance(tounicode(c), _unicode))
3408 self.assertEqual(_bytes('<b></b>'),
3409 canonicalize(tounicode(b)))
3410 self.assertEqual(_bytes('<c><d></d></c>'),
3411 canonicalize(tounicode(c)))
3412
3416
3418 tounicode = self.etree.tounicode
3419 Element = self.etree.Element
3420 SubElement = self.etree.SubElement
3421
3422 a = Element('a')
3423 b = SubElement(a, 'b')
3424 c = SubElement(a, 'c')
3425 d = SubElement(c, 'd')
3426 b.tail = 'Foo'
3427
3428 self.assertTrue(isinstance(tounicode(b), _unicode))
3429 self.assertTrue(tounicode(b) == '<b/>Foo' or
3430 tounicode(b) == '<b />Foo')
3431
3433 tounicode = self.etree.tounicode
3434 Element = self.etree.Element
3435 SubElement = self.etree.SubElement
3436
3437 a = Element('a')
3438 b = SubElement(a, 'b')
3439 c = SubElement(a, 'c')
3440
3441 result = tounicode(a)
3442 self.assertEqual(result, "<a><b/><c/></a>")
3443
3444 result = tounicode(a, pretty_print=False)
3445 self.assertEqual(result, "<a><b/><c/></a>")
3446
3447 result = tounicode(a, pretty_print=True)
3448 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3449
3451 tostring = self.etree.tostring
3452 Element = self.etree.Element
3453 SubElement = self.etree.SubElement
3454
3455 a = Element('a')
3456 b = SubElement(a, 'b')
3457 c = SubElement(a, 'c')
3458
3459 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode))
3460 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3461 canonicalize(tostring(a, encoding=_unicode)))
3462
3464 tostring = self.etree.tostring
3465 Element = self.etree.Element
3466 SubElement = self.etree.SubElement
3467
3468 a = Element('a')
3469 b = SubElement(a, 'b')
3470 c = SubElement(a, 'c')
3471 d = SubElement(c, 'd')
3472 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3473 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3474 self.assertEqual(_bytes('<b></b>'),
3475 canonicalize(tostring(b, encoding=_unicode)))
3476 self.assertEqual(_bytes('<c><d></d></c>'),
3477 canonicalize(tostring(c, encoding=_unicode)))
3478
3480 tostring = self.etree.tostring
3481 self.assertRaises(TypeError, self.etree.tostring,
3482 None, encoding=_unicode)
3483
3485 tostring = self.etree.tostring
3486 Element = self.etree.Element
3487 SubElement = self.etree.SubElement
3488
3489 a = Element('a')
3490 b = SubElement(a, 'b')
3491 c = SubElement(a, 'c')
3492 d = SubElement(c, 'd')
3493 b.tail = 'Foo'
3494
3495 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3496 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or
3497 tostring(b, encoding=_unicode) == '<b />Foo')
3498
3500 tostring = self.etree.tostring
3501 Element = self.etree.Element
3502 SubElement = self.etree.SubElement
3503
3504 a = Element('a')
3505 b = SubElement(a, 'b')
3506 c = SubElement(a, 'c')
3507
3508 result = tostring(a, encoding=_unicode)
3509 self.assertEqual(result, "<a><b/><c/></a>")
3510
3511 result = tostring(a, encoding=_unicode, pretty_print=False)
3512 self.assertEqual(result, "<a><b/><c/></a>")
3513
3514 result = tostring(a, encoding=_unicode, pretty_print=True)
3515 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3516
3518 root = etree.Element('parent')
3519 etree.SubElement(root, 'child')
3520
3521 self.assertEqual(len(root), 1)
3522 self.assertEqual(root[0].tag, 'child')
3523
3524 # in PyPy, GC used to kill the Python proxy instance without cleanup
3525 gc.collect()
3526 self.assertEqual(len(root), 1)
3527 self.assertEqual(root[0].tag, 'child')
3528
3532
3533 el1 = SubEl()
3534 el2 = SubEl()
3535 self.assertEqual('SubEl', el1.tag)
3536 self.assertEqual('SubEl', el2.tag)
3537 el1.other = el2
3538 el2.other = el1
3539
3540 del el1, el2
3541 gc.collect()
3542 # not really testing anything here, but it shouldn't crash
3543
3544 # helper methods
3545
3547 """Write out element for comparison.
3548 """
3549 ElementTree = self.etree.ElementTree
3550 f = BytesIO()
3551 tree = ElementTree(element=element)
3552 tree.write(f, encoding=encoding, compression=compression)
3553 data = f.getvalue()
3554 if compression:
3555 data = zlib.decompress(data)
3556 return canonicalize(data)
3557
3558
3561 filename = fileInTestDir('test_broken.xml')
3562 root = etree.XML(_bytes('''\
3563 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3564 <xi:include href="%s" parse="text"/>
3565 </doc>
3566 ''' % path2url(filename)))
3567 old_text = root.text
3568 content = read_file(filename)
3569 old_tail = root[0].tail
3570
3571 self.include( etree.ElementTree(root) )
3572 self.assertEqual(old_text + content + old_tail,
3573 root.text)
3574
3576 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
3577 self.assertNotEqual(
3578 'a',
3579 tree.getroot()[1].tag)
3580 # process xincludes
3581 self.include( tree )
3582 # check whether we find it replaced with included data
3583 self.assertEqual(
3584 'a',
3585 tree.getroot()[1].tag)
3586
3588 class res(etree.Resolver):
3589 include_text = read_file(fileInTestDir('test.xml'))
3590 called = {}
3591 def resolve(self, url, id, context):
3592 if url.endswith(".dtd"):
3593 self.called["dtd"] = True
3594 return self.resolve_filename(
3595 fileInTestDir('test.dtd'), context)
3596 elif url.endswith("test_xinclude.xml"):
3597 self.called["input"] = True
3598 return None # delegate to default resolver
3599 else:
3600 self.called["include"] = True
3601 return self.resolve_string(self.include_text, context)
3602
3603 res_instance = res()
3604 parser = etree.XMLParser(load_dtd = True)
3605 parser.resolvers.add(res_instance)
3606
3607 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3608 parser = parser)
3609
3610 self.include(tree)
3611
3612 called = list(res_instance.called.items())
3613 called.sort()
3614 self.assertEqual(
3615 [("dtd", True), ("include", True), ("input", True)],
3616 called)
3617
3618
3622
3623
3628
3629
3632 tree = self.parse(_bytes('<a><b/></a>'))
3633 f = BytesIO()
3634 tree.write_c14n(f)
3635 s = f.getvalue()
3636 self.assertEqual(_bytes('<a><b></b></a>'),
3637 s)
3638
3640 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3641 f = BytesIO()
3642 tree.write_c14n(f, compression=9)
3643 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3644 try:
3645 s = gzfile.read()
3646 finally:
3647 gzfile.close()
3648 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3649 s)
3650
3652 tree = self.parse(_bytes('<a><b/></a>'))
3653 handle, filename = tempfile.mkstemp()
3654 try:
3655 tree.write_c14n(filename)
3656 data = read_file(filename, 'rb')
3657 finally:
3658 os.close(handle)
3659 os.remove(filename)
3660 self.assertEqual(_bytes('<a><b></b></a>'),
3661 data)
3662
3664 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3665 handle, filename = tempfile.mkstemp()
3666 try:
3667 tree.write_c14n(filename, compression=9)
3668 f = gzip.open(filename, 'rb')
3669 try:
3670 data = f.read()
3671 finally:
3672 f.close()
3673 finally:
3674 os.close(handle)
3675 os.remove(filename)
3676 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3677 data)
3678
3680 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3681 f = BytesIO()
3682 tree.write_c14n(f)
3683 s = f.getvalue()
3684 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3685 s)
3686 f = BytesIO()
3687 tree.write_c14n(f, with_comments=True)
3688 s = f.getvalue()
3689 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3690 s)
3691 f = BytesIO()
3692 tree.write_c14n(f, with_comments=False)
3693 s = f.getvalue()
3694 self.assertEqual(_bytes('<a><b></b></a>'),
3695 s)
3696
3698 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3699 s = etree.tostring(tree, method='c14n')
3700 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3701 s)
3702 s = etree.tostring(tree, method='c14n', with_comments=True)
3703 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3704 s)
3705 s = etree.tostring(tree, method='c14n', with_comments=False)
3706 self.assertEqual(_bytes('<a><b></b></a>'),
3707 s)
3708
3710 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3711 s = etree.tostring(tree.getroot(), method='c14n')
3712 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
3713 s)
3714 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
3715 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
3716 s)
3717 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
3718 self.assertEqual(_bytes('<a><b></b></a>'),
3719 s)
3720
3722 tree = self.parse(_bytes(
3723 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3724 f = BytesIO()
3725 tree.write_c14n(f)
3726 s = f.getvalue()
3727 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3728 s)
3729 f = BytesIO()
3730 tree.write_c14n(f, exclusive=False)
3731 s = f.getvalue()
3732 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3733 s)
3734 f = BytesIO()
3735 tree.write_c14n(f, exclusive=True)
3736 s = f.getvalue()
3737 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3738 s)
3739
3740 f = BytesIO()
3741 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
3742 s = f.getvalue()
3743 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
3744 s)
3745
3747 tree = self.parse(_bytes(
3748 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3749 s = etree.tostring(tree, method='c14n')
3750 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3751 s)
3752 s = etree.tostring(tree, method='c14n', exclusive=False)
3753 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3754 s)
3755 s = etree.tostring(tree, method='c14n', exclusive=True)
3756 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3757 s)
3758
3759 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3760 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
3761 s)
3762
3764 tree = self.parse(_bytes(
3765 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3766 s = etree.tostring(tree.getroot(), method='c14n')
3767 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3768 s)
3769 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3770 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3771 s)
3772 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3773 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3774 s)
3775
3776 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3777 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3778 s)
3779 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3780 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3781 s)
3782
3783 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3784 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3785 s)
3786
3788 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
3789 tree = self.parse(_bytes(
3790 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3791
3792 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
3793 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3794 s)
3795
3796
3799 tree = self.parse(_bytes('<a><b/></a>'))
3800 f = BytesIO()
3801 tree.write(f)
3802 s = f.getvalue()
3803 self.assertEqual(_bytes('<a><b/></a>'),
3804 s)
3805
3807 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3808 f = BytesIO()
3809 tree.write(f, compression=9)
3810 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3811 try:
3812 s = gzfile.read()
3813 finally:
3814 gzfile.close()
3815 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3816 s)
3817
3819 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3820 f = BytesIO()
3821 tree.write(f, compression=0)
3822 s0 = f.getvalue()
3823
3824 f = BytesIO()
3825 tree.write(f)
3826 self.assertEqual(f.getvalue(), s0)
3827
3828 f = BytesIO()
3829 tree.write(f, compression=1)
3830 s = f.getvalue()
3831 self.assertTrue(len(s) <= len(s0))
3832 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3833 try:
3834 s1 = gzfile.read()
3835 finally:
3836 gzfile.close()
3837
3838 f = BytesIO()
3839 tree.write(f, compression=9)
3840 s = f.getvalue()
3841 self.assertTrue(len(s) <= len(s0))
3842 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3843 try:
3844 s9 = gzfile.read()
3845 finally:
3846 gzfile.close()
3847
3848 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3849 s0)
3850 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3851 s1)
3852 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3853 s9)
3854
3856 tree = self.parse(_bytes('<a><b/></a>'))
3857 handle, filename = tempfile.mkstemp()
3858 try:
3859 tree.write(filename)
3860 data = read_file(filename, 'rb')
3861 finally:
3862 os.close(handle)
3863 os.remove(filename)
3864 self.assertEqual(_bytes('<a><b/></a>'),
3865 data)
3866
3868 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3869 handle, filename = tempfile.mkstemp()
3870 try:
3871 tree.write(filename, compression=9)
3872 f = gzip.open(filename, 'rb')
3873 try:
3874 data = f.read()
3875 finally:
3876 f.close()
3877 finally:
3878 os.close(handle)
3879 os.remove(filename)
3880 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</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 data = etree.tostring(etree.parse(filename))
3889 finally:
3890 os.close(handle)
3891 os.remove(filename)
3892 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3893 data)
3894
3896 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3897 handle, filename = tempfile.mkstemp()
3898 try:
3899 tree.write(filename, compression=9)
3900 data = etree.tostring(etree.parse(
3901 gzip.GzipFile(filename)))
3902 finally:
3903 os.close(handle)
3904 os.remove(filename)
3905 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3906 data)
3907
3909 etree = etree
3910
3912 parse = self.etree.parse
3913 f = BytesIO('<a><b></c></b></a>')
3914 self.etree.clear_error_log()
3915 try:
3916 parse(f)
3917 logs = None
3918 except SyntaxError:
3919 e = sys.exc_info()[1]
3920 logs = e.error_log
3921 f.close()
3922 self.assertTrue([ log for log in logs
3923 if 'mismatch' in log.message ])
3924 self.assertTrue([ log for log in logs
3925 if 'PARSER' in log.domain_name])
3926 self.assertTrue([ log for log in logs
3927 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
3928 self.assertTrue([ log for log in logs
3929 if 1 == log.line ])
3930 self.assertTrue([ log for log in logs
3931 if 15 == log.column ])
3932
3943
3944 self.etree.use_global_python_log(Logger())
3945 f = BytesIO('<a><b></c></b></a>')
3946 try:
3947 parse(f)
3948 except SyntaxError:
3949 pass
3950 f.close()
3951
3952 self.assertTrue([ message for message in messages
3953 if 'mismatch' in message ])
3954 self.assertTrue([ message for message in messages
3955 if ':PARSER:' in message])
3956 self.assertTrue([ message for message in messages
3957 if ':ERR_TAG_NAME_MISMATCH:' in message ])
3958 self.assertTrue([ message for message in messages
3959 if ':1:15:' in message ])
3960
3961
3975 def close(self):
3976 return 'close()'
3977
3978 parser = self.etree.XMLPullParser(target=Target())
3979 events = parser.read_events()
3980
3981 parser.feed('<root><element>')
3982 self.assertFalse(list(events))
3983 self.assertFalse(list(events))
3984 parser.feed('</element><child>')
3985 self.assertEqual([('end', 'end(element)')], list(events))
3986 parser.feed('</child>')
3987 self.assertEqual([('end', 'end(child)')], list(events))
3988 parser.feed('</root>')
3989 self.assertEqual([('end', 'end(root)')], list(events))
3990 self.assertFalse(list(events))
3991 self.assertEqual('close()', parser.close())
3992
3997 def end(self, tag):
3998 return 'end(%s)' % tag
3999 def close(self):
4000 return 'close()'
4001
4002 parser = self.etree.XMLPullParser(
4003 ['start', 'end'], target=Target())
4004 events = parser.read_events()
4005
4006 parser.feed('<root><element>')
4007 self.assertEqual(
4008 [('start', 'start(root)'), ('start', 'start(element)')],
4009 list(events))
4010 self.assertFalse(list(events))
4011 parser.feed('</element><child>')
4012 self.assertEqual(
4013 [('end', 'end(element)'), ('start', 'start(child)')],
4014 list(events))
4015 parser.feed('</child>')
4016 self.assertEqual(
4017 [('end', 'end(child)')],
4018 list(events))
4019 parser.feed('</root>')
4020 self.assertEqual(
4021 [('end', 'end(root)')],
4022 list(events))
4023 self.assertFalse(list(events))
4024 self.assertEqual('close()', parser.close())
4025
4027 parser = self.etree.XMLPullParser(
4028 ['start', 'end'], target=etree.TreeBuilder())
4029 events = parser.read_events()
4030
4031 parser.feed('<root><element>')
4032 self.assert_event_tags(
4033 events, [('start', 'root'), ('start', 'element')])
4034 self.assertFalse(list(events))
4035 parser.feed('</element><child>')
4036 self.assert_event_tags(
4037 events, [('end', 'element'), ('start', 'child')])
4038 parser.feed('</child>')
4039 self.assert_event_tags(
4040 events, [('end', 'child')])
4041 parser.feed('</root>')
4042 self.assert_event_tags(
4043 events, [('end', 'root')])
4044 self.assertFalse(list(events))
4045 root = parser.close()
4046 self.assertEqual('root', root.tag)
4047
4049 class Target(etree.TreeBuilder):
4050 def end(self, tag):
4051 el = super(Target, self).end(tag)
4052 el.tag += '-huhu'
4053 return el
4054
4055 parser = self.etree.XMLPullParser(
4056 ['start', 'end'], target=Target())
4057 events = parser.read_events()
4058
4059 parser.feed('<root><element>')
4060 self.assert_event_tags(
4061 events, [('start', 'root'), ('start', 'element')])
4062 self.assertFalse(list(events))
4063 parser.feed('</element><child>')
4064 self.assert_event_tags(
4065 events, [('end', 'element-huhu'), ('start', 'child')])
4066 parser.feed('</child>')
4067 self.assert_event_tags(
4068 events, [('end', 'child-huhu')])
4069 parser.feed('</root>')
4070 self.assert_event_tags(
4071 events, [('end', 'root-huhu')])
4072 self.assertFalse(list(events))
4073 root = parser.close()
4074 self.assertEqual('root-huhu', root.tag)
4075
4076
4078 suite = unittest.TestSuite()
4079 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
4080 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
4081 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
4082 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
4083 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
4084 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
4085 suite.addTests([unittest.makeSuite(XMLPullParserTest)])
4086 suite.addTests(doctest.DocTestSuite(etree))
4087 suite.addTests(
4088 [make_doctest('../../../doc/tutorial.txt')])
4089 if sys.version_info >= (2,6):
4090 # now requires the 'with' statement
4091 suite.addTests(
4092 [make_doctest('../../../doc/api.txt')])
4093 suite.addTests(
4094 [make_doctest('../../../doc/FAQ.txt')])
4095 suite.addTests(
4096 [make_doctest('../../../doc/parsing.txt')])
4097 suite.addTests(
4098 [make_doctest('../../../doc/resolvers.txt')])
4099 return suite
4100
4101 if __name__ == '__main__':
4102 print('to test use test.py %s' % __file__)
4103
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Mar 4 19:19:03 2014 | http://epydoc.sourceforge.net |