| 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("""
659 <a> \n \n <b> b test </b> \n
660
661 \n\t <c> \n </c> </a> \n """)
662 iterator = iterparse(f, remove_blank_text=True)
663 text = [ (element.text, element.tail)
664 for event, element in iterator ]
665 self.assertEqual(
666 [(" b test ", None), (" \n ", None), (None, None)],
667 text)
668
670 iterparse = self.etree.iterparse
671 f = BytesIO('<a><b><d/></b><c/></a>')
672
673 iterator = iterparse(f, tag="b", events=('start', 'end'))
674 events = list(iterator)
675 root = iterator.root
676 self.assertEqual(
677 [('start', root[0]), ('end', root[0])],
678 events)
679
681 iterparse = self.etree.iterparse
682 f = BytesIO('<a><b><d/></b><c/></a>')
683
684 iterator = iterparse(f, tag="*", events=('start', 'end'))
685 events = list(iterator)
686 self.assertEqual(
687 8,
688 len(events))
689
691 iterparse = self.etree.iterparse
692 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
693
694 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
695 events = list(iterator)
696 root = iterator.root
697 self.assertEqual(
698 [('start', root[0]), ('end', root[0])],
699 events)
700
702 iterparse = self.etree.iterparse
703 f = BytesIO('<a><b><d/></b><c/></a>')
704 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
705 events = list(iterator)
706 root = iterator.root
707 self.assertEqual(
708 [('start', root[0]), ('end', root[0])],
709 events)
710
711 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
712 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
713 events = list(iterator)
714 root = iterator.root
715 self.assertEqual([], events)
716
718 iterparse = self.etree.iterparse
719 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
720 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
721 events = list(iterator)
722 self.assertEqual(8, len(events))
723
725 iterparse = self.etree.iterparse
726 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
727 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
728 events = list(iterator)
729 self.assertEqual([], events)
730
731 f = BytesIO('<a><b><d/></b><c/></a>')
732 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
733 events = list(iterator)
734 self.assertEqual(8, len(events))
735
737 text = _str('Søk på nettet')
738 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
739 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
740 ).encode('iso-8859-1')
741
742 self.assertRaises(self.etree.ParseError,
743 list, self.etree.iterparse(BytesIO(xml_latin1)))
744
746 text = _str('Søk på nettet', encoding="UTF-8")
747 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
748 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
749 ).encode('iso-8859-1')
750
751 iterator = self.etree.iterparse(BytesIO(xml_latin1),
752 encoding="iso-8859-1")
753 self.assertEqual(1, len(list(iterator)))
754
755 a = iterator.root
756 self.assertEqual(a.text, text)
757
759 tostring = self.etree.tostring
760 f = BytesIO('<root><![CDATA[test]]></root>')
761 context = self.etree.iterparse(f, strip_cdata=False)
762 content = [ el.text for event,el in context ]
763
764 self.assertEqual(['test'], content)
765 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
766 tostring(context.root))
767
771
773 self.etree.XMLParser(encoding="ascii")
774 self.etree.XMLParser(encoding="utf-8")
775 self.etree.XMLParser(encoding="iso-8859-1")
776
778 parser = self.etree.XMLParser(recover=True)
779
780 parser.feed('<?xml version=')
781 parser.feed('"1.0"?><ro')
782 parser.feed('ot><')
783 parser.feed('a test="works"')
784 parser.feed('><othertag/></root') # <a> not closed!
785 parser.feed('>')
786
787 root = parser.close()
788
789 self.assertEqual(root.tag, "root")
790 self.assertEqual(len(root), 1)
791 self.assertEqual(root[0].tag, "a")
792 self.assertEqual(root[0].get("test"), "works")
793 self.assertEqual(len(root[0]), 1)
794 self.assertEqual(root[0][0].tag, "othertag")
795 # FIXME: would be nice to get some errors logged ...
796 #self.assertTrue(len(parser.error_log) > 0, "error log is empty")
797
799 assertEqual = self.assertEqual
800 assertFalse = self.assertFalse
801
802 events = []
803 class Target(object):
804 def start(self, tag, attrib):
805 events.append("start")
806 assertFalse(attrib)
807 assertEqual("TAG", tag)
808 def end(self, tag):
809 events.append("end")
810 assertEqual("TAG", tag)
811 def close(self):
812 return "DONE" # no Element!
813
814 parser = self.etree.XMLParser(target=Target())
815 tree = self.etree.ElementTree()
816
817 self.assertRaises(TypeError,
818 tree.parse, BytesIO("<TAG/>"), parser=parser)
819 self.assertEqual(["start", "end"], events)
820
822 # ET doesn't call .close() on errors
823 events = []
824 class Target(object):
825 def start(self, tag, attrib):
826 events.append("start-" + tag)
827 def end(self, tag):
828 events.append("end-" + tag)
829 if tag == 'a':
830 raise ValueError("dead and gone")
831 def data(self, data):
832 events.append("data-" + data)
833 def close(self):
834 events.append("close")
835 return "DONE"
836
837 parser = self.etree.XMLParser(target=Target())
838
839 try:
840 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
841 done = parser.close()
842 self.fail("error expected, but parsing succeeded")
843 except ValueError:
844 done = 'value error received as expected'
845
846 self.assertEqual(["start-root", "data-A", "start-a",
847 "data-ca", "end-a", "close"],
848 events)
849
851 # ET doesn't call .close() on errors
852 events = []
853 class Target(object):
854 def start(self, tag, attrib):
855 events.append("start-" + tag)
856 def end(self, tag):
857 events.append("end-" + tag)
858 if tag == 'a':
859 raise ValueError("dead and gone")
860 def data(self, data):
861 events.append("data-" + data)
862 def close(self):
863 events.append("close")
864 return "DONE"
865
866 parser = self.etree.XMLParser(target=Target())
867
868 try:
869 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
870 parser=parser)
871 self.fail("error expected, but parsing succeeded")
872 except ValueError:
873 done = 'value error received as expected'
874
875 self.assertEqual(["start-root", "data-A", "start-a",
876 "data-ca", "end-a", "close"],
877 events)
878
880 events = []
881 class Target(object):
882 def start(self, tag, attrib):
883 events.append("start-" + tag)
884 def end(self, tag):
885 events.append("end-" + tag)
886 def data(self, data):
887 events.append("data-" + data)
888 def comment(self, text):
889 events.append("comment-" + text)
890 def close(self):
891 return "DONE"
892
893 parser = self.etree.XMLParser(target=Target())
894
895 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
896 done = parser.close()
897
898 self.assertEqual("DONE", done)
899 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
900 "start-sub", "end-sub", "comment-c", "data-B",
901 "end-root", "comment-d"],
902 events)
903
905 events = []
906 class Target(object):
907 def start(self, tag, attrib):
908 events.append("start-" + tag)
909 def end(self, tag):
910 events.append("end-" + tag)
911 def data(self, data):
912 events.append("data-" + data)
913 def pi(self, target, data):
914 events.append("pi-" + target + "-" + data)
915 def close(self):
916 return "DONE"
917
918 parser = self.etree.XMLParser(target=Target())
919
920 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
921 done = parser.close()
922
923 self.assertEqual("DONE", done)
924 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b",
925 "data-B", "end-root", "pi-test-c"],
926 events)
927
929 events = []
930 class Target(object):
931 def start(self, tag, attrib):
932 events.append("start-" + tag)
933 def end(self, tag):
934 events.append("end-" + tag)
935 def data(self, data):
936 events.append("data-" + data)
937 def close(self):
938 return "DONE"
939
940 parser = self.etree.XMLParser(target=Target(),
941 strip_cdata=False)
942
943 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
944 done = parser.close()
945
946 self.assertEqual("DONE", done)
947 self.assertEqual(["start-root", "data-A", "start-a",
948 "data-ca", "end-a", "data-B", "end-root"],
949 events)
950
952 events = []
953 class Target(object):
954 def start(self, tag, attrib):
955 events.append("start-" + tag)
956 def end(self, tag):
957 events.append("end-" + tag)
958 def data(self, data):
959 events.append("data-" + data)
960 def close(self):
961 events.append("close")
962 return "DONE"
963
964 parser = self.etree.XMLParser(target=Target(),
965 recover=True)
966
967 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
968 done = parser.close()
969
970 self.assertEqual("DONE", done)
971 self.assertEqual(["start-root", "data-A", "start-a",
972 "data-ca", "end-a", "data-B",
973 "end-root", "close"],
974 events)
975
977 iterwalk = self.etree.iterwalk
978 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
979
980 iterator = iterwalk(root, tag="b", events=('start', 'end'))
981 events = list(iterator)
982 self.assertEqual(
983 [('start', root[0]), ('end', root[0])],
984 events)
985
987 iterwalk = self.etree.iterwalk
988 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
989
990 iterator = iterwalk(root, tag="*", events=('start', 'end'))
991 events = list(iterator)
992 self.assertEqual(
993 8,
994 len(events))
995
997 iterwalk = self.etree.iterwalk
998 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
999
1000 events = list(iterwalk(root))
1001 self.assertEqual(
1002 [('end', root[0]), ('end', root[1]), ('end', root)],
1003 events)
1004
1006 iterwalk = self.etree.iterwalk
1007 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1008
1009 iterator = iterwalk(root, events=('start',))
1010 events = list(iterator)
1011 self.assertEqual(
1012 [('start', root), ('start', root[0]), ('start', root[1])],
1013 events)
1014
1016 iterwalk = self.etree.iterwalk
1017 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1018
1019 iterator = iterwalk(root, events=('start','end'))
1020 events = list(iterator)
1021 self.assertEqual(
1022 [('start', root), ('start', root[0]), ('end', root[0]),
1023 ('start', root[1]), ('end', root[1]), ('end', root)],
1024 events)
1025
1027 iterwalk = self.etree.iterwalk
1028 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1029
1030 iterator = iterwalk(root)
1031 for event, elem in iterator:
1032 elem.clear()
1033
1034 self.assertEqual(0,
1035 len(root))
1036
1038 iterwalk = self.etree.iterwalk
1039 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1040
1041 attr_name = '{testns}bla'
1042 events = []
1043 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1044 for event, elem in iterator:
1045 events.append(event)
1046 if event == 'start':
1047 if elem.tag != '{ns1}a':
1048 elem.set(attr_name, 'value')
1049
1050 self.assertEqual(
1051 ['start-ns', 'start', 'start', 'start-ns', 'start',
1052 'end', 'end-ns', 'end', 'end', 'end-ns'],
1053 events)
1054
1055 self.assertEqual(
1056 None,
1057 root.get(attr_name))
1058 self.assertEqual(
1059 'value',
1060 root[0].get(attr_name))
1061
1063 iterwalk = self.etree.iterwalk
1064 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
1065
1066 counts = []
1067 for event, elem in iterwalk(root):
1068 counts.append(len(list(elem.getiterator())))
1069 self.assertEqual(
1070 [1,2,1,4],
1071 counts)
1072
1074 parse = self.etree.parse
1075 parser = self.etree.XMLParser(dtd_validation=True)
1076 assertEqual = self.assertEqual
1077 test_url = _str("__nosuch.dtd")
1078
1079 class MyResolver(self.etree.Resolver):
1080 def resolve(self, url, id, context):
1081 assertEqual(url, test_url)
1082 return self.resolve_string(
1083 _str('''<!ENTITY myentity "%s">
1084 <!ELEMENT doc ANY>''') % url, context)
1085
1086 parser.resolvers.add(MyResolver())
1087
1088 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1089 tree = parse(StringIO(xml), parser)
1090 root = tree.getroot()
1091 self.assertEqual(root.text, test_url)
1092
1094 parse = self.etree.parse
1095 parser = self.etree.XMLParser(dtd_validation=True)
1096 assertEqual = self.assertEqual
1097 test_url = _str("__nosuch.dtd")
1098
1099 class MyResolver(self.etree.Resolver):
1100 def resolve(self, url, id, context):
1101 assertEqual(url, test_url)
1102 return self.resolve_string(
1103 (_str('''<!ENTITY myentity "%s">
1104 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1105 context)
1106
1107 parser.resolvers.add(MyResolver())
1108
1109 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1110 tree = parse(StringIO(xml), parser)
1111 root = tree.getroot()
1112 self.assertEqual(root.text, test_url)
1113
1115 parse = self.etree.parse
1116 parser = self.etree.XMLParser(dtd_validation=True)
1117 assertEqual = self.assertEqual
1118 test_url = _str("__nosuch.dtd")
1119
1120 class MyResolver(self.etree.Resolver):
1121 def resolve(self, url, id, context):
1122 assertEqual(url, test_url)
1123 return self.resolve_file(
1124 SillyFileLike(
1125 _str('''<!ENTITY myentity "%s">
1126 <!ELEMENT doc ANY>''') % url), context)
1127
1128 parser.resolvers.add(MyResolver())
1129
1130 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1131 tree = parse(StringIO(xml), parser)
1132 root = tree.getroot()
1133 self.assertEqual(root.text, test_url)
1134
1136 parse = self.etree.parse
1137 parser = self.etree.XMLParser(attribute_defaults=True)
1138 assertEqual = self.assertEqual
1139 test_url = _str("__nosuch.dtd")
1140
1141 class MyResolver(self.etree.Resolver):
1142 def resolve(self, url, id, context):
1143 assertEqual(url, test_url)
1144 return self.resolve_filename(
1145 fileInTestDir('test.dtd'), context)
1146
1147 parser.resolvers.add(MyResolver())
1148
1149 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1150 tree = parse(StringIO(xml), parser)
1151 root = tree.getroot()
1152 self.assertEqual(
1153 root.attrib, {'default': 'valueA'})
1154 self.assertEqual(
1155 root[0].attrib, {'default': 'valueB'})
1156
1158 parse = self.etree.parse
1159 parser = self.etree.XMLParser(attribute_defaults=True)
1160 assertEqual = self.assertEqual
1161 test_url = _str("__nosuch.dtd")
1162
1163 class MyResolver(self.etree.Resolver):
1164 def resolve(self, url, id, context):
1165 assertEqual(url, fileInTestDir(test_url))
1166 return self.resolve_filename(
1167 fileInTestDir('test.dtd'), context)
1168
1169 parser.resolvers.add(MyResolver())
1170
1171 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1172 tree = parse(StringIO(xml), parser,
1173 base_url=fileInTestDir('__test.xml'))
1174 root = tree.getroot()
1175 self.assertEqual(
1176 root.attrib, {'default': 'valueA'})
1177 self.assertEqual(
1178 root[0].attrib, {'default': 'valueB'})
1179
1181 parse = self.etree.parse
1182 parser = self.etree.XMLParser(attribute_defaults=True)
1183 assertEqual = self.assertEqual
1184 test_url = _str("__nosuch.dtd")
1185
1186 class MyResolver(self.etree.Resolver):
1187 def resolve(self, url, id, context):
1188 assertEqual(url, test_url)
1189 return self.resolve_file(
1190 open(fileInTestDir('test.dtd'), 'rb'), context)
1191
1192 parser.resolvers.add(MyResolver())
1193
1194 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1195 tree = parse(StringIO(xml), parser)
1196 root = tree.getroot()
1197 self.assertEqual(
1198 root.attrib, {'default': 'valueA'})
1199 self.assertEqual(
1200 root[0].attrib, {'default': 'valueB'})
1201
1203 parse = self.etree.parse
1204 parser = self.etree.XMLParser(load_dtd=True)
1205 assertEqual = self.assertEqual
1206 test_url = _str("__nosuch.dtd")
1207
1208 class check(object):
1209 resolved = False
1210
1211 class MyResolver(self.etree.Resolver):
1212 def resolve(self, url, id, context):
1213 assertEqual(url, test_url)
1214 check.resolved = True
1215 return self.resolve_empty(context)
1216
1217 parser.resolvers.add(MyResolver())
1218
1219 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1220 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1221 self.assertTrue(check.resolved)
1222
1224 parse = self.etree.parse
1225 parser = self.etree.XMLParser(dtd_validation=True)
1226
1227 class _LocalException(Exception):
1228 pass
1229
1230 class MyResolver(self.etree.Resolver):
1231 def resolve(self, url, id, context):
1232 raise _LocalException
1233
1234 parser.resolvers.add(MyResolver())
1235
1236 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1237 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1238
1239 if etree.LIBXML_VERSION > (2,6,20):
1241 parse = self.etree.parse
1242 tostring = self.etree.tostring
1243 parser = self.etree.XMLParser(resolve_entities=False)
1244 Entity = self.etree.Entity
1245
1246 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>')
1247 tree = parse(BytesIO(xml), parser)
1248 root = tree.getroot()
1249 self.assertEqual(root[0].tag, Entity)
1250 self.assertEqual(root[0].text, "&myentity;")
1251 self.assertEqual(root[0].tail, None)
1252 self.assertEqual(root[0].name, "myentity")
1253
1254 self.assertEqual(_bytes('<doc>&myentity;</doc>'),
1255 tostring(root))
1256
1258 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1259 <root>
1260 <child1/>
1261 <child2/>
1262 <child3> </child3>
1263 </root>''')
1264
1265 parser = self.etree.XMLParser(resolve_entities=False)
1266 root = etree.fromstring(xml, parser)
1267 self.assertEqual([ el.tag for el in root ],
1268 ['child1', 'child2', 'child3'])
1269
1270 root[0] = root[-1]
1271 self.assertEqual([ el.tag for el in root ],
1272 ['child3', 'child2'])
1273 self.assertEqual(root[0][0].text, ' ')
1274 self.assertEqual(root[0][0].name, 'nbsp')
1275
1277 Entity = self.etree.Entity
1278 Element = self.etree.Element
1279 tostring = self.etree.tostring
1280
1281 root = Element("root")
1282 root.append( Entity("test") )
1283
1284 self.assertEqual(root[0].tag, Entity)
1285 self.assertEqual(root[0].text, "&test;")
1286 self.assertEqual(root[0].tail, None)
1287 self.assertEqual(root[0].name, "test")
1288
1289 self.assertEqual(_bytes('<root>&test;</root>'),
1290 tostring(root))
1291
1293 Entity = self.etree.Entity
1294 self.assertEqual(Entity("test").text, '&test;')
1295 self.assertEqual(Entity("#17683").text, '䔓')
1296 self.assertEqual(Entity("#x1768").text, 'ᝨ')
1297 self.assertEqual(Entity("#x98AF").text, '颯')
1298
1300 Entity = self.etree.Entity
1301 self.assertRaises(ValueError, Entity, 'a b c')
1302 self.assertRaises(ValueError, Entity, 'a,b')
1303 self.assertRaises(ValueError, Entity, 'a\0b')
1304 self.assertRaises(ValueError, Entity, '#abc')
1305 self.assertRaises(ValueError, Entity, '#xxyz')
1306
1308 CDATA = self.etree.CDATA
1309 Element = self.etree.Element
1310 tostring = self.etree.tostring
1311
1312 root = Element("root")
1313 root.text = CDATA('test')
1314
1315 self.assertEqual('test',
1316 root.text)
1317 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1318 tostring(root))
1319
1321 CDATA = self.etree.CDATA
1322 Element = self.etree.Element
1323 root = Element("root")
1324
1325 root.text = CDATA("test")
1326 self.assertEqual('test', root.text)
1327
1328 root.text = CDATA(_str("test"))
1329 self.assertEqual('test', root.text)
1330
1331 self.assertRaises(TypeError, CDATA, 1)
1332
1334 CDATA = self.etree.CDATA
1335 Element = self.etree.Element
1336
1337 root = Element("root")
1338 cdata = CDATA('test')
1339
1340 self.assertRaises(TypeError,
1341 setattr, root, 'tail', cdata)
1342 self.assertRaises(TypeError,
1343 root.set, 'attr', cdata)
1344 self.assertRaises(TypeError,
1345 operator.setitem, root.attrib, 'attr', cdata)
1346
1348 tostring = self.etree.tostring
1349 parser = self.etree.XMLParser(strip_cdata=False)
1350 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1351
1352 self.assertEqual('test', root.text)
1353 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1354 tostring(root))
1355
1357 tostring = self.etree.tostring
1358 parser = self.etree.XMLParser(strip_cdata=False)
1359 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1360 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1361 tostring(root))
1362
1363 self.assertEqual(['test'], root.xpath('//text()'))
1364
1365 # TypeError in etree, AssertionError in ElementTree;
1367 Element = self.etree.Element
1368 SubElement = self.etree.SubElement
1369
1370 a = Element('a')
1371 b = SubElement(a, 'b')
1372
1373 self.assertRaises(TypeError,
1374 a.__setitem__, 0, 'foo')
1375
1377 Element = self.etree.Element
1378 root = Element('root')
1379 # raises AssertionError in ElementTree
1380 self.assertRaises(TypeError, root.append, None)
1381 self.assertRaises(TypeError, root.extend, [None])
1382 self.assertRaises(TypeError, root.extend, [Element('one'), None])
1383 self.assertEqual('one', root[0].tag)
1384
1386 Element = self.etree.Element
1387 SubElement = self.etree.SubElement
1388 root = Element('root')
1389 self.assertRaises(ValueError, root.append, root)
1390 child = SubElement(root, 'child')
1391 self.assertRaises(ValueError, child.append, root)
1392 child2 = SubElement(child, 'child2')
1393 self.assertRaises(ValueError, child2.append, root)
1394 self.assertRaises(ValueError, child2.append, child)
1395 self.assertEqual('child2', root[0][0].tag)
1396
1398 Element = self.etree.Element
1399 SubElement = self.etree.SubElement
1400 root = Element('root')
1401 SubElement(root, 'a')
1402 SubElement(root, 'b')
1403
1404 self.assertEqual(['a', 'b'],
1405 [c.tag for c in root])
1406 root[1].addnext(root[0])
1407 self.assertEqual(['b', 'a'],
1408 [c.tag for c in root])
1409
1411 Element = self.etree.Element
1412 SubElement = self.etree.SubElement
1413 root = Element('root')
1414 SubElement(root, 'a')
1415 SubElement(root, 'b')
1416
1417 self.assertEqual(['a', 'b'],
1418 [c.tag for c in root])
1419 root[0].addprevious(root[1])
1420 self.assertEqual(['b', 'a'],
1421 [c.tag for c in root])
1422
1424 Element = self.etree.Element
1425 SubElement = self.etree.SubElement
1426 root = Element('root')
1427 a = SubElement(root, 'a')
1428 b = SubElement(root, 'b')
1429 a.addprevious(a)
1430 self.assertEqual('a', root[0].tag)
1431 self.assertEqual('b', root[1].tag)
1432 b.addprevious(b)
1433 self.assertEqual('a', root[0].tag)
1434 self.assertEqual('b', root[1].tag)
1435 b.addprevious(a)
1436 self.assertEqual('a', root[0].tag)
1437 self.assertEqual('b', root[1].tag)
1438
1440 Element = self.etree.Element
1441 SubElement = self.etree.SubElement
1442 root = Element('root')
1443 a = SubElement(root, 'a')
1444 b = SubElement(root, 'b')
1445 a.addnext(a)
1446 self.assertEqual('a', root[0].tag)
1447 self.assertEqual('b', root[1].tag)
1448 b.addnext(b)
1449 self.assertEqual('a', root[0].tag)
1450 self.assertEqual('b', root[1].tag)
1451 a.addnext(b)
1452 self.assertEqual('a', root[0].tag)
1453 self.assertEqual('b', root[1].tag)
1454
1456 Element = self.etree.Element
1457 a = Element('a')
1458 b = Element('b')
1459 self.assertRaises(TypeError, a.addnext, b)
1460
1462 Element = self.etree.Element
1463 SubElement = self.etree.SubElement
1464 PI = self.etree.PI
1465 root = Element('root')
1466 SubElement(root, 'a')
1467 pi = PI('TARGET', 'TEXT')
1468 pi.tail = "TAIL"
1469
1470 self.assertEqual(_bytes('<root><a></a></root>'),
1471 self._writeElement(root))
1472 root[0].addprevious(pi)
1473 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
1474 self._writeElement(root))
1475
1477 Element = self.etree.Element
1478 PI = self.etree.PI
1479 root = Element('root')
1480 pi = PI('TARGET', 'TEXT')
1481 pi.tail = "TAIL"
1482
1483 self.assertEqual(_bytes('<root></root>'),
1484 self._writeElement(root))
1485 root.addprevious(pi)
1486 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'),
1487 self._writeElement(root))
1488
1490 Element = self.etree.Element
1491 SubElement = self.etree.SubElement
1492 PI = self.etree.PI
1493 root = Element('root')
1494 SubElement(root, 'a')
1495 pi = PI('TARGET', 'TEXT')
1496 pi.tail = "TAIL"
1497
1498 self.assertEqual(_bytes('<root><a></a></root>'),
1499 self._writeElement(root))
1500 root[0].addnext(pi)
1501 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
1502 self._writeElement(root))
1503
1505 Element = self.etree.Element
1506 PI = self.etree.PI
1507 root = Element('root')
1508 pi = PI('TARGET', 'TEXT')
1509 pi.tail = "TAIL"
1510
1511 self.assertEqual(_bytes('<root></root>'),
1512 self._writeElement(root))
1513 root.addnext(pi)
1514 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'),
1515 self._writeElement(root))
1516
1518 Element = self.etree.Element
1519 SubElement = self.etree.SubElement
1520 Comment = self.etree.Comment
1521 root = Element('root')
1522 SubElement(root, 'a')
1523 comment = Comment('TEXT ')
1524 comment.tail = "TAIL"
1525
1526 self.assertEqual(_bytes('<root><a></a></root>'),
1527 self._writeElement(root))
1528 root[0].addnext(comment)
1529 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
1530 self._writeElement(root))
1531
1533 Element = self.etree.Element
1534 Comment = self.etree.Comment
1535 root = Element('root')
1536 comment = Comment('TEXT ')
1537 comment.tail = "TAIL"
1538
1539 self.assertEqual(_bytes('<root></root>'),
1540 self._writeElement(root))
1541 root.addnext(comment)
1542 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'),
1543 self._writeElement(root))
1544
1546 Element = self.etree.Element
1547 SubElement = self.etree.SubElement
1548 Comment = self.etree.Comment
1549 root = Element('root')
1550 SubElement(root, 'a')
1551 comment = Comment('TEXT ')
1552 comment.tail = "TAIL"
1553
1554 self.assertEqual(_bytes('<root><a></a></root>'),
1555 self._writeElement(root))
1556 root[0].addprevious(comment)
1557 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
1558 self._writeElement(root))
1559
1561 Element = self.etree.Element
1562 Comment = self.etree.Comment
1563 root = Element('root')
1564 comment = Comment('TEXT ')
1565 comment.tail = "TAIL"
1566
1567 self.assertEqual(_bytes('<root></root>'),
1568 self._writeElement(root))
1569 root.addprevious(comment)
1570 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'),
1571 self._writeElement(root))
1572
1573 # ET's Elements have items() and key(), but not values()
1575 XML = self.etree.XML
1576
1577 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
1578 values = root.values()
1579 values.sort()
1580 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1581
1582 # gives error in ElementTree
1584 Element = self.etree.Element
1585 Comment = self.etree.Comment
1586
1587 a = Element('a')
1588 a.append(Comment())
1589 self.assertEqual(
1590 _bytes('<a><!----></a>'),
1591 self._writeElement(a))
1592
1593 # ElementTree ignores comments
1595 ElementTree = self.etree.ElementTree
1596 tostring = self.etree.tostring
1597
1598 xml = _bytes('<a><b/><!----><c/></a>')
1599 f = BytesIO(xml)
1600 doc = ElementTree(file=f)
1601 a = doc.getroot()
1602 self.assertEqual(
1603 '',
1604 a[1].text)
1605 self.assertEqual(
1606 xml,
1607 tostring(a))
1608
1609 # ElementTree ignores comments
1611 ElementTree = self.etree.ElementTree
1612
1613 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
1614 doc = ElementTree(file=f)
1615 a = doc.getroot()
1616 self.assertEqual(
1617 ' hoi ',
1618 a[1].text)
1619
1620 # does not raise an exception in ElementTree
1622 Element = self.etree.Element
1623 Comment = self.etree.Comment
1624
1625 c = Comment()
1626 el = Element('myel')
1627
1628 self.assertRaises(TypeError, c.append, el)
1629 self.assertRaises(TypeError, c.insert, 0, el)
1630 self.assertRaises(TypeError, c.set, "myattr", "test")
1631
1632 # test passing 'None' to dump
1635
1637 ElementTree = self.etree.ElementTree
1638
1639 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
1640 doc = ElementTree(file=f)
1641 a = doc.getroot()
1642 self.assertEqual(
1643 None,
1644 a.prefix)
1645 self.assertEqual(
1646 'foo',
1647 a[0].prefix)
1648
1650 ElementTree = self.etree.ElementTree
1651
1652 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
1653 doc = ElementTree(file=f)
1654 a = doc.getroot()
1655 self.assertEqual(
1656 None,
1657 a.prefix)
1658 self.assertEqual(
1659 None,
1660 a[0].prefix)
1661
1663 Element = self.etree.Element
1664 SubElement = self.etree.SubElement
1665
1666 a = Element('a')
1667 b = SubElement(a, 'b')
1668 c = SubElement(a, 'c')
1669 d = SubElement(b, 'd')
1670 self.assertEqual(
1671 None,
1672 a.getparent())
1673 self.assertEqual(
1674 a,
1675 b.getparent())
1676 self.assertEqual(
1677 b.getparent(),
1678 c.getparent())
1679 self.assertEqual(
1680 b,
1681 d.getparent())
1682
1684 XML = self.etree.XML
1685
1686 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
1687 result = []
1688 for el in root.iterchildren():
1689 result.append(el.tag)
1690 self.assertEqual(['one', 'two', 'three'], result)
1691
1693 XML = self.etree.XML
1694
1695 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
1696 result = []
1697 for el in root.iterchildren(reversed=True):
1698 result.append(el.tag)
1699 self.assertEqual(['three', 'two', 'one'], result)
1700
1702 XML = self.etree.XML
1703
1704 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1705 result = []
1706 for el in root.iterchildren(tag='two'):
1707 result.append(el.text)
1708 self.assertEqual(['Two', 'Bla'], result)
1709
1711 XML = self.etree.XML
1712
1713 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1714 result = []
1715 for el in root.iterchildren(reversed=True, tag='two'):
1716 result.append(el.text)
1717 self.assertEqual(['Bla', 'Two'], result)
1718
1720 XML = self.etree.XML
1721
1722 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1723 result = []
1724 for el in root.iterchildren(tag=['two', 'three']):
1725 result.append(el.text)
1726 self.assertEqual(['Two', 'Bla', None], result)
1727
1729 XML = self.etree.XML
1730
1731 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1732 result = []
1733 for el in root.iterchildren(reversed=True, tag=['two', 'three']):
1734 result.append(el.text)
1735 self.assertEqual([None, 'Bla', 'Two'], result)
1736
1738 Element = self.etree.Element
1739 SubElement = self.etree.SubElement
1740
1741 a = Element('a')
1742 b = SubElement(a, 'b')
1743 c = SubElement(a, 'c')
1744 d = SubElement(b, 'd')
1745 self.assertEqual(
1746 [],
1747 list(a.iterancestors()))
1748 self.assertEqual(
1749 [a],
1750 list(b.iterancestors()))
1751 self.assertEqual(
1752 [a],
1753 list(c.iterancestors()))
1754 self.assertEqual(
1755 [b, a],
1756 list(d.iterancestors()))
1757
1759 Element = self.etree.Element
1760 SubElement = self.etree.SubElement
1761
1762 a = Element('a')
1763 b = SubElement(a, 'b')
1764 c = SubElement(a, 'c')
1765 d = SubElement(b, 'd')
1766 self.assertEqual(
1767 [a],
1768 list(d.iterancestors(tag='a')))
1769 self.assertEqual(
1770 [b, a],
1771 list(d.iterancestors(tag='*')))
1772
1774 Element = self.etree.Element
1775 SubElement = self.etree.SubElement
1776
1777 a = Element('a')
1778 b = SubElement(a, 'b')
1779 c = SubElement(a, 'c')
1780 d = SubElement(b, 'd')
1781 self.assertEqual(
1782 [b, a],
1783 list(d.iterancestors(tag=('a', 'b'))))
1784 self.assertEqual(
1785 [],
1786 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
1787 self.assertEqual(
1788 [],
1789 list(d.iterancestors(tag=('d', 'x'))))
1790 self.assertEqual(
1791 [b, a],
1792 list(d.iterancestors(tag=('b', '*'))))
1793 self.assertEqual(
1794 [b],
1795 list(d.iterancestors(tag=('b', 'c'))))
1796
1798 Element = self.etree.Element
1799 SubElement = self.etree.SubElement
1800
1801 a = Element('a')
1802 b = SubElement(a, 'b')
1803 c = SubElement(a, 'c')
1804 d = SubElement(b, 'd')
1805 e = SubElement(c, 'e')
1806
1807 self.assertEqual(
1808 [b, d, c, e],
1809 list(a.iterdescendants()))
1810 self.assertEqual(
1811 [],
1812 list(d.iterdescendants()))
1813
1815 Element = self.etree.Element
1816 SubElement = self.etree.SubElement
1817
1818 a = Element('a')
1819 b = SubElement(a, 'b')
1820 c = SubElement(a, 'c')
1821 d = SubElement(b, 'd')
1822 e = SubElement(c, 'e')
1823
1824 self.assertEqual(
1825 [],
1826 list(a.iterdescendants('a')))
1827 a2 = SubElement(e, 'a')
1828 self.assertEqual(
1829 [a2],
1830 list(a.iterdescendants('a')))
1831 self.assertEqual(
1832 [a2],
1833 list(c.iterdescendants('a')))
1834
1836 Element = self.etree.Element
1837 SubElement = self.etree.SubElement
1838
1839 a = Element('a')
1840 b = SubElement(a, 'b')
1841 c = SubElement(a, 'c')
1842 d = SubElement(b, 'd')
1843 e = SubElement(c, 'e')
1844
1845 self.assertEqual(
1846 [b, e],
1847 list(a.iterdescendants(tag=('a', 'b', 'e'))))
1848 a2 = SubElement(e, 'a')
1849 self.assertEqual(
1850 [b, a2],
1851 list(a.iterdescendants(tag=('a', 'b'))))
1852 self.assertEqual(
1853 [],
1854 list(c.iterdescendants(tag=('x', 'y', 'z'))))
1855 self.assertEqual(
1856 [b, d, c, e, a2],
1857 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
1858
1860 Element = self.etree.Element
1861 SubElement = self.etree.SubElement
1862
1863 a = Element('a')
1864 b = SubElement(a, 'b')
1865 c = SubElement(a, 'c')
1866 d = SubElement(b, 'd')
1867 self.assertEqual(
1868 a,
1869 a.getroottree().getroot())
1870 self.assertEqual(
1871 a,
1872 b.getroottree().getroot())
1873 self.assertEqual(
1874 a,
1875 d.getroottree().getroot())
1876
1878 Element = self.etree.Element
1879 SubElement = self.etree.SubElement
1880
1881 a = Element('a')
1882 b = SubElement(a, 'b')
1883 c = SubElement(a, 'c')
1884 self.assertEqual(
1885 None,
1886 a.getnext())
1887 self.assertEqual(
1888 c,
1889 b.getnext())
1890 self.assertEqual(
1891 None,
1892 c.getnext())
1893
1895 Element = self.etree.Element
1896 SubElement = self.etree.SubElement
1897
1898 a = Element('a')
1899 b = SubElement(a, 'b')
1900 c = SubElement(a, 'c')
1901 d = SubElement(b, 'd')
1902 self.assertEqual(
1903 None,
1904 a.getprevious())
1905 self.assertEqual(
1906 b,
1907 c.getprevious())
1908 self.assertEqual(
1909 None,
1910 b.getprevious())
1911
1913 Element = self.etree.Element
1914 SubElement = self.etree.SubElement
1915
1916 a = Element('a')
1917 b = SubElement(a, 'b')
1918 c = SubElement(a, 'c')
1919 d = SubElement(b, 'd')
1920 self.assertEqual(
1921 [],
1922 list(a.itersiblings()))
1923 self.assertEqual(
1924 [c],
1925 list(b.itersiblings()))
1926 self.assertEqual(
1927 [],
1928 list(c.itersiblings()))
1929 self.assertEqual(
1930 [b],
1931 list(c.itersiblings(preceding=True)))
1932 self.assertEqual(
1933 [],
1934 list(b.itersiblings(preceding=True)))
1935
1937 Element = self.etree.Element
1938 SubElement = self.etree.SubElement
1939
1940 a = Element('a')
1941 b = SubElement(a, 'b')
1942 c = SubElement(a, 'c')
1943 d = SubElement(b, 'd')
1944 self.assertEqual(
1945 [],
1946 list(a.itersiblings(tag='XXX')))
1947 self.assertEqual(
1948 [c],
1949 list(b.itersiblings(tag='c')))
1950 self.assertEqual(
1951 [c],
1952 list(b.itersiblings(tag='*')))
1953 self.assertEqual(
1954 [b],
1955 list(c.itersiblings(preceding=True, tag='b')))
1956 self.assertEqual(
1957 [],
1958 list(c.itersiblings(preceding=True, tag='c')))
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 e = SubElement(a, 'e')
1969 self.assertEqual(
1970 [],
1971 list(a.itersiblings(tag=('XXX', 'YYY'))))
1972 self.assertEqual(
1973 [c, e],
1974 list(b.itersiblings(tag=('c', 'd', 'e'))))
1975 self.assertEqual(
1976 [b],
1977 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
1978 self.assertEqual(
1979 [c, b],
1980 list(e.itersiblings(preceding=True, tag=('c', '*'))))
1981
1983 parseid = self.etree.parseid
1984 XML = self.etree.XML
1985 xml_text = _bytes('''
1986 <!DOCTYPE document [
1987 <!ELEMENT document (h1,p)*>
1988 <!ELEMENT h1 (#PCDATA)>
1989 <!ATTLIST h1 myid ID #REQUIRED>
1990 <!ELEMENT p (#PCDATA)>
1991 <!ATTLIST p someid ID #REQUIRED>
1992 ]>
1993 <document>
1994 <h1 myid="chapter1">...</h1>
1995 <p id="note1" class="note">...</p>
1996 <p>Regular paragraph.</p>
1997 <p xml:id="xmlid">XML:ID paragraph.</p>
1998 <p someid="warn1" class="warning">...</p>
1999 </document>
2000 ''')
2001
2002 tree, dic = parseid(BytesIO(xml_text))
2003 root = tree.getroot()
2004 root2 = XML(xml_text)
2005 self.assertEqual(self._writeElement(root),
2006 self._writeElement(root2))
2007 expected = {
2008 "chapter1" : root[0],
2009 "xmlid" : root[3],
2010 "warn1" : root[4]
2011 }
2012 self.assertTrue("chapter1" in dic)
2013 self.assertTrue("warn1" in dic)
2014 self.assertTrue("xmlid" in dic)
2015 self._checkIDDict(dic, expected)
2016
2018 XMLDTDID = self.etree.XMLDTDID
2019 XML = self.etree.XML
2020 xml_text = _bytes('''
2021 <!DOCTYPE document [
2022 <!ELEMENT document (h1,p)*>
2023 <!ELEMENT h1 (#PCDATA)>
2024 <!ATTLIST h1 myid ID #REQUIRED>
2025 <!ELEMENT p (#PCDATA)>
2026 <!ATTLIST p someid ID #REQUIRED>
2027 ]>
2028 <document>
2029 <h1 myid="chapter1">...</h1>
2030 <p id="note1" class="note">...</p>
2031 <p>Regular paragraph.</p>
2032 <p xml:id="xmlid">XML:ID paragraph.</p>
2033 <p someid="warn1" class="warning">...</p>
2034 </document>
2035 ''')
2036
2037 root, dic = XMLDTDID(xml_text)
2038 root2 = XML(xml_text)
2039 self.assertEqual(self._writeElement(root),
2040 self._writeElement(root2))
2041 expected = {
2042 "chapter1" : root[0],
2043 "xmlid" : root[3],
2044 "warn1" : root[4]
2045 }
2046 self.assertTrue("chapter1" in dic)
2047 self.assertTrue("warn1" in dic)
2048 self.assertTrue("xmlid" in dic)
2049 self._checkIDDict(dic, expected)
2050
2052 XMLDTDID = self.etree.XMLDTDID
2053 XML = self.etree.XML
2054 xml_text = _bytes('''
2055 <document>
2056 <h1 myid="chapter1">...</h1>
2057 <p id="note1" class="note">...</p>
2058 <p>Regular paragraph.</p>
2059 <p someid="warn1" class="warning">...</p>
2060 </document>
2061 ''')
2062
2063 root, dic = XMLDTDID(xml_text)
2064 root2 = XML(xml_text)
2065 self.assertEqual(self._writeElement(root),
2066 self._writeElement(root2))
2067 expected = {}
2068 self._checkIDDict(dic, expected)
2069
2071 self.assertEqual(len(dic),
2072 len(expected))
2073 self.assertEqual(sorted(dic.items()),
2074 sorted(expected.items()))
2075 if sys.version_info < (3,):
2076 self.assertEqual(sorted(dic.iteritems()),
2077 sorted(expected.iteritems()))
2078 self.assertEqual(sorted(dic.keys()),
2079 sorted(expected.keys()))
2080 if sys.version_info < (3,):
2081 self.assertEqual(sorted(dic.iterkeys()),
2082 sorted(expected.iterkeys()))
2083 if sys.version_info < (3,):
2084 self.assertEqual(sorted(dic.values()),
2085 sorted(expected.values()))
2086 self.assertEqual(sorted(dic.itervalues()),
2087 sorted(expected.itervalues()))
2088
2090 etree = self.etree
2091
2092 r = {'foo': 'http://ns.infrae.com/foo'}
2093 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2094 self.assertEqual(
2095 'foo',
2096 e.prefix)
2097 self.assertEqual(
2098 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2099 self._writeElement(e))
2100
2102 etree = self.etree
2103
2104 r = {None: 'http://ns.infrae.com/foo'}
2105 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2106 self.assertEqual(
2107 None,
2108 e.prefix)
2109 self.assertEqual(
2110 '{http://ns.infrae.com/foo}bar',
2111 e.tag)
2112 self.assertEqual(
2113 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2114 self._writeElement(e))
2115
2117 etree = self.etree
2118
2119 r = {None: 'http://ns.infrae.com/foo',
2120 'hoi': 'http://ns.infrae.com/hoi'}
2121 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2122 e.set('{http://ns.infrae.com/hoi}test', 'value')
2123 self.assertEqual(
2124 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2125 self._writeElement(e))
2126
2128 etree = self.etree
2129
2130 root = etree.Element('{http://test/ns}root',
2131 nsmap={None: 'http://test/ns'})
2132 sub = etree.Element('{http://test/ns}sub',
2133 nsmap={'test': 'http://test/ns'})
2134
2135 sub.attrib['{http://test/ns}attr'] = 'value'
2136 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2137 self.assertEqual(
2138 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2139 etree.tostring(sub))
2140
2141 root.append(sub)
2142 self.assertEqual(
2143 _bytes('<root xmlns="http://test/ns">'
2144 '<sub xmlns:test="http://test/ns" test:attr="value"/>'
2145 '</root>'),
2146 etree.tostring(root))
2147
2149 etree = self.etree
2150
2151 root = etree.Element('root')
2152 sub = etree.Element('{http://test/ns}sub',
2153 nsmap={'test': 'http://test/ns'})
2154
2155 sub.attrib['{http://test/ns}attr'] = 'value'
2156 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2157 self.assertEqual(
2158 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'),
2159 etree.tostring(sub))
2160
2161 root.append(sub)
2162 self.assertEqual(
2163 _bytes('<root>'
2164 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>'
2165 '</root>'),
2166 etree.tostring(root))
2167
2169 etree = self.etree
2170
2171 root = etree.Element('root')
2172 sub = etree.Element('{http://test/ns}sub',
2173 nsmap={None: 'http://test/ns'})
2174
2175 sub.attrib['{http://test/ns}attr'] = 'value'
2176 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2177 self.assertEqual(
2178 _bytes('<sub xmlns="http://test/ns" '
2179 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2180 etree.tostring(sub))
2181
2182 root.append(sub)
2183 self.assertEqual(
2184 _bytes('<root>'
2185 '<sub xmlns="http://test/ns"'
2186 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>'
2187 '</root>'),
2188 etree.tostring(root))
2189
2191 etree = self.etree
2192
2193 root = etree.Element('{http://test/ns}root',
2194 nsmap={'test': 'http://test/ns',
2195 None: 'http://test/ns'})
2196 sub = etree.Element('{http://test/ns}sub',
2197 nsmap={None: 'http://test/ns'})
2198
2199 sub.attrib['{http://test/ns}attr'] = 'value'
2200 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value')
2201 self.assertEqual(
2202 _bytes('<sub xmlns="http://test/ns" '
2203 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'),
2204 etree.tostring(sub))
2205
2206 root.append(sub)
2207 self.assertEqual(
2208 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">'
2209 '<test:sub test:attr="value"/>'
2210 '</test:root>'),
2211 etree.tostring(root))
2212
2214 etree = self.etree
2215 r = {None: 'http://ns.infrae.com/foo',
2216 'hoi': 'http://ns.infrae.com/hoi'}
2217 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2218 tree = etree.ElementTree(element=e)
2219 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2220 self.assertEqual(
2221 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2222 self._writeElement(e))
2223
2225 etree = self.etree
2226
2227 r = {None: 'http://ns.infrae.com/foo'}
2228 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2229 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2230
2231 e1.append(e2)
2232
2233 self.assertEqual(
2234 None,
2235 e1.prefix)
2236 self.assertEqual(
2237 None,
2238 e1[0].prefix)
2239 self.assertEqual(
2240 '{http://ns.infrae.com/foo}bar',
2241 e1.tag)
2242 self.assertEqual(
2243 '{http://ns.infrae.com/foo}bar',
2244 e1[0].tag)
2245
2247 etree = self.etree
2248
2249 r = {None: 'http://ns.infrae.com/BAR'}
2250 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2251 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2252
2253 e1.append(e2)
2254
2255 self.assertEqual(
2256 None,
2257 e1.prefix)
2258 self.assertNotEqual(
2259 None,
2260 e2.prefix)
2261 self.assertEqual(
2262 '{http://ns.infrae.com/BAR}bar',
2263 e1.tag)
2264 self.assertEqual(
2265 '{http://ns.infrae.com/foo}bar',
2266 e2.tag)
2267
2269 ns_href = "http://a.b.c"
2270 one = self.etree.fromstring(
2271 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2272 baz = one[0][0]
2273
2274 two = self.etree.fromstring(
2275 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2276 two.append(baz)
2277 del one # make sure the source document is deallocated
2278
2279 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2280 self.assertEqual(
2281 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2282 self.etree.tostring(two))
2283
2285 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>')
2286 root = self.etree.fromstring(xml)
2287 self.assertEqual(xml,
2288 self.etree.tostring(root))
2289 self.etree.cleanup_namespaces(root)
2290 self.assertEqual(
2291 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
2292 self.etree.tostring(root))
2293
2295 etree = self.etree
2296
2297 r = {None: 'http://ns.infrae.com/foo',
2298 'hoi': 'http://ns.infrae.com/hoi'}
2299 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2300 self.assertEqual(
2301 r,
2302 e.nsmap)
2303
2305 etree = self.etree
2306
2307 re = {None: 'http://ns.infrae.com/foo',
2308 'hoi': 'http://ns.infrae.com/hoi'}
2309 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2310
2311 rs = {None: 'http://ns.infrae.com/honk',
2312 'top': 'http://ns.infrae.com/top'}
2313 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2314
2315 r = re.copy()
2316 r.update(rs)
2317 self.assertEqual(re, e.nsmap)
2318 self.assertEqual(r, s.nsmap)
2319
2321 etree = self.etree
2322 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2323 self.assertEqual({'hha': None}, el.nsmap)
2324
2326 Element = self.etree.Element
2327 SubElement = self.etree.SubElement
2328
2329 a = Element('a')
2330 b = SubElement(a, 'b')
2331 c = SubElement(a, 'c')
2332 d = SubElement(b, 'd')
2333 e = SubElement(c, 'e')
2334 f = SubElement(c, 'f')
2335
2336 self.assertEqual(
2337 [a, b],
2338 list(a.getiterator('a', 'b')))
2339 self.assertEqual(
2340 [],
2341 list(a.getiterator('x', 'y')))
2342 self.assertEqual(
2343 [a, f],
2344 list(a.getiterator('f', 'a')))
2345 self.assertEqual(
2346 [c, e, f],
2347 list(c.getiterator('c', '*', 'a')))
2348 self.assertEqual(
2349 [],
2350 list(a.getiterator( (), () )))
2351
2353 Element = self.etree.Element
2354 SubElement = self.etree.SubElement
2355
2356 a = Element('a')
2357 b = SubElement(a, 'b')
2358 c = SubElement(a, 'c')
2359 d = SubElement(b, 'd')
2360 e = SubElement(c, 'e')
2361 f = SubElement(c, 'f')
2362
2363 self.assertEqual(
2364 [a, b],
2365 list(a.getiterator( ('a', 'b') )))
2366 self.assertEqual(
2367 [],
2368 list(a.getiterator( ('x', 'y') )))
2369 self.assertEqual(
2370 [a, f],
2371 list(a.getiterator( ('f', 'a') )))
2372 self.assertEqual(
2373 [c, e, f],
2374 list(c.getiterator( ('c', '*', 'a') )))
2375 self.assertEqual(
2376 [],
2377 list(a.getiterator( () )))
2378
2380 Element = self.etree.Element
2381 SubElement = self.etree.SubElement
2382
2383 a = Element('{a}a')
2384 b = SubElement(a, '{a}b')
2385 c = SubElement(a, '{a}c')
2386 d = SubElement(b, '{b}d')
2387 e = SubElement(c, '{a}e')
2388 f = SubElement(c, '{b}f')
2389 g = SubElement(c, 'g')
2390
2391 self.assertEqual(
2392 [a],
2393 list(a.getiterator('{a}a')))
2394 self.assertEqual(
2395 [],
2396 list(a.getiterator('{b}a')))
2397 self.assertEqual(
2398 [],
2399 list(a.getiterator('a')))
2400 self.assertEqual(
2401 [a,b,d,c,e,f,g],
2402 list(a.getiterator('*')))
2403 self.assertEqual(
2404 [f],
2405 list(c.getiterator('{b}*')))
2406 self.assertEqual(
2407 [d, f],
2408 list(a.getiterator('{b}*')))
2409 self.assertEqual(
2410 [g],
2411 list(a.getiterator('g')))
2412 self.assertEqual(
2413 [g],
2414 list(a.getiterator('{}g')))
2415 self.assertEqual(
2416 [g],
2417 list(a.getiterator('{}*')))
2418
2420 Element = self.etree.Element
2421 SubElement = self.etree.SubElement
2422
2423 a = Element('{a}a')
2424 b = SubElement(a, '{nsA}b')
2425 c = SubElement(b, '{nsB}b')
2426 d = SubElement(a, 'b')
2427 e = SubElement(a, '{nsA}e')
2428 f = SubElement(e, '{nsB}e')
2429 g = SubElement(e, 'e')
2430
2431 self.assertEqual(
2432 [b, c, d],
2433 list(a.getiterator('{*}b')))
2434 self.assertEqual(
2435 [e, f, g],
2436 list(a.getiterator('{*}e')))
2437 self.assertEqual(
2438 [a, b, c, d, e, f, g],
2439 list(a.getiterator('{*}*')))
2440
2442 Element = self.etree.Element
2443 Entity = self.etree.Entity
2444 SubElement = self.etree.SubElement
2445
2446 a = Element('a')
2447 b = SubElement(a, 'b')
2448 entity_b = Entity("TEST-b")
2449 b.append(entity_b)
2450
2451 self.assertEqual(
2452 [entity_b],
2453 list(a.getiterator(Entity)))
2454
2455 entity_a = Entity("TEST-a")
2456 a.append(entity_a)
2457
2458 self.assertEqual(
2459 [entity_b, entity_a],
2460 list(a.getiterator(Entity)))
2461
2462 self.assertEqual(
2463 [entity_b],
2464 list(b.getiterator(Entity)))
2465
2467 Element = self.etree.Element
2468 Comment = self.etree.Comment
2469 PI = self.etree.PI
2470 SubElement = self.etree.SubElement
2471
2472 a = Element('a')
2473 b = SubElement(a, 'b')
2474 a.append(Comment("test"))
2475 a.append(PI("pi", "content"))
2476 c = SubElement(a, 'c')
2477
2478 self.assertEqual(
2479 [a, b, c],
2480 list(a.getiterator(Element)))
2481
2483 # ElementTree iterates over everything here
2484 Element = self.etree.Element
2485 Comment = self.etree.Comment
2486 PI = self.etree.PI
2487 SubElement = self.etree.SubElement
2488
2489 a = Element('a')
2490 b = SubElement(a, 'b')
2491 a.append(Comment("test"))
2492 a.append(PI("pi", "content"))
2493 c = SubElement(a, 'c')
2494
2495 self.assertEqual(
2496 [a, b, c],
2497 list(a.getiterator('*')))
2498
2500 XML = self.etree.XML
2501 ElementTree = self.etree.ElementTree
2502 QName = self.etree.QName
2503 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
2504 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
2505
2507 XML = self.etree.XML
2508 ElementTree = self.etree.ElementTree
2509 QName = self.etree.QName
2510 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
2511 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
2512
2514 XML = self.etree.XML
2515 ElementTree = self.etree.ElementTree
2516 QName = self.etree.QName
2517 tree = ElementTree(XML(
2518 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
2519 self.assertEqual(len(list(tree.findall(QName("b")))), 2)
2520 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
2521
2523 XML = self.etree.XML
2524 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2525 self.assertEqual(len(root.findall(".//{X}b")), 2)
2526 self.assertEqual(len(root.findall(".//{X}*")), 2)
2527 self.assertEqual(len(root.findall(".//b")), 3)
2528
2530 XML = self.etree.XML
2531 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2532 nsmap = {'xx': 'X'}
2533 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2534 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2535 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2536 nsmap = {'xx': 'Y'}
2537 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2538 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2539 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2540
2542 XML = self.etree.XML
2543 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>'))
2544 nsmap = {'xx': 'X'}
2545 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2)
2546 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2)
2547 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2548 nsmap = {'xx': 'Y'}
2549 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1)
2550 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1)
2551 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2552
2554 XML = self.etree.XML
2555 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>'))
2556 self.assertRaises(SyntaxError, root.findall, '')
2557 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element
2558 self.assertRaises(SyntaxError, root.findall, './//')
2559
2561 etree = self.etree
2562 e = etree.Element('foo')
2563 for i in range(10):
2564 etree.SubElement(e, 'a%s' % i)
2565 for i in range(10):
2566 self.assertEqual(
2567 i,
2568 e.index(e[i]))
2569 self.assertEqual(
2570 3, e.index(e[3], 3))
2571 self.assertRaises(
2572 ValueError, e.index, e[3], 4)
2573 self.assertRaises(
2574 ValueError, e.index, e[3], 0, 2)
2575 self.assertRaises(
2576 ValueError, e.index, e[8], 0, -3)
2577 self.assertRaises(
2578 ValueError, e.index, e[8], -5, -3)
2579 self.assertEqual(
2580 8, e.index(e[8], 0, -1))
2581 self.assertEqual(
2582 8, e.index(e[8], -12, -1))
2583 self.assertEqual(
2584 0, e.index(e[0], -12, -1))
2585
2587 etree = self.etree
2588 e = etree.Element('foo')
2589 for i in range(10):
2590 el = etree.SubElement(e, 'a%s' % i)
2591 el.text = "text%d" % i
2592 el.tail = "tail%d" % i
2593
2594 child0 = e[0]
2595 child1 = e[1]
2596 child2 = e[2]
2597
2598 e.replace(e[0], e[1])
2599 self.assertEqual(
2600 9, len(e))
2601 self.assertEqual(
2602 child1, e[0])
2603 self.assertEqual(
2604 child1.text, "text1")
2605 self.assertEqual(
2606 child1.tail, "tail1")
2607 self.assertEqual(
2608 child0.tail, "tail0")
2609 self.assertEqual(
2610 child2, e[1])
2611
2612 e.replace(e[-1], e[0])
2613 self.assertEqual(
2614 child1, e[-1])
2615 self.assertEqual(
2616 child1.text, "text1")
2617 self.assertEqual(
2618 child1.tail, "tail1")
2619 self.assertEqual(
2620 child2, e[0])
2621
2623 etree = self.etree
2624 e = etree.Element('foo')
2625 for i in range(10):
2626 etree.SubElement(e, 'a%s' % i)
2627
2628 new_element = etree.Element("test")
2629 new_element.text = "TESTTEXT"
2630 new_element.tail = "TESTTAIL"
2631 child1 = e[1]
2632 e.replace(e[0], new_element)
2633 self.assertEqual(
2634 new_element, e[0])
2635 self.assertEqual(
2636 "TESTTEXT",
2637 e[0].text)
2638 self.assertEqual(
2639 "TESTTAIL",
2640 e[0].tail)
2641 self.assertEqual(
2642 child1, e[1])
2643
2645 Element = self.etree.Element
2646 SubElement = self.etree.SubElement
2647
2648 a = Element('a')
2649
2650 e = Element('e')
2651 f = Element('f')
2652 g = Element('g')
2653
2654 s = [e, f, g]
2655 a[::-1] = s
2656 self.assertEqual(
2657 [g, f, e],
2658 list(a))
2659
2661 Element = self.etree.Element
2662 SubElement = self.etree.SubElement
2663
2664 a = Element('a')
2665 b = SubElement(a, 'b')
2666 c = SubElement(a, 'c')
2667 d = SubElement(a, 'd')
2668 e = SubElement(a, 'e')
2669
2670 x = Element('x')
2671 y = Element('y')
2672
2673 a[1::2] = [x, y]
2674 self.assertEqual(
2675 [b, x, d, y],
2676 list(a))
2677
2679 Element = self.etree.Element
2680 SubElement = self.etree.SubElement
2681
2682 a = Element('a')
2683 b = SubElement(a, 'b')
2684 c = SubElement(a, 'c')
2685 d = SubElement(a, 'd')
2686 e = SubElement(a, 'e')
2687
2688 x = Element('x')
2689 y = Element('y')
2690
2691 a[1::-1] = [x, y]
2692 self.assertEqual(
2693 [y, x, d, e],
2694 list(a))
2695
2697 Element = self.etree.Element
2698 SubElement = self.etree.SubElement
2699
2700 a = Element('a')
2701 b = SubElement(a, 'b')
2702 c = SubElement(a, 'c')
2703 d = SubElement(a, 'd')
2704 e = SubElement(a, 'e')
2705
2706 x = Element('x')
2707 y = Element('y')
2708
2709 a[::-2] = [x, y]
2710 self.assertEqual(
2711 [b, y, d, x],
2712 list(a))
2713
2715 Element = self.etree.Element
2716 SubElement = self.etree.SubElement
2717 try:
2718 slice
2719 except NameError:
2720 print("slice() not found")
2721 return
2722
2723 a = Element('a')
2724 b = SubElement(a, 'b')
2725 c = SubElement(a, 'c')
2726 d = SubElement(a, 'd')
2727 e = SubElement(a, 'e')
2728
2729 x = Element('x')
2730 y = Element('y')
2731 z = Element('z')
2732
2733 self.assertRaises(
2734 ValueError,
2735 operator.setitem, a, slice(1,None,2), [x, y, z])
2736
2737 self.assertEqual(
2738 [b, c, d, e],
2739 list(a))
2740
2742 XML = self.etree.XML
2743 root = XML(_bytes('''<?xml version="1.0"?>
2744 <root><test>
2745
2746 <bla/></test>
2747 </root>
2748 '''))
2749
2750 self.assertEqual(
2751 [2, 2, 4],
2752 [ el.sourceline for el in root.getiterator() ])
2753
2755 parse = self.etree.parse
2756 tree = parse(fileInTestDir('include/test_xinclude.xml'))
2757
2758 self.assertEqual(
2759 [1, 2, 3],
2760 [ el.sourceline for el in tree.getiterator() ])
2761
2763 iterparse = self.etree.iterparse
2764 lines = [ el.sourceline for (event, el) in
2765 iterparse(fileInTestDir('include/test_xinclude.xml')) ]
2766
2767 self.assertEqual(
2768 [2, 3, 1],
2769 lines)
2770
2772 iterparse = self.etree.iterparse
2773 lines = [ el.sourceline for (event, el) in
2774 iterparse(fileInTestDir('include/test_xinclude.xml'),
2775 events=("start",)) ]
2776
2777 self.assertEqual(
2778 [1, 2, 3],
2779 lines)
2780
2782 Element = self.etree.Element
2783 SubElement = self.etree.SubElement
2784 el = Element("test")
2785 self.assertEqual(None, el.sourceline)
2786
2787 child = SubElement(el, "test")
2788 self.assertEqual(None, el.sourceline)
2789 self.assertEqual(None, child.sourceline)
2790
2792 etree = self.etree
2793 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2794 docinfo = root.getroottree().docinfo
2795 self.assertEqual(docinfo.URL, "http://no/such/url")
2796
2798 etree = self.etree
2799 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2800 docinfo = root.getroottree().docinfo
2801 self.assertEqual(docinfo.URL, "http://no/such/url")
2802 docinfo.URL = "https://secret/url"
2803 self.assertEqual(docinfo.URL, "https://secret/url")
2804
2806 etree = self.etree
2807 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
2808 docinfo = tree.docinfo
2809 self.assertEqual(docinfo.URL, "http://no/such/url")
2810
2812 etree = self.etree
2813 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
2814 base_url="http://no/such/url")
2815 docinfo = tree.docinfo
2816 self.assertEqual(docinfo.URL, "http://no/such/url")
2817
2819 etree = self.etree
2820 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
2821 docinfo = root.getroottree().docinfo
2822 self.assertEqual(docinfo.URL, "http://no/such/url")
2823
2825 etree = self.etree
2826 xml_header = '<?xml version="1.0" encoding="ascii"?>'
2827 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2828 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2829 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
2830
2831 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2832
2833 tree = etree.parse(BytesIO(xml))
2834 docinfo = tree.docinfo
2835 self.assertEqual(docinfo.encoding, "ascii")
2836 self.assertEqual(docinfo.xml_version, "1.0")
2837 self.assertEqual(docinfo.public_id, pub_id)
2838 self.assertEqual(docinfo.system_url, sys_id)
2839 self.assertEqual(docinfo.root_name, 'html')
2840 self.assertEqual(docinfo.doctype, doctype_string)
2841
2843 etree = self.etree
2844 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
2845 sys_id = "some.dtd"
2846 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
2847 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2848
2849 tree = etree.parse(BytesIO(xml))
2850 docinfo = tree.docinfo
2851 self.assertEqual(docinfo.encoding, "UTF-8")
2852 self.assertEqual(docinfo.xml_version, "1.0")
2853 self.assertEqual(docinfo.public_id, None)
2854 self.assertEqual(docinfo.system_url, sys_id)
2855 self.assertEqual(docinfo.root_name, 'html')
2856 self.assertEqual(docinfo.doctype, doctype_string)
2857
2859 etree = self.etree
2860 xml = _bytes('<html><body></body></html>')
2861 tree = etree.parse(BytesIO(xml))
2862 docinfo = tree.docinfo
2863 self.assertEqual(docinfo.encoding, "UTF-8")
2864 self.assertEqual(docinfo.xml_version, "1.0")
2865 self.assertEqual(docinfo.public_id, None)
2866 self.assertEqual(docinfo.system_url, None)
2867 self.assertEqual(docinfo.root_name, 'html')
2868 self.assertEqual(docinfo.doctype, '')
2869
2871 etree = self.etree
2872 xml = _bytes('<!DOCTYPE root><root></root>')
2873 tree = etree.parse(BytesIO(xml))
2874 docinfo = tree.docinfo
2875 self.assertEqual(docinfo.encoding, "UTF-8")
2876 self.assertEqual(docinfo.xml_version, "1.0")
2877 self.assertEqual(docinfo.public_id, None)
2878 self.assertEqual(docinfo.system_url, None)
2879 self.assertEqual(docinfo.root_name, 'root')
2880 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
2881
2883 etree = self.etree
2884 xml = _bytes('<!DOCTYPE root>\n<root/>')
2885 tree = etree.parse(BytesIO(xml))
2886 self.assertEqual(xml, etree.tostring(tree))
2887
2889 etree = self.etree
2890 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2891 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2892 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
2893
2894 xml = _bytes('<!DOCTYPE root>\n<root/>')
2895 tree = etree.parse(BytesIO(xml))
2896 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
2897 etree.tostring(tree, doctype=doctype_string))
2898
2900 etree = self.etree
2901 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2902 self.assertEqual(root.base, "http://no/such/url")
2903 self.assertEqual(
2904 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2905 root.base = "https://secret/url"
2906 self.assertEqual(root.base, "https://secret/url")
2907 self.assertEqual(
2908 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2909 "https://secret/url")
2910
2912 etree = self.etree
2913 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2914 self.assertEqual(root.base, "http://no/such/url")
2915 self.assertEqual(
2916 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2917 root.set('{http://www.w3.org/XML/1998/namespace}base',
2918 "https://secret/url")
2919 self.assertEqual(root.base, "https://secret/url")
2920 self.assertEqual(
2921 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2922 "https://secret/url")
2923
2925 etree = self.etree
2926 root = etree.HTML(_bytes("<html><body></body></html>"),
2927 base_url="http://no/such/url")
2928 self.assertEqual(root.base, "http://no/such/url")
2929
2931 etree = self.etree
2932 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
2933 self.assertEqual(root.base, "http://no/such/url")
2934
2936 # parse from a file object that returns unicode strings
2937 f = LargeFileLikeUnicode()
2938 tree = self.etree.parse(f)
2939 root = tree.getroot()
2940 self.assertTrue(root.tag.endswith('root'))
2941
2943 # check that DTDs that go in also go back out
2944 xml = _bytes('''\
2945 <!DOCTYPE test SYSTEM "test.dtd" [
2946 <!ENTITY entity "tasty">
2947 <!ELEMENT test (a)>
2948 <!ELEMENT a (#PCDATA)>
2949 ]>
2950 <test><a>test-test</a></test>\
2951 ''')
2952 tree = self.etree.parse(BytesIO(xml))
2953 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
2954 xml.replace(_bytes(" "), _bytes("")))
2955
2957 Element = self.etree.Element
2958
2959 a = Element('a')
2960 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
2961 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
2962
2963 self.assertRaises(ValueError, Element, 'ha\0ho')
2964
2966 Element = self.etree.Element
2967
2968 a = Element('a')
2969 self.assertRaises(ValueError, setattr, a, "text",
2970 _str('ha\0ho'))
2971 self.assertRaises(ValueError, setattr, a, "tail",
2972 _str('ha\0ho'))
2973
2974 self.assertRaises(ValueError, Element,
2975 _str('ha\0ho'))
2976
2978 Element = self.etree.Element
2979
2980 a = Element('a')
2981 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
2982 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
2983
2984 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
2985 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
2986
2987 self.assertRaises(ValueError, Element, 'ha\x07ho')
2988 self.assertRaises(ValueError, Element, 'ha\x02ho')
2989
2991 Element = self.etree.Element
2992
2993 a = Element('a')
2994 self.assertRaises(ValueError, setattr, a, "text",
2995 _str('ha\x07ho'))
2996 self.assertRaises(ValueError, setattr, a, "text",
2997 _str('ha\x02ho'))
2998
2999 self.assertRaises(ValueError, setattr, a, "tail",
3000 _str('ha\x07ho'))
3001 self.assertRaises(ValueError, setattr, a, "tail",
3002 _str('ha\x02ho'))
3003
3004 self.assertRaises(ValueError, Element,
3005 _str('ha\x07ho'))
3006 self.assertRaises(ValueError, Element,
3007 _str('ha\x02ho'))
3008
3010 Element = self.etree.Element
3011
3012 a = Element('a')
3013 self.assertRaises(ValueError, setattr, a, "text",
3014 _str('ha\u1234\x07ho'))
3015 self.assertRaises(ValueError, setattr, a, "text",
3016 _str('ha\u1234\x02ho'))
3017
3018 self.assertRaises(ValueError, setattr, a, "tail",
3019 _str('ha\u1234\x07ho'))
3020 self.assertRaises(ValueError, setattr, a, "tail",
3021 _str('ha\u1234\x02ho'))
3022
3023 self.assertRaises(ValueError, Element,
3024 _str('ha\u1234\x07ho'))
3025 self.assertRaises(ValueError, Element,
3026 _str('ha\u1234\x02ho'))
3027
3029 # ElementTree fails to serialize this
3030 tostring = self.etree.tostring
3031 Element = self.etree.Element
3032 SubElement = self.etree.SubElement
3033
3034 a = Element('a')
3035 b = SubElement(a, 'b')
3036 c = SubElement(a, 'c')
3037
3038 result = tostring(a, encoding='UTF-16')
3039 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3040 canonicalize(result))
3041
3043 # ElementTree raises an AssertionError here
3044 tostring = self.etree.tostring
3045 self.assertRaises(TypeError, self.etree.tostring, None)
3046
3048 tostring = self.etree.tostring
3049 Element = self.etree.Element
3050 SubElement = self.etree.SubElement
3051
3052 a = Element('a')
3053 b = SubElement(a, 'b')
3054 c = SubElement(a, 'c')
3055
3056 result = tostring(a)
3057 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3058
3059 result = tostring(a, pretty_print=False)
3060 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
3061
3062 result = tostring(a, pretty_print=True)
3063 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3064
3066 tostring = self.etree.tostring
3067 Element = self.etree.Element
3068 SubElement = self.etree.SubElement
3069
3070 a = Element('a')
3071 a.tail = "aTAIL"
3072 b = SubElement(a, 'b')
3073 b.tail = "bTAIL"
3074 c = SubElement(a, 'c')
3075
3076 result = tostring(a)
3077 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3078
3079 result = tostring(a, with_tail=False)
3080 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>"))
3081
3082 result = tostring(a, with_tail=True)
3083 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3084
3086 tostring = self.etree.tostring
3087 XML = self.etree.XML
3088 ElementTree = self.etree.ElementTree
3089 Element = self.etree.Element
3090
3091 tree = Element("root").getroottree()
3092 self.assertEqual(None, tree.docinfo.standalone)
3093
3094 tree = XML(_bytes("<root/>")).getroottree()
3095 self.assertEqual(None, tree.docinfo.standalone)
3096
3097 tree = XML(_bytes(
3098 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
3099 )).getroottree()
3100 self.assertEqual(True, tree.docinfo.standalone)
3101
3102 tree = XML(_bytes(
3103 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
3104 )).getroottree()
3105 self.assertEqual(False, tree.docinfo.standalone)
3106
3108 tostring = self.etree.tostring
3109 XML = self.etree.XML
3110 ElementTree = self.etree.ElementTree
3111
3112 root = XML(_bytes("<root/>"))
3113
3114 tree = ElementTree(root)
3115 self.assertEqual(None, tree.docinfo.standalone)
3116
3117 result = tostring(root, xml_declaration=True, encoding="ASCII")
3118 self.assertEqual(result, _bytes(
3119 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3120
3121 result = tostring(root, xml_declaration=True, encoding="ASCII",
3122 standalone=True)
3123 self.assertEqual(result, _bytes(
3124 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3125
3126 tree = ElementTree(XML(result))
3127 self.assertEqual(True, tree.docinfo.standalone)
3128
3129 result = tostring(root, xml_declaration=True, encoding="ASCII",
3130 standalone=False)
3131 self.assertEqual(result, _bytes(
3132 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
3133
3134 tree = ElementTree(XML(result))
3135 self.assertEqual(False, tree.docinfo.standalone)
3136
3138 tostring = self.etree.tostring
3139 XML = self.etree.XML
3140 ElementTree = self.etree.ElementTree
3141
3142 root = XML(_bytes(
3143 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
3144
3145 tree = ElementTree(root)
3146 self.assertEqual(True, tree.docinfo.standalone)
3147
3148 result = tostring(root, xml_declaration=True, encoding="ASCII")
3149 self.assertEqual(result, _bytes(
3150 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3151
3152 result = tostring(root, xml_declaration=True, encoding="ASCII",
3153 standalone=True)
3154 self.assertEqual(result, _bytes(
3155 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3156
3158 tostring = self.etree.tostring
3159 Element = self.etree.Element
3160 SubElement = self.etree.SubElement
3161
3162 a = Element('a')
3163 a.text = "A"
3164 a.tail = "tail"
3165 b = SubElement(a, 'b')
3166 b.text = "B"
3167 b.tail = _str("Søk på nettet")
3168 c = SubElement(a, 'c')
3169 c.text = "C"
3170
3171 result = tostring(a, method="text", encoding="UTF-16")
3172
3173 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3174 result)
3175
3177 tostring = self.etree.tostring
3178 Element = self.etree.Element
3179 SubElement = self.etree.SubElement
3180
3181 a = Element('a')
3182 a.text = _str('Søk på nettetA')
3183 a.tail = "tail"
3184 b = SubElement(a, 'b')
3185 b.text = "B"
3186 b.tail = _str('Søk på nettetB')
3187 c = SubElement(a, 'c')
3188 c.text = "C"
3189
3190 self.assertRaises(UnicodeEncodeError,
3191 tostring, a, method="text")
3192
3193 self.assertEqual(
3194 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3195 tostring(a, encoding="UTF-8", method="text"))
3196
3198 tounicode = self.etree.tounicode
3199 Element = self.etree.Element
3200 SubElement = self.etree.SubElement
3201
3202 a = Element('a')
3203 b = SubElement(a, 'b')
3204 c = SubElement(a, 'c')
3205
3206 self.assertTrue(isinstance(tounicode(a), _unicode))
3207 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3208 canonicalize(tounicode(a)))
3209
3211 tounicode = self.etree.tounicode
3212 Element = self.etree.Element
3213 SubElement = self.etree.SubElement
3214
3215 a = Element('a')
3216 b = SubElement(a, 'b')
3217 c = SubElement(a, 'c')
3218 d = SubElement(c, 'd')
3219 self.assertTrue(isinstance(tounicode(b), _unicode))
3220 self.assertTrue(isinstance(tounicode(c), _unicode))
3221 self.assertEqual(_bytes('<b></b>'),
3222 canonicalize(tounicode(b)))
3223 self.assertEqual(_bytes('<c><d></d></c>'),
3224 canonicalize(tounicode(c)))
3225
3229
3231 tounicode = self.etree.tounicode
3232 Element = self.etree.Element
3233 SubElement = self.etree.SubElement
3234
3235 a = Element('a')
3236 b = SubElement(a, 'b')
3237 c = SubElement(a, 'c')
3238 d = SubElement(c, 'd')
3239 b.tail = 'Foo'
3240
3241 self.assertTrue(isinstance(tounicode(b), _unicode))
3242 self.assertTrue(tounicode(b) == '<b/>Foo' or
3243 tounicode(b) == '<b />Foo')
3244
3246 tounicode = self.etree.tounicode
3247 Element = self.etree.Element
3248 SubElement = self.etree.SubElement
3249
3250 a = Element('a')
3251 b = SubElement(a, 'b')
3252 c = SubElement(a, 'c')
3253
3254 result = tounicode(a)
3255 self.assertEqual(result, "<a><b/><c/></a>")
3256
3257 result = tounicode(a, pretty_print=False)
3258 self.assertEqual(result, "<a><b/><c/></a>")
3259
3260 result = tounicode(a, pretty_print=True)
3261 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3262
3264 tostring = self.etree.tostring
3265 Element = self.etree.Element
3266 SubElement = self.etree.SubElement
3267
3268 a = Element('a')
3269 b = SubElement(a, 'b')
3270 c = SubElement(a, 'c')
3271
3272 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode))
3273 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3274 canonicalize(tostring(a, encoding=_unicode)))
3275
3277 tostring = self.etree.tostring
3278 Element = self.etree.Element
3279 SubElement = self.etree.SubElement
3280
3281 a = Element('a')
3282 b = SubElement(a, 'b')
3283 c = SubElement(a, 'c')
3284 d = SubElement(c, 'd')
3285 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3286 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3287 self.assertEqual(_bytes('<b></b>'),
3288 canonicalize(tostring(b, encoding=_unicode)))
3289 self.assertEqual(_bytes('<c><d></d></c>'),
3290 canonicalize(tostring(c, encoding=_unicode)))
3291
3293 tostring = self.etree.tostring
3294 self.assertRaises(TypeError, self.etree.tostring,
3295 None, encoding=_unicode)
3296
3298 tostring = self.etree.tostring
3299 Element = self.etree.Element
3300 SubElement = self.etree.SubElement
3301
3302 a = Element('a')
3303 b = SubElement(a, 'b')
3304 c = SubElement(a, 'c')
3305 d = SubElement(c, 'd')
3306 b.tail = 'Foo'
3307
3308 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3309 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or
3310 tostring(b, encoding=_unicode) == '<b />Foo')
3311
3313 tostring = self.etree.tostring
3314 Element = self.etree.Element
3315 SubElement = self.etree.SubElement
3316
3317 a = Element('a')
3318 b = SubElement(a, 'b')
3319 c = SubElement(a, 'c')
3320
3321 result = tostring(a, encoding=_unicode)
3322 self.assertEqual(result, "<a><b/><c/></a>")
3323
3324 result = tostring(a, encoding=_unicode, pretty_print=False)
3325 self.assertEqual(result, "<a><b/><c/></a>")
3326
3327 result = tostring(a, encoding=_unicode, pretty_print=True)
3328 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3329
3331 root = etree.Element('parent')
3332 etree.SubElement(root, 'child')
3333
3334 self.assertEqual(len(root), 1)
3335 self.assertEqual(root[0].tag, 'child')
3336
3337 # in PyPy, GC used to kill the Python proxy instance without cleanup
3338 gc.collect()
3339 self.assertEqual(len(root), 1)
3340 self.assertEqual(root[0].tag, 'child')
3341
3345
3346 el1 = SubEl()
3347 el2 = SubEl()
3348 self.assertEqual('SubEl', el1.tag)
3349 self.assertEqual('SubEl', el2.tag)
3350 el1.other = el2
3351 el2.other = el1
3352
3353 del el1, el2
3354 gc.collect()
3355 # not really testing anything here, but it shouldn't crash
3356
3357 # helper methods
3358
3360 """Write out element for comparison.
3361 """
3362 ElementTree = self.etree.ElementTree
3363 f = BytesIO()
3364 tree = ElementTree(element=element)
3365 tree.write(f, encoding=encoding, compression=compression)
3366 data = f.getvalue()
3367 if compression:
3368 data = zlib.decompress(data)
3369 return canonicalize(data)
3370
3371
3374 filename = fileInTestDir('test_broken.xml')
3375 root = etree.XML(_bytes('''\
3376 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3377 <xi:include href="%s" parse="text"/>
3378 </doc>
3379 ''' % filename))
3380 old_text = root.text
3381 content = read_file(filename)
3382 old_tail = root[0].tail
3383
3384 self.include( etree.ElementTree(root) )
3385 self.assertEqual(old_text + content + old_tail,
3386 root.text)
3387
3389 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
3390 self.assertNotEqual(
3391 'a',
3392 tree.getroot()[1].tag)
3393 # process xincludes
3394 self.include( tree )
3395 # check whether we find it replaced with included data
3396 self.assertEqual(
3397 'a',
3398 tree.getroot()[1].tag)
3399
3401 class res(etree.Resolver):
3402 include_text = read_file(fileInTestDir('test.xml'))
3403 called = {}
3404 def resolve(self, url, id, context):
3405 if url.endswith(".dtd"):
3406 self.called["dtd"] = True
3407 return self.resolve_filename(
3408 fileInTestDir('test.dtd'), context)
3409 elif url.endswith("test_xinclude.xml"):
3410 self.called["input"] = True
3411 return None # delegate to default resolver
3412 else:
3413 self.called["include"] = True
3414 return self.resolve_string(self.include_text, context)
3415
3416 res_instance = res()
3417 parser = etree.XMLParser(load_dtd = True)
3418 parser.resolvers.add(res_instance)
3419
3420 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3421 parser = parser)
3422
3423 self.include(tree)
3424
3425 called = list(res_instance.called.items())
3426 called.sort()
3427 self.assertEqual(
3428 [("dtd", True), ("include", True), ("input", True)],
3429 called)
3430
3434
3435
3440
3441
3444 tree = self.parse(_bytes('<a><b/></a>'))
3445 f = BytesIO()
3446 tree.write_c14n(f)
3447 s = f.getvalue()
3448 self.assertEqual(_bytes('<a><b></b></a>'),
3449 s)
3450
3452 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3453 f = BytesIO()
3454 tree.write_c14n(f, compression=9)
3455 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3456 try:
3457 s = gzfile.read()
3458 finally:
3459 gzfile.close()
3460 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3461 s)
3462
3464 tree = self.parse(_bytes('<a><b/></a>'))
3465 handle, filename = tempfile.mkstemp()
3466 try:
3467 tree.write_c14n(filename)
3468 data = read_file(filename, 'rb')
3469 finally:
3470 os.close(handle)
3471 os.remove(filename)
3472 self.assertEqual(_bytes('<a><b></b></a>'),
3473 data)
3474
3476 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3477 handle, filename = tempfile.mkstemp()
3478 try:
3479 tree.write_c14n(filename, compression=9)
3480 f = gzip.open(filename, 'rb')
3481 try:
3482 data = f.read()
3483 finally:
3484 f.close()
3485 finally:
3486 os.close(handle)
3487 os.remove(filename)
3488 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3489 data)
3490
3492 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3493 f = BytesIO()
3494 tree.write_c14n(f)
3495 s = f.getvalue()
3496 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3497 s)
3498 f = BytesIO()
3499 tree.write_c14n(f, with_comments=True)
3500 s = f.getvalue()
3501 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3502 s)
3503 f = BytesIO()
3504 tree.write_c14n(f, with_comments=False)
3505 s = f.getvalue()
3506 self.assertEqual(_bytes('<a><b></b></a>'),
3507 s)
3508
3510 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3511 s = etree.tostring(tree, method='c14n')
3512 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3513 s)
3514 s = etree.tostring(tree, method='c14n', with_comments=True)
3515 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3516 s)
3517 s = etree.tostring(tree, method='c14n', with_comments=False)
3518 self.assertEqual(_bytes('<a><b></b></a>'),
3519 s)
3520
3522 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3523 s = etree.tostring(tree.getroot(), method='c14n')
3524 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
3525 s)
3526 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
3527 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
3528 s)
3529 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
3530 self.assertEqual(_bytes('<a><b></b></a>'),
3531 s)
3532
3534 tree = self.parse(_bytes(
3535 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3536 f = BytesIO()
3537 tree.write_c14n(f)
3538 s = f.getvalue()
3539 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3540 s)
3541 f = BytesIO()
3542 tree.write_c14n(f, exclusive=False)
3543 s = f.getvalue()
3544 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3545 s)
3546 f = BytesIO()
3547 tree.write_c14n(f, exclusive=True)
3548 s = f.getvalue()
3549 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3550 s)
3551
3552 f = BytesIO()
3553 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
3554 s = f.getvalue()
3555 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
3556 s)
3557
3559 tree = self.parse(_bytes(
3560 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3561 s = etree.tostring(tree, method='c14n')
3562 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3563 s)
3564 s = etree.tostring(tree, method='c14n', exclusive=False)
3565 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3566 s)
3567 s = etree.tostring(tree, method='c14n', exclusive=True)
3568 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3569 s)
3570
3571 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3572 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
3573 s)
3574
3576 tree = self.parse(_bytes(
3577 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3578 s = etree.tostring(tree.getroot(), method='c14n')
3579 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3580 s)
3581 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3582 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3583 s)
3584 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3585 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3586 s)
3587
3588 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3589 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3590 s)
3591 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3592 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3593 s)
3594
3595 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3596 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3597 s)
3598
3600 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
3601 tree = self.parse(_bytes(
3602 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3603
3604 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
3605 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3606 s)
3607
3608
3611 tree = self.parse(_bytes('<a><b/></a>'))
3612 f = BytesIO()
3613 tree.write(f)
3614 s = f.getvalue()
3615 self.assertEqual(_bytes('<a><b/></a>'),
3616 s)
3617
3619 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3620 f = BytesIO()
3621 tree.write(f, compression=9)
3622 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3623 try:
3624 s = gzfile.read()
3625 finally:
3626 gzfile.close()
3627 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3628 s)
3629
3631 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3632 f = BytesIO()
3633 tree.write(f, compression=0)
3634 s0 = f.getvalue()
3635
3636 f = BytesIO()
3637 tree.write(f)
3638 self.assertEqual(f.getvalue(), s0)
3639
3640 f = BytesIO()
3641 tree.write(f, compression=1)
3642 s = f.getvalue()
3643 self.assertTrue(len(s) <= len(s0))
3644 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3645 try:
3646 s1 = gzfile.read()
3647 finally:
3648 gzfile.close()
3649
3650 f = BytesIO()
3651 tree.write(f, compression=9)
3652 s = f.getvalue()
3653 self.assertTrue(len(s) <= len(s0))
3654 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3655 try:
3656 s9 = gzfile.read()
3657 finally:
3658 gzfile.close()
3659
3660 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3661 s0)
3662 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3663 s1)
3664 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3665 s9)
3666
3668 tree = self.parse(_bytes('<a><b/></a>'))
3669 handle, filename = tempfile.mkstemp()
3670 try:
3671 tree.write(filename)
3672 data = read_file(filename, 'rb')
3673 finally:
3674 os.close(handle)
3675 os.remove(filename)
3676 self.assertEqual(_bytes('<a><b/></a>'),
3677 data)
3678
3680 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3681 handle, filename = tempfile.mkstemp()
3682 try:
3683 tree.write(filename, compression=9)
3684 f = gzip.open(filename, 'rb')
3685 try:
3686 data = f.read()
3687 finally:
3688 f.close()
3689 finally:
3690 os.close(handle)
3691 os.remove(filename)
3692 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3693 data)
3694
3696 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3697 handle, filename = tempfile.mkstemp()
3698 try:
3699 tree.write(filename, compression=9)
3700 data = etree.tostring(etree.parse(filename))
3701 finally:
3702 os.close(handle)
3703 os.remove(filename)
3704 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3705 data)
3706
3708 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3709 handle, filename = tempfile.mkstemp()
3710 try:
3711 tree.write(filename, compression=9)
3712 data = etree.tostring(etree.parse(
3713 gzip.GzipFile(filename)))
3714 finally:
3715 os.close(handle)
3716 os.remove(filename)
3717 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3718 data)
3719
3721 etree = etree
3722
3724 parse = self.etree.parse
3725 f = BytesIO('<a><b></c></b></a>')
3726 self.etree.clear_error_log()
3727 try:
3728 parse(f)
3729 logs = None
3730 except SyntaxError:
3731 e = sys.exc_info()[1]
3732 logs = e.error_log
3733 f.close()
3734 self.assertTrue([ log for log in logs
3735 if 'mismatch' in log.message ])
3736 self.assertTrue([ log for log in logs
3737 if 'PARSER' in log.domain_name])
3738 self.assertTrue([ log for log in logs
3739 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
3740 self.assertTrue([ log for log in logs
3741 if 1 == log.line ])
3742 self.assertTrue([ log for log in logs
3743 if 15 == log.column ])
3744
3755
3756 self.etree.use_global_python_log(Logger())
3757 f = BytesIO('<a><b></c></b></a>')
3758 try:
3759 parse(f)
3760 except SyntaxError:
3761 pass
3762 f.close()
3763
3764 self.assertTrue([ message for message in messages
3765 if 'mismatch' in message ])
3766 self.assertTrue([ message for message in messages
3767 if ':PARSER:' in message])
3768 self.assertTrue([ message for message in messages
3769 if ':ERR_TAG_NAME_MISMATCH:' in message ])
3770 self.assertTrue([ message for message in messages
3771 if ':1:15:' in message ])
3772
3774 suite = unittest.TestSuite()
3775 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
3776 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
3777 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
3778 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
3779 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
3780 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
3781 suite.addTests(
3782 [make_doctest('../../../doc/tutorial.txt')])
3783 if sys.version_info >= (2,6):
3784 # now requires the 'with' statement
3785 suite.addTests(
3786 [make_doctest('../../../doc/api.txt')])
3787 suite.addTests(
3788 [make_doctest('../../../doc/FAQ.txt')])
3789 suite.addTests(
3790 [make_doctest('../../../doc/parsing.txt')])
3791 suite.addTests(
3792 [make_doctest('../../../doc/resolvers.txt')])
3793 return suite
3794
3795 if __name__ == '__main__':
3796 print('to test use test.py %s' % __file__)
3797
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Thu Nov 7 17:44:12 2013 | http://epydoc.sourceforge.net |