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