| 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 operator
16 import tempfile
17 import gzip
18
19 this_dir = os.path.dirname(__file__)
20 if this_dir not in sys.path:
21 sys.path.insert(0, this_dir) # needed for Py3
22
23 from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir, read_file
24 from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest
25 from common_imports import canonicalize, sorted, _str, _bytes
26
27 print("")
28 print("TESTED VERSION: %s" % etree.__version__)
29 print(" Python: " + repr(sys.version_info))
30 print(" lxml.etree: " + repr(etree.LXML_VERSION))
31 print(" libxml used: " + repr(etree.LIBXML_VERSION))
32 print(" libxml compiled: " + repr(etree.LIBXML_COMPILED_VERSION))
33 print(" libxslt used: " + repr(etree.LIBXSLT_VERSION))
34 print(" libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION))
35 print("")
36
37 try:
38 _unicode = unicode
39 except NameError:
40 # Python 3
41 _unicode = str
42
44 """Tests only for etree, not ElementTree"""
45 etree = etree
46
48 self.assert_(isinstance(etree.__version__, _unicode))
49 self.assert_(isinstance(etree.LXML_VERSION, tuple))
50 self.assertEqual(len(etree.LXML_VERSION), 4)
51 self.assert_(isinstance(etree.LXML_VERSION[0], int))
52 self.assert_(isinstance(etree.LXML_VERSION[1], int))
53 self.assert_(isinstance(etree.LXML_VERSION[2], int))
54 self.assert_(isinstance(etree.LXML_VERSION[3], int))
55 self.assert_(etree.__version__.startswith(
56 str(etree.LXML_VERSION[0])))
57
59 if hasattr(self.etree, '__pyx_capi__'):
60 # newer Pyrex compatible C-API
61 self.assert_(isinstance(self.etree.__pyx_capi__, dict))
62 self.assert_(len(self.etree.__pyx_capi__) > 0)
63 else:
64 # older C-API mechanism
65 self.assert_(hasattr(self.etree, '_import_c_api'))
66
68 Element = self.etree.Element
69 el = Element('name')
70 self.assertEquals(el.tag, 'name')
71 el = Element('{}name')
72 self.assertEquals(el.tag, 'name')
73
75 Element = self.etree.Element
76 el = Element('name')
77 self.assertRaises(ValueError, Element, '{}')
78 self.assertRaises(ValueError, setattr, el, 'tag', '{}')
79
80 self.assertRaises(ValueError, Element, '{test}')
81 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
82
84 Element = self.etree.Element
85 self.assertRaises(ValueError, Element, 'p:name')
86 self.assertRaises(ValueError, Element, '{test}p:name')
87
88 el = Element('name')
89 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
90
92 Element = self.etree.Element
93 self.assertRaises(ValueError, Element, "p'name")
94 self.assertRaises(ValueError, Element, 'p"name')
95
96 self.assertRaises(ValueError, Element, "{test}p'name")
97 self.assertRaises(ValueError, Element, '{test}p"name')
98
99 el = Element('name')
100 self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
101 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
102
104 Element = self.etree.Element
105 self.assertRaises(ValueError, Element, ' name ')
106 self.assertRaises(ValueError, Element, 'na me')
107 self.assertRaises(ValueError, Element, '{test} name')
108
109 el = Element('name')
110 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
111
113 Element = self.etree.Element
114 SubElement = self.etree.SubElement
115
116 el = Element('name')
117 self.assertRaises(ValueError, SubElement, el, '{}')
118 self.assertRaises(ValueError, SubElement, el, '{test}')
119
121 Element = self.etree.Element
122 SubElement = self.etree.SubElement
123
124 el = Element('name')
125 self.assertRaises(ValueError, SubElement, el, 'p:name')
126 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
127
129 Element = self.etree.Element
130 SubElement = self.etree.SubElement
131
132 el = Element('name')
133 self.assertRaises(ValueError, SubElement, el, "p'name")
134 self.assertRaises(ValueError, SubElement, el, "{test}p'name")
135
136 self.assertRaises(ValueError, SubElement, el, 'p"name')
137 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
138
140 Element = self.etree.Element
141 SubElement = self.etree.SubElement
142
143 el = Element('name')
144 self.assertRaises(ValueError, SubElement, el, ' name ')
145 self.assertRaises(ValueError, SubElement, el, 'na me')
146 self.assertRaises(ValueError, SubElement, el, '{test} name')
147
149 Element = self.etree.Element
150 SubElement = self.etree.SubElement
151
152 el = Element('name')
153 self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'})
154 self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'})
155 self.assertEquals(0, len(el))
156
158 QName = self.etree.QName
159 self.assertRaises(ValueError, QName, '')
160 self.assertRaises(ValueError, QName, 'test', '')
161
163 QName = self.etree.QName
164 self.assertRaises(ValueError, QName, 'p:name')
165 self.assertRaises(ValueError, QName, 'test', 'p:name')
166
168 QName = self.etree.QName
169 self.assertRaises(ValueError, QName, ' name ')
170 self.assertRaises(ValueError, QName, 'na me')
171 self.assertRaises(ValueError, QName, 'test', ' name')
172
174 # ET doesn't have namespace/localname properties on QNames
175 QName = self.etree.QName
176 namespace, localname = 'http://myns', 'a'
177 qname = QName(namespace, localname)
178 self.assertEquals(namespace, qname.namespace)
179 self.assertEquals(localname, qname.localname)
180
182 # ET doesn't have namespace/localname properties on QNames
183 QName = self.etree.QName
184 qname1 = QName('http://myns', 'a')
185 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
186
187 qname2 = QName(a)
188 self.assertEquals(a.tag, qname1.text)
189 self.assertEquals(qname1.text, qname2.text)
190 self.assertEquals(qname1, qname2)
191
193 # ET doesn't resove QNames as text values
194 etree = self.etree
195 qname = etree.QName('http://myns', 'a')
196 a = etree.Element(qname, nsmap={'p' : 'http://myns'})
197 a.text = qname
198
199 self.assertEquals("p:a", a.text)
200
202 etree = self.etree
203 self.assertRaises(ValueError,
204 etree.Element, "root", nsmap={'"' : 'testns'})
205 self.assertRaises(ValueError,
206 etree.Element, "root", nsmap={'&' : 'testns'})
207 self.assertRaises(ValueError,
208 etree.Element, "root", nsmap={'a:b' : 'testns'})
209
211 # ET in Py 3.x has no "attrib.has_key()" method
212 XML = self.etree.XML
213
214 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
215 self.assertEquals(
216 True, root.attrib.has_key('bar'))
217 self.assertEquals(
218 False, root.attrib.has_key('baz'))
219 self.assertEquals(
220 False, root.attrib.has_key('hah'))
221 self.assertEquals(
222 True,
223 root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
224
226 Element = self.etree.Element
227 root = Element("root")
228 root.set("attr", "TEST")
229 self.assertEquals("TEST", root.get("attr"))
230
232 # ElementTree accepts arbitrary attribute values
233 # lxml.etree allows only strings
234 Element = self.etree.Element
235 root = Element("root")
236 self.assertRaises(TypeError, root.set, "newattr", 5)
237 self.assertRaises(TypeError, root.set, "newattr", None)
238
240 XML = self.etree.XML
241 xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>')
242
243 root = XML(xml)
244 self.etree.strip_attributes(root, 'a')
245 self.assertEquals(_bytes('<test b="10" c="20"><x b="2"></x></test>'),
246 self._writeElement(root))
247
248 root = XML(xml)
249 self.etree.strip_attributes(root, 'b', 'c')
250 self.assertEquals(_bytes('<test a="5"><x a="4"></x></test>'),
251 self._writeElement(root))
252
254 XML = self.etree.XML
255 xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>')
256
257 root = XML(xml)
258 self.etree.strip_attributes(root, 'a')
259 self.assertEquals(
260 _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'),
261 self._writeElement(root))
262
263 root = XML(xml)
264 self.etree.strip_attributes(root, '{http://test/ns}a', 'c')
265 self.assertEquals(
266 _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'),
267 self._writeElement(root))
268
269 root = XML(xml)
270 self.etree.strip_attributes(root, '{http://test/ns}*')
271 self.assertEquals(
272 _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'),
273 self._writeElement(root))
274
276 XML = self.etree.XML
277 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
278
279 root = XML(xml)
280 self.etree.strip_elements(root, 'a')
281 self.assertEquals(_bytes('<test><x></x></test>'),
282 self._writeElement(root))
283
284 root = XML(xml)
285 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
286 self.assertEquals(_bytes('<test><a></a><x><a></a></x></test>'),
287 self._writeElement(root))
288
289 root = XML(xml)
290 self.etree.strip_elements(root, 'c')
291 self.assertEquals(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
292 self._writeElement(root))
293
295 XML = self.etree.XML
296 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>')
297
298 root = XML(xml)
299 self.etree.strip_elements(root, 'a')
300 self.assertEquals(_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>'),
301 self._writeElement(root))
302
303 root = XML(xml)
304 self.etree.strip_elements(root, '{urn:a}b', 'c')
305 self.assertEquals(_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>'),
306 self._writeElement(root))
307
308 root = XML(xml)
309 self.etree.strip_elements(root, '{urn:a}*', 'c')
310 self.assertEquals(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
311 self._writeElement(root))
312
313 root = XML(xml)
314 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
315 self.assertEquals(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
316 self._writeElement(root))
317
336
362
389
415
434
436 # lxml.etree separates target and text
437 Element = self.etree.Element
438 SubElement = self.etree.SubElement
439 ProcessingInstruction = self.etree.ProcessingInstruction
440
441 a = Element('a')
442 a.append(ProcessingInstruction('foo', 'some more text'))
443 self.assertEquals(a[0].target, 'foo')
444 self.assertEquals(a[0].text, 'some more text')
445
447 XML = self.etree.XML
448 root = XML(_bytes("<test><?mypi my test ?></test>"))
449 self.assertEquals(root[0].target, "mypi")
450 self.assertEquals(root[0].text, "my test ")
451
453 XML = self.etree.XML
454 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
455 self.assertEquals(root[0].target, "mypi")
456 self.assertEquals(root[0].get('my'), "1")
457 self.assertEquals(root[0].get('test'), " abc ")
458 self.assertEquals(root[0].get('quotes'), "' '")
459 self.assertEquals(root[0].get('only'), None)
460 self.assertEquals(root[0].get('names'), None)
461 self.assertEquals(root[0].get('nope'), None)
462
464 XML = self.etree.XML
465 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
466 self.assertEquals(root[0].target, "mypi")
467 self.assertEquals(root[0].attrib['my'], "1")
468 self.assertEquals(root[0].attrib['test'], " abc ")
469 self.assertEquals(root[0].attrib['quotes'], "' '")
470 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
471 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
472 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
473
475 # previously caused a crash
476 ProcessingInstruction = self.etree.ProcessingInstruction
477
478 a = ProcessingInstruction("PI", "ONE")
479 b = copy.deepcopy(a)
480 b.text = "ANOTHER"
481
482 self.assertEquals('ONE', a.text)
483 self.assertEquals('ANOTHER', b.text)
484
486 XML = self.etree.XML
487 tostring = self.etree.tostring
488 root = XML(_bytes("<?mypi my test ?><test/><!--comment -->"))
489 tree1 = self.etree.ElementTree(root)
490 self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"),
491 tostring(tree1))
492
493 tree2 = copy.deepcopy(tree1)
494 self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"),
495 tostring(tree2))
496
497 root2 = copy.deepcopy(tree1.getroot())
498 self.assertEquals(_bytes("<test/>"),
499 tostring(root2))
500
502 XML = self.etree.XML
503 tostring = self.etree.tostring
504 xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>')
505 root = XML(xml)
506 tree1 = self.etree.ElementTree(root)
507 self.assertEquals(xml, tostring(tree1))
508
509 tree2 = copy.deepcopy(tree1)
510 self.assertEquals(xml, tostring(tree2))
511
512 root2 = copy.deepcopy(tree1.getroot())
513 self.assertEquals(_bytes("<test/>"),
514 tostring(root2))
515
517 # ElementTree accepts arbitrary attribute values
518 # lxml.etree allows only strings
519 Element = self.etree.Element
520
521 root = Element("root")
522 root.set("attr", "TEST")
523 self.assertEquals("TEST", root.get("attr"))
524 self.assertRaises(TypeError, root.set, "newattr", 5)
525
527 fromstring = self.etree.fromstring
528 tostring = self.etree.tostring
529 XMLParser = self.etree.XMLParser
530
531 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
532 parser = XMLParser(remove_comments=True)
533 root = fromstring(xml, parser)
534 self.assertEquals(
535 _bytes('<a><b><c/></b></a>'),
536 tostring(root))
537
539 parse = self.etree.parse
540 tostring = self.etree.tostring
541 XMLParser = self.etree.XMLParser
542
543 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>')
544
545 f = BytesIO(xml)
546 tree = parse(f)
547 self.assertEquals(
548 xml,
549 tostring(tree))
550
551 parser = XMLParser(remove_pis=True)
552 tree = parse(f, parser)
553 self.assertEquals(
554 _bytes('<a><b><c/></b></a>'),
555 tostring(tree))
556
558 # ET raises IOError only
559 parse = self.etree.parse
560 self.assertRaises(TypeError, parse, 'notthere.xml', object())
561
563 # ET removes comments
564 iterparse = self.etree.iterparse
565 tostring = self.etree.tostring
566
567 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
568 events = list(iterparse(f))
569 root = events[-1][1]
570 self.assertEquals(3, len(events))
571 self.assertEquals(
572 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
573 tostring(root))
574
576 # ET removes comments
577 iterparse = self.etree.iterparse
578 tostring = self.etree.tostring
579
580 def name(event, el):
581 if event == 'comment':
582 return el.text
583 else:
584 return el.tag
585
586 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
587 events = list(iterparse(f, events=('end', 'comment')))
588 root = events[-1][1]
589 self.assertEquals(6, len(events))
590 self.assertEquals(['A', ' B ', 'c', 'b', 'C', 'a'],
591 [ name(*item) for item in events ])
592 self.assertEquals(
593 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
594 tostring(root))
595
597 # ET removes pis
598 iterparse = self.etree.iterparse
599 tostring = self.etree.tostring
600 ElementTree = self.etree.ElementTree
601
602 def name(event, el):
603 if event == 'pi':
604 return (el.target, el.text)
605 else:
606 return el.tag
607
608 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
609 events = list(iterparse(f, events=('end', 'pi')))
610 root = events[-2][1]
611 self.assertEquals(8, len(events))
612 self.assertEquals([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
613 ('pid','d'), 'a', ('pie','e')],
614 [ name(*item) for item in events ])
615 self.assertEquals(
616 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
617 tostring(ElementTree(root)))
618
620 iterparse = self.etree.iterparse
621 tostring = self.etree.tostring
622
623 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
624 events = list(iterparse(f, remove_comments=True,
625 events=('end', 'comment')))
626 root = events[-1][1]
627 self.assertEquals(3, len(events))
628 self.assertEquals(['c', 'b', 'a'],
629 [ el.tag for (event, el) in events ])
630 self.assertEquals(
631 _bytes('<a><b><c/></b></a>'),
632 tostring(root))
633
635 iterparse = self.etree.iterparse
636 f = BytesIO('<a><b><c/></a>')
637 # ET raises ExpatError, lxml raises XMLSyntaxError
638 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
639
641 iterparse = self.etree.iterparse
642 f = BytesIO("""
643 <a> \n \n <b> b test </b> \n
644
645 \n\t <c> \n </c> </a> \n """)
646 iterator = iterparse(f, remove_blank_text=True)
647 text = [ (element.text, element.tail)
648 for event, element in iterator ]
649 self.assertEquals(
650 [(" b test ", None), (" \n ", None), (None, None)],
651 text)
652
654 iterparse = self.etree.iterparse
655 f = BytesIO('<a><b><d/></b><c/></a>')
656
657 iterator = iterparse(f, tag="b", events=('start', 'end'))
658 events = list(iterator)
659 root = iterator.root
660 self.assertEquals(
661 [('start', root[0]), ('end', root[0])],
662 events)
663
665 iterparse = self.etree.iterparse
666 f = BytesIO('<a><b><d/></b><c/></a>')
667
668 iterator = iterparse(f, tag="*", events=('start', 'end'))
669 events = list(iterator)
670 self.assertEquals(
671 8,
672 len(events))
673
675 iterparse = self.etree.iterparse
676 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
677
678 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
679 events = list(iterator)
680 root = iterator.root
681 self.assertEquals(
682 [('start', root[0]), ('end', root[0])],
683 events)
684
686 iterparse = self.etree.iterparse
687 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
688
689 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
690 events = list(iterator)
691 self.assertEquals(
692 8,
693 len(events))
694
696 text = _str('Søk på nettet')
697 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
698 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
699 ).encode('iso-8859-1')
700
701 self.assertRaises(self.etree.ParseError,
702 list, self.etree.iterparse(BytesIO(xml_latin1)))
703
705 text = _str('Søk på nettet', encoding="UTF-8")
706 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
707 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
708 ).encode('iso-8859-1')
709
710 iterator = self.etree.iterparse(BytesIO(xml_latin1),
711 encoding="iso-8859-1")
712 self.assertEquals(1, len(list(iterator)))
713
714 a = iterator.root
715 self.assertEquals(a.text, text)
716
718 tostring = self.etree.tostring
719 f = BytesIO('<root><![CDATA[test]]></root>')
720 context = self.etree.iterparse(f, strip_cdata=False)
721 content = [ el.text for event,el in context ]
722
723 self.assertEquals(['test'], content)
724 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
725 tostring(context.root))
726
730
732 self.etree.XMLParser(encoding="ascii")
733 self.etree.XMLParser(encoding="utf-8")
734 self.etree.XMLParser(encoding="iso-8859-1")
735
737 parser = self.etree.XMLParser(recover=True)
738
739 parser.feed('<?xml version=')
740 parser.feed('"1.0"?><ro')
741 parser.feed('ot><')
742 parser.feed('a test="works"')
743 parser.feed('><othertag/></root') # <a> not closed!
744 parser.feed('>')
745
746 root = parser.close()
747
748 self.assertEquals(root.tag, "root")
749 self.assertEquals(len(root), 1)
750 self.assertEquals(root[0].tag, "a")
751 self.assertEquals(root[0].get("test"), "works")
752 self.assertEquals(len(root[0]), 1)
753 self.assertEquals(root[0][0].tag, "othertag")
754 # FIXME: would be nice to get some errors logged ...
755 #self.assert_(len(parser.error_log) > 0, "error log is empty")
756
758 assertEquals = self.assertEquals
759 assertFalse = self.assertFalse
760
761 events = []
762 class Target(object):
763 def start(self, tag, attrib):
764 events.append("start")
765 assertFalse(attrib)
766 assertEquals("TAG", tag)
767 def end(self, tag):
768 events.append("end")
769 assertEquals("TAG", tag)
770 def close(self):
771 return "DONE" # no Element!
772
773 parser = self.etree.XMLParser(target=Target())
774 tree = self.etree.ElementTree()
775
776 self.assertRaises(TypeError,
777 tree.parse, BytesIO("<TAG/>"), parser=parser)
778 self.assertEquals(["start", "end"], events)
779
781 # ET doesn't call .close() on errors
782 events = []
783 class Target(object):
784 def start(self, tag, attrib):
785 events.append("start-" + tag)
786 def end(self, tag):
787 events.append("end-" + tag)
788 if tag == 'a':
789 raise ValueError("dead and gone")
790 def data(self, data):
791 events.append("data-" + data)
792 def close(self):
793 events.append("close")
794 return "DONE"
795
796 parser = self.etree.XMLParser(target=Target())
797
798 try:
799 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
800 done = parser.close()
801 self.fail("error expected, but parsing succeeded")
802 except ValueError:
803 done = 'value error received as expected'
804
805 self.assertEquals(["start-root", "data-A", "start-a",
806 "data-ca", "end-a", "close"],
807 events)
808
810 # ET doesn't call .close() on errors
811 events = []
812 class Target(object):
813 def start(self, tag, attrib):
814 events.append("start-" + tag)
815 def end(self, tag):
816 events.append("end-" + tag)
817 if tag == 'a':
818 raise ValueError("dead and gone")
819 def data(self, data):
820 events.append("data-" + data)
821 def close(self):
822 events.append("close")
823 return "DONE"
824
825 parser = self.etree.XMLParser(target=Target())
826
827 try:
828 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
829 parser=parser)
830 self.fail("error expected, but parsing succeeded")
831 except ValueError:
832 done = 'value error received as expected'
833
834 self.assertEquals(["start-root", "data-A", "start-a",
835 "data-ca", "end-a", "close"],
836 events)
837
839 events = []
840 class Target(object):
841 def start(self, tag, attrib):
842 events.append("start-" + tag)
843 def end(self, tag):
844 events.append("end-" + tag)
845 def data(self, data):
846 events.append("data-" + data)
847 def comment(self, text):
848 events.append("comment-" + text)
849 def close(self):
850 return "DONE"
851
852 parser = self.etree.XMLParser(target=Target())
853
854 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
855 done = parser.close()
856
857 self.assertEquals("DONE", done)
858 self.assertEquals(["comment-a", "start-root", "data-A", "comment-b",
859 "start-sub", "end-sub", "comment-c", "data-B",
860 "end-root", "comment-d"],
861 events)
862
864 events = []
865 class Target(object):
866 def start(self, tag, attrib):
867 events.append("start-" + tag)
868 def end(self, tag):
869 events.append("end-" + tag)
870 def data(self, data):
871 events.append("data-" + data)
872 def pi(self, target, data):
873 events.append("pi-" + target + "-" + data)
874 def close(self):
875 return "DONE"
876
877 parser = self.etree.XMLParser(target=Target())
878
879 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
880 done = parser.close()
881
882 self.assertEquals("DONE", done)
883 self.assertEquals(["pi-test-a", "start-root", "data-A", "pi-test-b",
884 "data-B", "end-root", "pi-test-c"],
885 events)
886
888 events = []
889 class Target(object):
890 def start(self, tag, attrib):
891 events.append("start-" + tag)
892 def end(self, tag):
893 events.append("end-" + tag)
894 def data(self, data):
895 events.append("data-" + data)
896 def close(self):
897 return "DONE"
898
899 parser = self.etree.XMLParser(target=Target(),
900 strip_cdata=False)
901
902 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
903 done = parser.close()
904
905 self.assertEquals("DONE", done)
906 self.assertEquals(["start-root", "data-A", "start-a",
907 "data-ca", "end-a", "data-B", "end-root"],
908 events)
909
911 events = []
912 class Target(object):
913 def start(self, tag, attrib):
914 events.append("start-" + tag)
915 def end(self, tag):
916 events.append("end-" + tag)
917 def data(self, data):
918 events.append("data-" + data)
919 def close(self):
920 events.append("close")
921 return "DONE"
922
923 parser = self.etree.XMLParser(target=Target(),
924 recover=True)
925
926 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
927 done = parser.close()
928
929 self.assertEquals("DONE", done)
930 self.assertEquals(["start-root", "data-A", "start-a",
931 "data-ca", "end-a", "data-B",
932 "end-root", "close"],
933 events)
934
936 iterwalk = self.etree.iterwalk
937 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
938
939 iterator = iterwalk(root, tag="b", events=('start', 'end'))
940 events = list(iterator)
941 self.assertEquals(
942 [('start', root[0]), ('end', root[0])],
943 events)
944
946 iterwalk = self.etree.iterwalk
947 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
948
949 iterator = iterwalk(root, tag="*", events=('start', 'end'))
950 events = list(iterator)
951 self.assertEquals(
952 8,
953 len(events))
954
956 iterwalk = self.etree.iterwalk
957 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
958
959 events = list(iterwalk(root))
960 self.assertEquals(
961 [('end', root[0]), ('end', root[1]), ('end', root)],
962 events)
963
965 iterwalk = self.etree.iterwalk
966 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
967
968 iterator = iterwalk(root, events=('start',))
969 events = list(iterator)
970 self.assertEquals(
971 [('start', root), ('start', root[0]), ('start', root[1])],
972 events)
973
975 iterwalk = self.etree.iterwalk
976 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
977
978 iterator = iterwalk(root, events=('start','end'))
979 events = list(iterator)
980 self.assertEquals(
981 [('start', root), ('start', root[0]), ('end', root[0]),
982 ('start', root[1]), ('end', root[1]), ('end', root)],
983 events)
984
986 iterwalk = self.etree.iterwalk
987 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
988
989 iterator = iterwalk(root)
990 for event, elem in iterator:
991 elem.clear()
992
993 self.assertEquals(0,
994 len(root))
995
997 iterwalk = self.etree.iterwalk
998 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
999
1000 attr_name = '{testns}bla'
1001 events = []
1002 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1003 for event, elem in iterator:
1004 events.append(event)
1005 if event == 'start':
1006 if elem.tag != '{ns1}a':
1007 elem.set(attr_name, 'value')
1008
1009 self.assertEquals(
1010 ['start-ns', 'start', 'start', 'start-ns', 'start',
1011 'end', 'end-ns', 'end', 'end', 'end-ns'],
1012 events)
1013
1014 self.assertEquals(
1015 None,
1016 root.get(attr_name))
1017 self.assertEquals(
1018 'value',
1019 root[0].get(attr_name))
1020
1022 iterwalk = self.etree.iterwalk
1023 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
1024
1025 counts = []
1026 for event, elem in iterwalk(root):
1027 counts.append(len(list(elem.getiterator())))
1028 self.assertEquals(
1029 [1,2,1,4],
1030 counts)
1031
1033 parse = self.etree.parse
1034 parser = self.etree.XMLParser(dtd_validation=True)
1035 assertEqual = self.assertEqual
1036 test_url = _str("__nosuch.dtd")
1037
1038 class MyResolver(self.etree.Resolver):
1039 def resolve(self, url, id, context):
1040 assertEqual(url, test_url)
1041 return self.resolve_string(
1042 _str('''<!ENTITY myentity "%s">
1043 <!ELEMENT doc ANY>''') % url, context)
1044
1045 parser.resolvers.add(MyResolver())
1046
1047 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1048 tree = parse(StringIO(xml), parser)
1049 root = tree.getroot()
1050 self.assertEquals(root.text, test_url)
1051
1053 parse = self.etree.parse
1054 parser = self.etree.XMLParser(dtd_validation=True)
1055 assertEqual = self.assertEqual
1056 test_url = _str("__nosuch.dtd")
1057
1058 class MyResolver(self.etree.Resolver):
1059 def resolve(self, url, id, context):
1060 assertEqual(url, test_url)
1061 return self.resolve_string(
1062 (_str('''<!ENTITY myentity "%s">
1063 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1064 context)
1065
1066 parser.resolvers.add(MyResolver())
1067
1068 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1069 tree = parse(StringIO(xml), parser)
1070 root = tree.getroot()
1071 self.assertEquals(root.text, test_url)
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_file(
1083 SillyFileLike(
1084 _str('''<!ENTITY myentity "%s">
1085 <!ELEMENT doc ANY>''') % url), context)
1086
1087 parser.resolvers.add(MyResolver())
1088
1089 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1090 tree = parse(StringIO(xml), parser)
1091 root = tree.getroot()
1092 self.assertEquals(root.text, test_url)
1093
1095 parse = self.etree.parse
1096 parser = self.etree.XMLParser(attribute_defaults=True)
1097 assertEqual = self.assertEqual
1098 test_url = _str("__nosuch.dtd")
1099
1100 class MyResolver(self.etree.Resolver):
1101 def resolve(self, url, id, context):
1102 assertEqual(url, test_url)
1103 return self.resolve_filename(
1104 fileInTestDir('test.dtd'), context)
1105
1106 parser.resolvers.add(MyResolver())
1107
1108 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1109 tree = parse(StringIO(xml), parser)
1110 root = tree.getroot()
1111 self.assertEquals(
1112 root.attrib, {'default': 'valueA'})
1113 self.assertEquals(
1114 root[0].attrib, {'default': 'valueB'})
1115
1117 parse = self.etree.parse
1118 parser = self.etree.XMLParser(attribute_defaults=True)
1119 assertEqual = self.assertEqual
1120 test_url = _str("__nosuch.dtd")
1121
1122 class MyResolver(self.etree.Resolver):
1123 def resolve(self, url, id, context):
1124 assertEqual(url, fileInTestDir(test_url))
1125 return self.resolve_filename(
1126 fileInTestDir('test.dtd'), context)
1127
1128 parser.resolvers.add(MyResolver())
1129
1130 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1131 tree = parse(StringIO(xml), parser,
1132 base_url=fileInTestDir('__test.xml'))
1133 root = tree.getroot()
1134 self.assertEquals(
1135 root.attrib, {'default': 'valueA'})
1136 self.assertEquals(
1137 root[0].attrib, {'default': 'valueB'})
1138
1140 parse = self.etree.parse
1141 parser = self.etree.XMLParser(attribute_defaults=True)
1142 assertEqual = self.assertEqual
1143 test_url = _str("__nosuch.dtd")
1144
1145 class MyResolver(self.etree.Resolver):
1146 def resolve(self, url, id, context):
1147 assertEqual(url, test_url)
1148 return self.resolve_file(
1149 open(fileInTestDir('test.dtd'), 'rb'), context)
1150
1151 parser.resolvers.add(MyResolver())
1152
1153 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1154 tree = parse(StringIO(xml), parser)
1155 root = tree.getroot()
1156 self.assertEquals(
1157 root.attrib, {'default': 'valueA'})
1158 self.assertEquals(
1159 root[0].attrib, {'default': 'valueB'})
1160
1162 parse = self.etree.parse
1163 parser = self.etree.XMLParser(load_dtd=True)
1164 assertEqual = self.assertEqual
1165 test_url = _str("__nosuch.dtd")
1166
1167 class check(object):
1168 resolved = False
1169
1170 class MyResolver(self.etree.Resolver):
1171 def resolve(self, url, id, context):
1172 assertEqual(url, test_url)
1173 check.resolved = True
1174 return self.resolve_empty(context)
1175
1176 parser.resolvers.add(MyResolver())
1177
1178 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1179 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1180 self.assert_(check.resolved)
1181
1183 parse = self.etree.parse
1184 parser = self.etree.XMLParser(dtd_validation=True)
1185
1186 class _LocalException(Exception):
1187 pass
1188
1189 class MyResolver(self.etree.Resolver):
1190 def resolve(self, url, id, context):
1191 raise _LocalException
1192
1193 parser.resolvers.add(MyResolver())
1194
1195 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1196 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1197
1198 if etree.LIBXML_VERSION > (2,6,20):
1200 parse = self.etree.parse
1201 tostring = self.etree.tostring
1202 parser = self.etree.XMLParser(resolve_entities=False)
1203 Entity = self.etree.Entity
1204
1205 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>')
1206 tree = parse(BytesIO(xml), parser)
1207 root = tree.getroot()
1208 self.assertEquals(root[0].tag, Entity)
1209 self.assertEquals(root[0].text, "&myentity;")
1210 self.assertEquals(root[0].tail, None)
1211 self.assertEquals(root[0].name, "myentity")
1212
1213 self.assertEquals(_bytes('<doc>&myentity;</doc>'),
1214 tostring(root))
1215
1217 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1218 <root>
1219 <child1/>
1220 <child2/>
1221 <child3> </child3>
1222 </root>''')
1223
1224 parser = self.etree.XMLParser(resolve_entities=False)
1225 root = etree.fromstring(xml, parser)
1226 self.assertEquals([ el.tag for el in root ],
1227 ['child1', 'child2', 'child3'])
1228
1229 root[0] = root[-1]
1230 self.assertEquals([ el.tag for el in root ],
1231 ['child3', 'child2'])
1232 self.assertEquals(root[0][0].text, ' ')
1233 self.assertEquals(root[0][0].name, 'nbsp')
1234
1236 Entity = self.etree.Entity
1237 Element = self.etree.Element
1238 tostring = self.etree.tostring
1239
1240 root = Element("root")
1241 root.append( Entity("test") )
1242
1243 self.assertEquals(root[0].tag, Entity)
1244 self.assertEquals(root[0].text, "&test;")
1245 self.assertEquals(root[0].tail, None)
1246 self.assertEquals(root[0].name, "test")
1247
1248 self.assertEquals(_bytes('<root>&test;</root>'),
1249 tostring(root))
1250
1252 Entity = self.etree.Entity
1253 self.assertEquals(Entity("test").text, '&test;')
1254 self.assertEquals(Entity("#17683").text, '䔓')
1255 self.assertEquals(Entity("#x1768").text, 'ᝨ')
1256 self.assertEquals(Entity("#x98AF").text, '颯')
1257
1259 Entity = self.etree.Entity
1260 self.assertRaises(ValueError, Entity, 'a b c')
1261 self.assertRaises(ValueError, Entity, 'a,b')
1262 self.assertRaises(ValueError, Entity, 'a\0b')
1263 self.assertRaises(ValueError, Entity, '#abc')
1264 self.assertRaises(ValueError, Entity, '#xxyz')
1265
1267 CDATA = self.etree.CDATA
1268 Element = self.etree.Element
1269 tostring = self.etree.tostring
1270
1271 root = Element("root")
1272 root.text = CDATA('test')
1273
1274 self.assertEquals('test',
1275 root.text)
1276 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
1277 tostring(root))
1278
1280 CDATA = self.etree.CDATA
1281 Element = self.etree.Element
1282 root = Element("root")
1283
1284 root.text = CDATA("test")
1285 self.assertEquals('test', root.text)
1286
1287 root.text = CDATA(_str("test"))
1288 self.assertEquals('test', root.text)
1289
1290 self.assertRaises(TypeError, CDATA, 1)
1291
1293 CDATA = self.etree.CDATA
1294 Element = self.etree.Element
1295
1296 root = Element("root")
1297 cdata = CDATA('test')
1298
1299 self.assertRaises(TypeError,
1300 setattr, root, 'tail', cdata)
1301 self.assertRaises(TypeError,
1302 root.set, 'attr', cdata)
1303 self.assertRaises(TypeError,
1304 operator.setitem, root.attrib, 'attr', cdata)
1305
1307 tostring = self.etree.tostring
1308 parser = self.etree.XMLParser(strip_cdata=False)
1309 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1310
1311 self.assertEquals('test', root.text)
1312 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
1313 tostring(root))
1314
1316 tostring = self.etree.tostring
1317 parser = self.etree.XMLParser(strip_cdata=False)
1318 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1319 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
1320 tostring(root))
1321
1322 self.assertEquals(['test'], root.xpath('//text()'))
1323
1324 # TypeError in etree, AssertionError in ElementTree;
1326 Element = self.etree.Element
1327 SubElement = self.etree.SubElement
1328
1329 a = Element('a')
1330 b = SubElement(a, 'b')
1331
1332 self.assertRaises(TypeError,
1333 a.__setitem__, 0, 'foo')
1334
1336 Element = self.etree.Element
1337 root = Element('root')
1338 # raises AssertionError in ElementTree
1339 self.assertRaises(TypeError, root.append, None)
1340 self.assertRaises(TypeError, root.extend, [None])
1341 self.assertRaises(TypeError, root.extend, [Element('one'), None])
1342 self.assertEquals('one', root[0].tag)
1343
1345 Element = self.etree.Element
1346 SubElement = self.etree.SubElement
1347 root = Element('root')
1348 SubElement(root, 'a')
1349 SubElement(root, 'b')
1350
1351 self.assertEquals(['a', 'b'],
1352 [c.tag for c in root])
1353 root[1].addnext(root[0])
1354 self.assertEquals(['b', 'a'],
1355 [c.tag for c in root])
1356
1358 Element = self.etree.Element
1359 SubElement = self.etree.SubElement
1360 root = Element('root')
1361 SubElement(root, 'a')
1362 SubElement(root, 'b')
1363
1364 self.assertEquals(['a', 'b'],
1365 [c.tag for c in root])
1366 root[0].addprevious(root[1])
1367 self.assertEquals(['b', 'a'],
1368 [c.tag for c in root])
1369
1371 Element = self.etree.Element
1372 a = Element('a')
1373 b = Element('b')
1374 self.assertRaises(TypeError, a.addnext, b)
1375
1377 Element = self.etree.Element
1378 a = Element('a')
1379 b = Element('b')
1380 self.assertRaises(TypeError, a.addnext, b)
1381
1383 Element = self.etree.Element
1384 SubElement = self.etree.SubElement
1385 PI = self.etree.PI
1386 root = Element('root')
1387 SubElement(root, 'a')
1388 pi = PI('TARGET', 'TEXT')
1389 pi.tail = "TAIL"
1390
1391 self.assertEquals(_bytes('<root><a></a></root>'),
1392 self._writeElement(root))
1393 root[0].addprevious(pi)
1394 self.assertEquals(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
1395 self._writeElement(root))
1396
1398 Element = self.etree.Element
1399 PI = self.etree.PI
1400 root = Element('root')
1401 pi = PI('TARGET', 'TEXT')
1402 pi.tail = "TAIL"
1403
1404 self.assertEquals(_bytes('<root></root>'),
1405 self._writeElement(root))
1406 root.addprevious(pi)
1407 self.assertEquals(_bytes('<?TARGET TEXT?>\n<root></root>'),
1408 self._writeElement(root))
1409
1411 Element = self.etree.Element
1412 SubElement = self.etree.SubElement
1413 PI = self.etree.PI
1414 root = Element('root')
1415 SubElement(root, 'a')
1416 pi = PI('TARGET', 'TEXT')
1417 pi.tail = "TAIL"
1418
1419 self.assertEquals(_bytes('<root><a></a></root>'),
1420 self._writeElement(root))
1421 root[0].addnext(pi)
1422 self.assertEquals(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
1423 self._writeElement(root))
1424
1426 Element = self.etree.Element
1427 PI = self.etree.PI
1428 root = Element('root')
1429 pi = PI('TARGET', 'TEXT')
1430 pi.tail = "TAIL"
1431
1432 self.assertEquals(_bytes('<root></root>'),
1433 self._writeElement(root))
1434 root.addnext(pi)
1435 self.assertEquals(_bytes('<root></root>\n<?TARGET TEXT?>'),
1436 self._writeElement(root))
1437
1439 Element = self.etree.Element
1440 SubElement = self.etree.SubElement
1441 Comment = self.etree.Comment
1442 root = Element('root')
1443 SubElement(root, 'a')
1444 comment = Comment('TEXT ')
1445 comment.tail = "TAIL"
1446
1447 self.assertEquals(_bytes('<root><a></a></root>'),
1448 self._writeElement(root))
1449 root[0].addnext(comment)
1450 self.assertEquals(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
1451 self._writeElement(root))
1452
1454 Element = self.etree.Element
1455 Comment = self.etree.Comment
1456 root = Element('root')
1457 comment = Comment('TEXT ')
1458 comment.tail = "TAIL"
1459
1460 self.assertEquals(_bytes('<root></root>'),
1461 self._writeElement(root))
1462 root.addnext(comment)
1463 self.assertEquals(_bytes('<root></root>\n<!--TEXT -->'),
1464 self._writeElement(root))
1465
1467 Element = self.etree.Element
1468 SubElement = self.etree.SubElement
1469 Comment = self.etree.Comment
1470 root = Element('root')
1471 SubElement(root, 'a')
1472 comment = Comment('TEXT ')
1473 comment.tail = "TAIL"
1474
1475 self.assertEquals(_bytes('<root><a></a></root>'),
1476 self._writeElement(root))
1477 root[0].addprevious(comment)
1478 self.assertEquals(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
1479 self._writeElement(root))
1480
1482 Element = self.etree.Element
1483 Comment = self.etree.Comment
1484 root = Element('root')
1485 comment = Comment('TEXT ')
1486 comment.tail = "TAIL"
1487
1488 self.assertEquals(_bytes('<root></root>'),
1489 self._writeElement(root))
1490 root.addprevious(comment)
1491 self.assertEquals(_bytes('<!--TEXT -->\n<root></root>'),
1492 self._writeElement(root))
1493
1494 # ET's Elements have items() and key(), but not values()
1496 XML = self.etree.XML
1497
1498 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
1499 values = root.values()
1500 values.sort()
1501 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
1502
1503 # gives error in ElementTree
1505 Element = self.etree.Element
1506 Comment = self.etree.Comment
1507
1508 a = Element('a')
1509 a.append(Comment())
1510 self.assertEquals(
1511 _bytes('<a><!----></a>'),
1512 self._writeElement(a))
1513
1514 # ElementTree ignores comments
1516 ElementTree = self.etree.ElementTree
1517 tostring = self.etree.tostring
1518
1519 xml = _bytes('<a><b/><!----><c/></a>')
1520 f = BytesIO(xml)
1521 doc = ElementTree(file=f)
1522 a = doc.getroot()
1523 self.assertEquals(
1524 '',
1525 a[1].text)
1526 self.assertEquals(
1527 xml,
1528 tostring(a))
1529
1530 # ElementTree ignores comments
1532 ElementTree = self.etree.ElementTree
1533
1534 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
1535 doc = ElementTree(file=f)
1536 a = doc.getroot()
1537 self.assertEquals(
1538 ' hoi ',
1539 a[1].text)
1540
1541 # does not raise an exception in ElementTree
1543 Element = self.etree.Element
1544 Comment = self.etree.Comment
1545
1546 c = Comment()
1547 el = Element('myel')
1548
1549 self.assertRaises(TypeError, c.append, el)
1550 self.assertRaises(TypeError, c.insert, 0, el)
1551 self.assertRaises(TypeError, c.set, "myattr", "test")
1552
1553 # test passing 'None' to dump
1556
1558 ElementTree = self.etree.ElementTree
1559
1560 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
1561 doc = ElementTree(file=f)
1562 a = doc.getroot()
1563 self.assertEquals(
1564 None,
1565 a.prefix)
1566 self.assertEquals(
1567 'foo',
1568 a[0].prefix)
1569
1571 ElementTree = self.etree.ElementTree
1572
1573 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
1574 doc = ElementTree(file=f)
1575 a = doc.getroot()
1576 self.assertEquals(
1577 None,
1578 a.prefix)
1579 self.assertEquals(
1580 None,
1581 a[0].prefix)
1582
1584 Element = self.etree.Element
1585 SubElement = self.etree.SubElement
1586
1587 a = Element('a')
1588 b = SubElement(a, 'b')
1589 c = SubElement(a, 'c')
1590 d = SubElement(b, 'd')
1591 self.assertEquals(
1592 None,
1593 a.getparent())
1594 self.assertEquals(
1595 a,
1596 b.getparent())
1597 self.assertEquals(
1598 b.getparent(),
1599 c.getparent())
1600 self.assertEquals(
1601 b,
1602 d.getparent())
1603
1605 XML = self.etree.XML
1606
1607 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
1608 result = []
1609 for el in root.iterchildren():
1610 result.append(el.tag)
1611 self.assertEquals(['one', 'two', 'three'], result)
1612
1614 XML = self.etree.XML
1615
1616 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
1617 result = []
1618 for el in root.iterchildren(reversed=True):
1619 result.append(el.tag)
1620 self.assertEquals(['three', 'two', 'one'], result)
1621
1623 XML = self.etree.XML
1624
1625 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1626 result = []
1627 for el in root.iterchildren(tag='two'):
1628 result.append(el.text)
1629 self.assertEquals(['Two', 'Bla'], result)
1630
1632 XML = self.etree.XML
1633
1634 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1635 result = []
1636 for el in root.iterchildren(reversed=True, tag='two'):
1637 result.append(el.text)
1638 self.assertEquals(['Bla', 'Two'], result)
1639
1641 Element = self.etree.Element
1642 SubElement = self.etree.SubElement
1643
1644 a = Element('a')
1645 b = SubElement(a, 'b')
1646 c = SubElement(a, 'c')
1647 d = SubElement(b, 'd')
1648 self.assertEquals(
1649 [],
1650 list(a.iterancestors()))
1651 self.assertEquals(
1652 [a],
1653 list(b.iterancestors()))
1654 self.assertEquals(
1655 [a],
1656 list(c.iterancestors()))
1657 self.assertEquals(
1658 [b, a],
1659 list(d.iterancestors()))
1660
1662 Element = self.etree.Element
1663 SubElement = self.etree.SubElement
1664
1665 a = Element('a')
1666 b = SubElement(a, 'b')
1667 c = SubElement(a, 'c')
1668 d = SubElement(b, 'd')
1669 self.assertEquals(
1670 [a],
1671 list(d.iterancestors(tag='a')))
1672
1674 Element = self.etree.Element
1675 SubElement = self.etree.SubElement
1676
1677 a = Element('a')
1678 b = SubElement(a, 'b')
1679 c = SubElement(a, 'c')
1680 d = SubElement(b, 'd')
1681 e = SubElement(c, 'e')
1682
1683 self.assertEquals(
1684 [b, d, c, e],
1685 list(a.iterdescendants()))
1686 self.assertEquals(
1687 [],
1688 list(d.iterdescendants()))
1689
1691 Element = self.etree.Element
1692 SubElement = self.etree.SubElement
1693
1694 a = Element('a')
1695 b = SubElement(a, 'b')
1696 c = SubElement(a, 'c')
1697 d = SubElement(b, 'd')
1698 e = SubElement(c, 'e')
1699
1700 self.assertEquals(
1701 [],
1702 list(a.iterdescendants('a')))
1703 a2 = SubElement(e, 'a')
1704 self.assertEquals(
1705 [a2],
1706 list(a.iterdescendants('a')))
1707 self.assertEquals(
1708 [a2],
1709 list(c.iterdescendants('a')))
1710
1712 Element = self.etree.Element
1713 SubElement = self.etree.SubElement
1714
1715 a = Element('a')
1716 b = SubElement(a, 'b')
1717 c = SubElement(a, 'c')
1718 d = SubElement(b, 'd')
1719 self.assertEquals(
1720 a,
1721 a.getroottree().getroot())
1722 self.assertEquals(
1723 a,
1724 b.getroottree().getroot())
1725 self.assertEquals(
1726 a,
1727 d.getroottree().getroot())
1728
1730 Element = self.etree.Element
1731 SubElement = self.etree.SubElement
1732
1733 a = Element('a')
1734 b = SubElement(a, 'b')
1735 c = SubElement(a, 'c')
1736 self.assertEquals(
1737 None,
1738 a.getnext())
1739 self.assertEquals(
1740 c,
1741 b.getnext())
1742 self.assertEquals(
1743 None,
1744 c.getnext())
1745
1747 Element = self.etree.Element
1748 SubElement = self.etree.SubElement
1749
1750 a = Element('a')
1751 b = SubElement(a, 'b')
1752 c = SubElement(a, 'c')
1753 d = SubElement(b, 'd')
1754 self.assertEquals(
1755 None,
1756 a.getprevious())
1757 self.assertEquals(
1758 b,
1759 c.getprevious())
1760 self.assertEquals(
1761 None,
1762 b.getprevious())
1763
1765 Element = self.etree.Element
1766 SubElement = self.etree.SubElement
1767
1768 a = Element('a')
1769 b = SubElement(a, 'b')
1770 c = SubElement(a, 'c')
1771 d = SubElement(b, 'd')
1772 self.assertEquals(
1773 [],
1774 list(a.itersiblings()))
1775 self.assertEquals(
1776 [c],
1777 list(b.itersiblings()))
1778 self.assertEquals(
1779 [],
1780 list(c.itersiblings()))
1781 self.assertEquals(
1782 [b],
1783 list(c.itersiblings(preceding=True)))
1784 self.assertEquals(
1785 [],
1786 list(b.itersiblings(preceding=True)))
1787
1789 Element = self.etree.Element
1790 SubElement = self.etree.SubElement
1791
1792 a = Element('a')
1793 b = SubElement(a, 'b')
1794 c = SubElement(a, 'c')
1795 d = SubElement(b, 'd')
1796 self.assertEquals(
1797 [],
1798 list(a.itersiblings(tag='XXX')))
1799 self.assertEquals(
1800 [c],
1801 list(b.itersiblings(tag='c')))
1802 self.assertEquals(
1803 [b],
1804 list(c.itersiblings(preceding=True, tag='b')))
1805 self.assertEquals(
1806 [],
1807 list(c.itersiblings(preceding=True, tag='c')))
1808
1810 parseid = self.etree.parseid
1811 XML = self.etree.XML
1812 xml_text = _bytes('''
1813 <!DOCTYPE document [
1814 <!ELEMENT document (h1,p)*>
1815 <!ELEMENT h1 (#PCDATA)>
1816 <!ATTLIST h1 myid ID #REQUIRED>
1817 <!ELEMENT p (#PCDATA)>
1818 <!ATTLIST p someid ID #REQUIRED>
1819 ]>
1820 <document>
1821 <h1 myid="chapter1">...</h1>
1822 <p id="note1" class="note">...</p>
1823 <p>Regular paragraph.</p>
1824 <p xml:id="xmlid">XML:ID paragraph.</p>
1825 <p someid="warn1" class="warning">...</p>
1826 </document>
1827 ''')
1828
1829 tree, dic = parseid(BytesIO(xml_text))
1830 root = tree.getroot()
1831 root2 = XML(xml_text)
1832 self.assertEquals(self._writeElement(root),
1833 self._writeElement(root2))
1834 expected = {
1835 "chapter1" : root[0],
1836 "xmlid" : root[3],
1837 "warn1" : root[4]
1838 }
1839 self.assert_("chapter1" in dic)
1840 self.assert_("warn1" in dic)
1841 self.assert_("xmlid" in dic)
1842 self._checkIDDict(dic, expected)
1843
1845 XMLDTDID = self.etree.XMLDTDID
1846 XML = self.etree.XML
1847 xml_text = _bytes('''
1848 <!DOCTYPE document [
1849 <!ELEMENT document (h1,p)*>
1850 <!ELEMENT h1 (#PCDATA)>
1851 <!ATTLIST h1 myid ID #REQUIRED>
1852 <!ELEMENT p (#PCDATA)>
1853 <!ATTLIST p someid ID #REQUIRED>
1854 ]>
1855 <document>
1856 <h1 myid="chapter1">...</h1>
1857 <p id="note1" class="note">...</p>
1858 <p>Regular paragraph.</p>
1859 <p xml:id="xmlid">XML:ID paragraph.</p>
1860 <p someid="warn1" class="warning">...</p>
1861 </document>
1862 ''')
1863
1864 root, dic = XMLDTDID(xml_text)
1865 root2 = XML(xml_text)
1866 self.assertEquals(self._writeElement(root),
1867 self._writeElement(root2))
1868 expected = {
1869 "chapter1" : root[0],
1870 "xmlid" : root[3],
1871 "warn1" : root[4]
1872 }
1873 self.assert_("chapter1" in dic)
1874 self.assert_("warn1" in dic)
1875 self.assert_("xmlid" in dic)
1876 self._checkIDDict(dic, expected)
1877
1879 XMLDTDID = self.etree.XMLDTDID
1880 XML = self.etree.XML
1881 xml_text = _bytes('''
1882 <document>
1883 <h1 myid="chapter1">...</h1>
1884 <p id="note1" class="note">...</p>
1885 <p>Regular paragraph.</p>
1886 <p someid="warn1" class="warning">...</p>
1887 </document>
1888 ''')
1889
1890 root, dic = XMLDTDID(xml_text)
1891 root2 = XML(xml_text)
1892 self.assertEquals(self._writeElement(root),
1893 self._writeElement(root2))
1894 expected = {}
1895 self._checkIDDict(dic, expected)
1896
1898 self.assertEquals(len(dic),
1899 len(expected))
1900 self.assertEquals(sorted(dic.items()),
1901 sorted(expected.items()))
1902 if sys.version_info < (3,):
1903 self.assertEquals(sorted(dic.iteritems()),
1904 sorted(expected.iteritems()))
1905 self.assertEquals(sorted(dic.keys()),
1906 sorted(expected.keys()))
1907 if sys.version_info < (3,):
1908 self.assertEquals(sorted(dic.iterkeys()),
1909 sorted(expected.iterkeys()))
1910 if sys.version_info < (3,):
1911 self.assertEquals(sorted(dic.values()),
1912 sorted(expected.values()))
1913 self.assertEquals(sorted(dic.itervalues()),
1914 sorted(expected.itervalues()))
1915
1917 etree = self.etree
1918
1919 r = {'foo': 'http://ns.infrae.com/foo'}
1920 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1921 self.assertEquals(
1922 'foo',
1923 e.prefix)
1924 self.assertEquals(
1925 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
1926 self._writeElement(e))
1927
1929 etree = self.etree
1930
1931 r = {None: 'http://ns.infrae.com/foo'}
1932 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1933 self.assertEquals(
1934 None,
1935 e.prefix)
1936 self.assertEquals(
1937 '{http://ns.infrae.com/foo}bar',
1938 e.tag)
1939 self.assertEquals(
1940 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
1941 self._writeElement(e))
1942
1944 etree = self.etree
1945
1946 r = {None: 'http://ns.infrae.com/foo',
1947 'hoi': 'http://ns.infrae.com/hoi'}
1948 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1949 e.set('{http://ns.infrae.com/hoi}test', 'value')
1950 self.assertEquals(
1951 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
1952 self._writeElement(e))
1953
1955 etree = self.etree
1956 r = {None: 'http://ns.infrae.com/foo',
1957 'hoi': 'http://ns.infrae.com/hoi'}
1958 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
1959 tree = etree.ElementTree(element=e)
1960 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
1961 self.assertEquals(
1962 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
1963 self._writeElement(e))
1964
1966 etree = self.etree
1967
1968 r = {None: 'http://ns.infrae.com/foo'}
1969 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1970 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1971
1972 e1.append(e2)
1973
1974 self.assertEquals(
1975 None,
1976 e1.prefix)
1977 self.assertEquals(
1978 None,
1979 e1[0].prefix)
1980 self.assertEquals(
1981 '{http://ns.infrae.com/foo}bar',
1982 e1.tag)
1983 self.assertEquals(
1984 '{http://ns.infrae.com/foo}bar',
1985 e1[0].tag)
1986
1988 etree = self.etree
1989
1990 r = {None: 'http://ns.infrae.com/BAR'}
1991 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
1992 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1993
1994 e1.append(e2)
1995
1996 self.assertEquals(
1997 None,
1998 e1.prefix)
1999 self.assertNotEquals(
2000 None,
2001 e2.prefix)
2002 self.assertEquals(
2003 '{http://ns.infrae.com/BAR}bar',
2004 e1.tag)
2005 self.assertEquals(
2006 '{http://ns.infrae.com/foo}bar',
2007 e2.tag)
2008
2010 ns_href = "http://a.b.c"
2011 one = self.etree.fromstring(
2012 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2013 baz = one[0][0]
2014
2015 two = self.etree.fromstring(
2016 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2017 two.append(baz)
2018 del one # make sure the source document is deallocated
2019
2020 self.assertEquals('{%s}baz' % ns_href, baz.tag)
2021 self.assertEquals(
2022 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2023 self.etree.tostring(two))
2024
2026 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>')
2027 root = self.etree.fromstring(xml)
2028 self.assertEquals(xml,
2029 self.etree.tostring(root))
2030 self.etree.cleanup_namespaces(root)
2031 self.assertEquals(
2032 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
2033 self.etree.tostring(root))
2034
2036 etree = self.etree
2037
2038 r = {None: 'http://ns.infrae.com/foo',
2039 'hoi': 'http://ns.infrae.com/hoi'}
2040 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2041 self.assertEquals(
2042 r,
2043 e.nsmap)
2044
2046 etree = self.etree
2047
2048 re = {None: 'http://ns.infrae.com/foo',
2049 'hoi': 'http://ns.infrae.com/hoi'}
2050 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2051
2052 rs = {None: 'http://ns.infrae.com/honk',
2053 'top': 'http://ns.infrae.com/top'}
2054 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2055
2056 r = re.copy()
2057 r.update(rs)
2058 self.assertEquals(re, e.nsmap)
2059 self.assertEquals(r, s.nsmap)
2060
2062 etree = self.etree
2063 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2064 self.assertEquals({'hha': None}, el.nsmap)
2065
2067 Element = self.etree.Element
2068 SubElement = self.etree.SubElement
2069
2070 a = Element('{a}a')
2071 b = SubElement(a, '{a}b')
2072 c = SubElement(a, '{a}c')
2073 d = SubElement(b, '{b}d')
2074 e = SubElement(c, '{a}e')
2075 f = SubElement(c, '{b}f')
2076
2077 self.assertEquals(
2078 [a],
2079 list(a.getiterator('{a}a')))
2080 self.assertEquals(
2081 [],
2082 list(a.getiterator('{b}a')))
2083 self.assertEquals(
2084 [],
2085 list(a.getiterator('a')))
2086 self.assertEquals(
2087 [f],
2088 list(c.getiterator('{b}*')))
2089 self.assertEquals(
2090 [d, f],
2091 list(a.getiterator('{b}*')))
2092
2094 Element = self.etree.Element
2095 Entity = self.etree.Entity
2096 SubElement = self.etree.SubElement
2097
2098 a = Element('a')
2099 b = SubElement(a, 'b')
2100 entity_b = Entity("TEST-b")
2101 b.append(entity_b)
2102
2103 self.assertEquals(
2104 [entity_b],
2105 list(a.getiterator(Entity)))
2106
2107 entity_a = Entity("TEST-a")
2108 a.append(entity_a)
2109
2110 self.assertEquals(
2111 [entity_b, entity_a],
2112 list(a.getiterator(Entity)))
2113
2114 self.assertEquals(
2115 [entity_b],
2116 list(b.getiterator(Entity)))
2117
2119 Element = self.etree.Element
2120 Comment = self.etree.Comment
2121 PI = self.etree.PI
2122 SubElement = self.etree.SubElement
2123
2124 a = Element('a')
2125 b = SubElement(a, 'b')
2126 a.append(Comment("test"))
2127 a.append(PI("pi", "content"))
2128 c = SubElement(a, 'c')
2129
2130 self.assertEquals(
2131 [a, b, c],
2132 list(a.getiterator(Element)))
2133
2135 # ElementTree iterates over everything here
2136 Element = self.etree.Element
2137 Comment = self.etree.Comment
2138 PI = self.etree.PI
2139 SubElement = self.etree.SubElement
2140
2141 a = Element('a')
2142 b = SubElement(a, 'b')
2143 a.append(Comment("test"))
2144 a.append(PI("pi", "content"))
2145 c = SubElement(a, 'c')
2146
2147 self.assertEquals(
2148 [a, b, c],
2149 list(a.getiterator('*')))
2150
2152 XML = self.etree.XML
2153 ElementTree = self.etree.ElementTree
2154 QName = self.etree.QName
2155 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
2156 self.assertEquals(tree.find(QName("c")), tree.getroot()[2])
2157
2159 XML = self.etree.XML
2160 ElementTree = self.etree.ElementTree
2161 QName = self.etree.QName
2162 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
2163 self.assertEquals(len(list(tree.findall(QName("c")))), 1)
2164
2166 XML = self.etree.XML
2167 ElementTree = self.etree.ElementTree
2168 QName = self.etree.QName
2169 tree = ElementTree(XML(
2170 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
2171 self.assertEquals(len(list(tree.findall(QName("b")))), 2)
2172 self.assertEquals(len(list(tree.findall(QName("X", "b")))), 1)
2173
2175 XML = self.etree.XML
2176 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2177 self.assertEquals(len(root.findall(".//{X}b")), 2)
2178 self.assertEquals(len(root.findall(".//{X}*")), 2)
2179 self.assertEquals(len(root.findall(".//b")), 3)
2180
2182 etree = self.etree
2183 e = etree.Element('foo')
2184 for i in range(10):
2185 etree.SubElement(e, 'a%s' % i)
2186 for i in range(10):
2187 self.assertEquals(
2188 i,
2189 e.index(e[i]))
2190 self.assertEquals(
2191 3, e.index(e[3], 3))
2192 self.assertRaises(
2193 ValueError, e.index, e[3], 4)
2194 self.assertRaises(
2195 ValueError, e.index, e[3], 0, 2)
2196 self.assertRaises(
2197 ValueError, e.index, e[8], 0, -3)
2198 self.assertRaises(
2199 ValueError, e.index, e[8], -5, -3)
2200 self.assertEquals(
2201 8, e.index(e[8], 0, -1))
2202 self.assertEquals(
2203 8, e.index(e[8], -12, -1))
2204 self.assertEquals(
2205 0, e.index(e[0], -12, -1))
2206
2208 etree = self.etree
2209 e = etree.Element('foo')
2210 for i in range(10):
2211 el = etree.SubElement(e, 'a%s' % i)
2212 el.text = "text%d" % i
2213 el.tail = "tail%d" % i
2214
2215 child0 = e[0]
2216 child1 = e[1]
2217 child2 = e[2]
2218
2219 e.replace(e[0], e[1])
2220 self.assertEquals(
2221 9, len(e))
2222 self.assertEquals(
2223 child1, e[0])
2224 self.assertEquals(
2225 child1.text, "text1")
2226 self.assertEquals(
2227 child1.tail, "tail1")
2228 self.assertEquals(
2229 child0.tail, "tail0")
2230 self.assertEquals(
2231 child2, e[1])
2232
2233 e.replace(e[-1], e[0])
2234 self.assertEquals(
2235 child1, e[-1])
2236 self.assertEquals(
2237 child1.text, "text1")
2238 self.assertEquals(
2239 child1.tail, "tail1")
2240 self.assertEquals(
2241 child2, e[0])
2242
2244 etree = self.etree
2245 e = etree.Element('foo')
2246 for i in range(10):
2247 etree.SubElement(e, 'a%s' % i)
2248
2249 new_element = etree.Element("test")
2250 new_element.text = "TESTTEXT"
2251 new_element.tail = "TESTTAIL"
2252 child1 = e[1]
2253 e.replace(e[0], new_element)
2254 self.assertEquals(
2255 new_element, e[0])
2256 self.assertEquals(
2257 "TESTTEXT",
2258 e[0].text)
2259 self.assertEquals(
2260 "TESTTAIL",
2261 e[0].tail)
2262 self.assertEquals(
2263 child1, e[1])
2264
2266 Element = self.etree.Element
2267 SubElement = self.etree.SubElement
2268
2269 a = Element('a')
2270
2271 e = Element('e')
2272 f = Element('f')
2273 g = Element('g')
2274
2275 s = [e, f, g]
2276 a[::-1] = s
2277 self.assertEquals(
2278 [g, f, e],
2279 list(a))
2280
2282 Element = self.etree.Element
2283 SubElement = self.etree.SubElement
2284
2285 a = Element('a')
2286 b = SubElement(a, 'b')
2287 c = SubElement(a, 'c')
2288 d = SubElement(a, 'd')
2289 e = SubElement(a, 'e')
2290
2291 x = Element('x')
2292 y = Element('y')
2293
2294 a[1::2] = [x, y]
2295 self.assertEquals(
2296 [b, x, d, y],
2297 list(a))
2298
2300 Element = self.etree.Element
2301 SubElement = self.etree.SubElement
2302
2303 a = Element('a')
2304 b = SubElement(a, 'b')
2305 c = SubElement(a, 'c')
2306 d = SubElement(a, 'd')
2307 e = SubElement(a, 'e')
2308
2309 x = Element('x')
2310 y = Element('y')
2311
2312 a[1::-1] = [x, y]
2313 self.assertEquals(
2314 [y, x, d, e],
2315 list(a))
2316
2318 Element = self.etree.Element
2319 SubElement = self.etree.SubElement
2320
2321 a = Element('a')
2322 b = SubElement(a, 'b')
2323 c = SubElement(a, 'c')
2324 d = SubElement(a, 'd')
2325 e = SubElement(a, 'e')
2326
2327 x = Element('x')
2328 y = Element('y')
2329
2330 a[::-2] = [x, y]
2331 self.assertEquals(
2332 [b, y, d, x],
2333 list(a))
2334
2336 Element = self.etree.Element
2337 SubElement = self.etree.SubElement
2338 try:
2339 slice
2340 except NameError:
2341 print("slice() not found")
2342 return
2343
2344 a = Element('a')
2345 b = SubElement(a, 'b')
2346 c = SubElement(a, 'c')
2347 d = SubElement(a, 'd')
2348 e = SubElement(a, 'e')
2349
2350 x = Element('x')
2351 y = Element('y')
2352 z = Element('z')
2353
2354 self.assertRaises(
2355 ValueError,
2356 operator.setitem, a, slice(1,None,2), [x, y, z])
2357
2358 self.assertEquals(
2359 [b, c, d, e],
2360 list(a))
2361
2363 XML = self.etree.XML
2364 root = XML(_bytes('''<?xml version="1.0"?>
2365 <root><test>
2366
2367 <bla/></test>
2368 </root>
2369 '''))
2370
2371 self.assertEquals(
2372 [2, 2, 4],
2373 [ el.sourceline for el in root.getiterator() ])
2374
2376 parse = self.etree.parse
2377 tree = parse(fileInTestDir('include/test_xinclude.xml'))
2378
2379 self.assertEquals(
2380 [1, 2, 3],
2381 [ el.sourceline for el in tree.getiterator() ])
2382
2384 iterparse = self.etree.iterparse
2385 lines = [ el.sourceline for (event, el) in
2386 iterparse(fileInTestDir('include/test_xinclude.xml')) ]
2387
2388 self.assertEquals(
2389 [2, 3, 1],
2390 lines)
2391
2393 iterparse = self.etree.iterparse
2394 lines = [ el.sourceline for (event, el) in
2395 iterparse(fileInTestDir('include/test_xinclude.xml'),
2396 events=("start",)) ]
2397
2398 self.assertEquals(
2399 [1, 2, 3],
2400 lines)
2401
2403 Element = self.etree.Element
2404 SubElement = self.etree.SubElement
2405 el = Element("test")
2406 self.assertEquals(None, el.sourceline)
2407
2408 child = SubElement(el, "test")
2409 self.assertEquals(None, el.sourceline)
2410 self.assertEquals(None, child.sourceline)
2411
2413 etree = self.etree
2414 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2415 docinfo = root.getroottree().docinfo
2416 self.assertEquals(docinfo.URL, "http://no/such/url")
2417
2419 etree = self.etree
2420 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2421 docinfo = root.getroottree().docinfo
2422 self.assertEquals(docinfo.URL, "http://no/such/url")
2423 docinfo.URL = "https://secret/url"
2424 self.assertEquals(docinfo.URL, "https://secret/url")
2425
2427 etree = self.etree
2428 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
2429 docinfo = tree.docinfo
2430 self.assertEquals(docinfo.URL, "http://no/such/url")
2431
2433 etree = self.etree
2434 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
2435 base_url="http://no/such/url")
2436 docinfo = tree.docinfo
2437 self.assertEquals(docinfo.URL, "http://no/such/url")
2438
2440 etree = self.etree
2441 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
2442 docinfo = root.getroottree().docinfo
2443 self.assertEquals(docinfo.URL, "http://no/such/url")
2444
2446 etree = self.etree
2447 xml_header = '<?xml version="1.0" encoding="ascii"?>'
2448 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2449 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2450 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
2451
2452 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2453
2454 tree = etree.parse(BytesIO(xml))
2455 docinfo = tree.docinfo
2456 self.assertEquals(docinfo.encoding, "ascii")
2457 self.assertEquals(docinfo.xml_version, "1.0")
2458 self.assertEquals(docinfo.public_id, pub_id)
2459 self.assertEquals(docinfo.system_url, sys_id)
2460 self.assertEquals(docinfo.root_name, 'html')
2461 self.assertEquals(docinfo.doctype, doctype_string)
2462
2464 etree = self.etree
2465 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
2466 sys_id = "some.dtd"
2467 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
2468 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2469
2470 tree = etree.parse(BytesIO(xml))
2471 docinfo = tree.docinfo
2472 self.assertEquals(docinfo.encoding, "UTF-8")
2473 self.assertEquals(docinfo.xml_version, "1.0")
2474 self.assertEquals(docinfo.public_id, None)
2475 self.assertEquals(docinfo.system_url, sys_id)
2476 self.assertEquals(docinfo.root_name, 'html')
2477 self.assertEquals(docinfo.doctype, doctype_string)
2478
2480 etree = self.etree
2481 xml = _bytes('<html><body></body></html>')
2482 tree = etree.parse(BytesIO(xml))
2483 docinfo = tree.docinfo
2484 self.assertEquals(docinfo.encoding, "UTF-8")
2485 self.assertEquals(docinfo.xml_version, "1.0")
2486 self.assertEquals(docinfo.public_id, None)
2487 self.assertEquals(docinfo.system_url, None)
2488 self.assertEquals(docinfo.root_name, 'html')
2489 self.assertEquals(docinfo.doctype, '')
2490
2492 etree = self.etree
2493 xml = _bytes('<!DOCTYPE root><root></root>')
2494 tree = etree.parse(BytesIO(xml))
2495 docinfo = tree.docinfo
2496 self.assertEquals(docinfo.encoding, "UTF-8")
2497 self.assertEquals(docinfo.xml_version, "1.0")
2498 self.assertEquals(docinfo.public_id, None)
2499 self.assertEquals(docinfo.system_url, None)
2500 self.assertEquals(docinfo.root_name, 'root')
2501 self.assertEquals(docinfo.doctype, '<!DOCTYPE root>')
2502
2504 etree = self.etree
2505 xml = _bytes('<!DOCTYPE root>\n<root/>')
2506 tree = etree.parse(BytesIO(xml))
2507 self.assertEquals(xml, etree.tostring(tree))
2508
2510 etree = self.etree
2511 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2512 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2513 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
2514
2515 xml = _bytes('<!DOCTYPE root>\n<root/>')
2516 tree = etree.parse(BytesIO(xml))
2517 self.assertEquals(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
2518 etree.tostring(tree, doctype=doctype_string))
2519
2521 etree = self.etree
2522 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2523 self.assertEquals(root.base, "http://no/such/url")
2524 self.assertEquals(
2525 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2526 root.base = "https://secret/url"
2527 self.assertEquals(root.base, "https://secret/url")
2528 self.assertEquals(
2529 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2530 "https://secret/url")
2531
2533 etree = self.etree
2534 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2535 self.assertEquals(root.base, "http://no/such/url")
2536 self.assertEquals(
2537 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2538 root.set('{http://www.w3.org/XML/1998/namespace}base',
2539 "https://secret/url")
2540 self.assertEquals(root.base, "https://secret/url")
2541 self.assertEquals(
2542 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2543 "https://secret/url")
2544
2546 etree = self.etree
2547 root = etree.HTML(_bytes("<html><body></body></html>"),
2548 base_url="http://no/such/url")
2549 self.assertEquals(root.base, "http://no/such/url")
2550
2552 etree = self.etree
2553 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
2554 self.assertEquals(root.base, "http://no/such/url")
2555
2557 # parse from a file object that returns unicode strings
2558 f = LargeFileLikeUnicode()
2559 tree = self.etree.parse(f)
2560 root = tree.getroot()
2561 self.assert_(root.tag.endswith('root'))
2562
2564 # check that DTDs that go in also go back out
2565 xml = _bytes('''\
2566 <!DOCTYPE test SYSTEM "test.dtd" [
2567 <!ENTITY entity "tasty">
2568 <!ELEMENT test (a)>
2569 <!ELEMENT a (#PCDATA)>
2570 ]>
2571 <test><a>test-test</a></test>\
2572 ''')
2573 tree = self.etree.parse(BytesIO(xml))
2574 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
2575 xml.replace(_bytes(" "), _bytes("")))
2576
2578 Element = self.etree.Element
2579
2580 a = Element('a')
2581 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
2582 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
2583
2584 self.assertRaises(ValueError, Element, 'ha\0ho')
2585
2587 Element = self.etree.Element
2588
2589 a = Element('a')
2590 self.assertRaises(ValueError, setattr, a, "text",
2591 _str('ha\0ho'))
2592 self.assertRaises(ValueError, setattr, a, "tail",
2593 _str('ha\0ho'))
2594
2595 self.assertRaises(ValueError, Element,
2596 _str('ha\0ho'))
2597
2599 Element = self.etree.Element
2600
2601 a = Element('a')
2602 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
2603 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
2604
2605 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
2606 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
2607
2608 self.assertRaises(ValueError, Element, 'ha\x07ho')
2609 self.assertRaises(ValueError, Element, 'ha\x02ho')
2610
2612 Element = self.etree.Element
2613
2614 a = Element('a')
2615 self.assertRaises(ValueError, setattr, a, "text",
2616 _str('ha\x07ho'))
2617 self.assertRaises(ValueError, setattr, a, "text",
2618 _str('ha\x02ho'))
2619
2620 self.assertRaises(ValueError, setattr, a, "tail",
2621 _str('ha\x07ho'))
2622 self.assertRaises(ValueError, setattr, a, "tail",
2623 _str('ha\x02ho'))
2624
2625 self.assertRaises(ValueError, Element,
2626 _str('ha\x07ho'))
2627 self.assertRaises(ValueError, Element,
2628 _str('ha\x02ho'))
2629
2631 Element = self.etree.Element
2632
2633 a = Element('a')
2634 self.assertRaises(ValueError, setattr, a, "text",
2635 _str('ha\u1234\x07ho'))
2636 self.assertRaises(ValueError, setattr, a, "text",
2637 _str('ha\u1234\x02ho'))
2638
2639 self.assertRaises(ValueError, setattr, a, "tail",
2640 _str('ha\u1234\x07ho'))
2641 self.assertRaises(ValueError, setattr, a, "tail",
2642 _str('ha\u1234\x02ho'))
2643
2644 self.assertRaises(ValueError, Element,
2645 _str('ha\u1234\x07ho'))
2646 self.assertRaises(ValueError, Element,
2647 _str('ha\u1234\x02ho'))
2648
2650 # ElementTree fails to serialize this
2651 tostring = self.etree.tostring
2652 Element = self.etree.Element
2653 SubElement = self.etree.SubElement
2654
2655 a = Element('a')
2656 b = SubElement(a, 'b')
2657 c = SubElement(a, 'c')
2658
2659 result = tostring(a, encoding='UTF-16')
2660 self.assertEquals(_bytes('<a><b></b><c></c></a>'),
2661 canonicalize(result))
2662
2664 # ElementTree raises an AssertionError here
2665 tostring = self.etree.tostring
2666 self.assertRaises(TypeError, self.etree.tostring, None)
2667
2669 tostring = self.etree.tostring
2670 Element = self.etree.Element
2671 SubElement = self.etree.SubElement
2672
2673 a = Element('a')
2674 b = SubElement(a, 'b')
2675 c = SubElement(a, 'c')
2676
2677 result = tostring(a)
2678 self.assertEquals(result, _bytes("<a><b/><c/></a>"))
2679
2680 result = tostring(a, pretty_print=False)
2681 self.assertEquals(result, _bytes("<a><b/><c/></a>"))
2682
2683 result = tostring(a, pretty_print=True)
2684 self.assertEquals(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
2685
2687 tostring = self.etree.tostring
2688 Element = self.etree.Element
2689 SubElement = self.etree.SubElement
2690
2691 a = Element('a')
2692 a.tail = "aTAIL"
2693 b = SubElement(a, 'b')
2694 b.tail = "bTAIL"
2695 c = SubElement(a, 'c')
2696
2697 result = tostring(a)
2698 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
2699
2700 result = tostring(a, with_tail=False)
2701 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>"))
2702
2703 result = tostring(a, with_tail=True)
2704 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
2705
2707 tostring = self.etree.tostring
2708 XML = self.etree.XML
2709 ElementTree = self.etree.ElementTree
2710 Element = self.etree.Element
2711
2712 tree = Element("root").getroottree()
2713 self.assertEquals(None, tree.docinfo.standalone)
2714
2715 tree = XML(_bytes("<root/>")).getroottree()
2716 self.assertEquals(None, tree.docinfo.standalone)
2717
2718 tree = XML(_bytes(
2719 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
2720 )).getroottree()
2721 self.assertEquals(True, tree.docinfo.standalone)
2722
2723 tree = XML(_bytes(
2724 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
2725 )).getroottree()
2726 self.assertEquals(False, tree.docinfo.standalone)
2727
2729 tostring = self.etree.tostring
2730 XML = self.etree.XML
2731 ElementTree = self.etree.ElementTree
2732
2733 root = XML(_bytes("<root/>"))
2734
2735 tree = ElementTree(root)
2736 self.assertEquals(None, tree.docinfo.standalone)
2737
2738 result = tostring(root, xml_declaration=True, encoding="ASCII")
2739 self.assertEquals(result, _bytes(
2740 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
2741
2742 result = tostring(root, xml_declaration=True, encoding="ASCII",
2743 standalone=True)
2744 self.assertEquals(result, _bytes(
2745 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
2746
2747 tree = ElementTree(XML(result))
2748 self.assertEquals(True, tree.docinfo.standalone)
2749
2750 result = tostring(root, xml_declaration=True, encoding="ASCII",
2751 standalone=False)
2752 self.assertEquals(result, _bytes(
2753 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
2754
2755 tree = ElementTree(XML(result))
2756 self.assertEquals(False, tree.docinfo.standalone)
2757
2759 tostring = self.etree.tostring
2760 XML = self.etree.XML
2761 ElementTree = self.etree.ElementTree
2762
2763 root = XML(_bytes(
2764 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
2765
2766 tree = ElementTree(root)
2767 self.assertEquals(True, tree.docinfo.standalone)
2768
2769 result = tostring(root, xml_declaration=True, encoding="ASCII")
2770 self.assertEquals(result, _bytes(
2771 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
2772
2773 result = tostring(root, xml_declaration=True, encoding="ASCII",
2774 standalone=True)
2775 self.assertEquals(result, _bytes(
2776 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
2777
2779 tostring = self.etree.tostring
2780 Element = self.etree.Element
2781 SubElement = self.etree.SubElement
2782
2783 a = Element('a')
2784 a.text = "A"
2785 a.tail = "tail"
2786 b = SubElement(a, 'b')
2787 b.text = "B"
2788 b.tail = _str("Søk på nettet")
2789 c = SubElement(a, 'c')
2790 c.text = "C"
2791
2792 result = tostring(a, method="text", encoding="UTF-16")
2793
2794 self.assertEquals(_str('ABSøk på nettetCtail').encode("UTF-16"),
2795 result)
2796
2798 tostring = self.etree.tostring
2799 Element = self.etree.Element
2800 SubElement = self.etree.SubElement
2801
2802 a = Element('a')
2803 a.text = _str('Søk på nettetA')
2804 a.tail = "tail"
2805 b = SubElement(a, 'b')
2806 b.text = "B"
2807 b.tail = _str('Søk på nettetB')
2808 c = SubElement(a, 'c')
2809 c.text = "C"
2810
2811 self.assertRaises(UnicodeEncodeError,
2812 tostring, a, method="text")
2813
2814 self.assertEquals(
2815 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
2816 tostring(a, encoding="UTF-8", method="text"))
2817
2819 tounicode = self.etree.tounicode
2820 Element = self.etree.Element
2821 SubElement = self.etree.SubElement
2822
2823 a = Element('a')
2824 b = SubElement(a, 'b')
2825 c = SubElement(a, 'c')
2826
2827 self.assert_(isinstance(tounicode(a), _unicode))
2828 self.assertEquals(_bytes('<a><b></b><c></c></a>'),
2829 canonicalize(tounicode(a)))
2830
2832 tounicode = self.etree.tounicode
2833 Element = self.etree.Element
2834 SubElement = self.etree.SubElement
2835
2836 a = Element('a')
2837 b = SubElement(a, 'b')
2838 c = SubElement(a, 'c')
2839 d = SubElement(c, 'd')
2840 self.assert_(isinstance(tounicode(b), _unicode))
2841 self.assert_(isinstance(tounicode(c), _unicode))
2842 self.assertEquals(_bytes('<b></b>'),
2843 canonicalize(tounicode(b)))
2844 self.assertEquals(_bytes('<c><d></d></c>'),
2845 canonicalize(tounicode(c)))
2846
2850
2852 tounicode = self.etree.tounicode
2853 Element = self.etree.Element
2854 SubElement = self.etree.SubElement
2855
2856 a = Element('a')
2857 b = SubElement(a, 'b')
2858 c = SubElement(a, 'c')
2859 d = SubElement(c, 'd')
2860 b.tail = 'Foo'
2861
2862 self.assert_(isinstance(tounicode(b), _unicode))
2863 self.assert_(tounicode(b) == '<b/>Foo' or
2864 tounicode(b) == '<b />Foo')
2865
2867 tounicode = self.etree.tounicode
2868 Element = self.etree.Element
2869 SubElement = self.etree.SubElement
2870
2871 a = Element('a')
2872 b = SubElement(a, 'b')
2873 c = SubElement(a, 'c')
2874
2875 result = tounicode(a)
2876 self.assertEquals(result, "<a><b/><c/></a>")
2877
2878 result = tounicode(a, pretty_print=False)
2879 self.assertEquals(result, "<a><b/><c/></a>")
2880
2881 result = tounicode(a, pretty_print=True)
2882 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2883
2885 tostring = self.etree.tostring
2886 Element = self.etree.Element
2887 SubElement = self.etree.SubElement
2888
2889 a = Element('a')
2890 b = SubElement(a, 'b')
2891 c = SubElement(a, 'c')
2892
2893 self.assert_(isinstance(tostring(a, encoding=_unicode), _unicode))
2894 self.assertEquals(_bytes('<a><b></b><c></c></a>'),
2895 canonicalize(tostring(a, encoding=_unicode)))
2896
2898 tostring = self.etree.tostring
2899 Element = self.etree.Element
2900 SubElement = self.etree.SubElement
2901
2902 a = Element('a')
2903 b = SubElement(a, 'b')
2904 c = SubElement(a, 'c')
2905 d = SubElement(c, 'd')
2906 self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
2907 self.assert_(isinstance(tostring(c, encoding=_unicode), _unicode))
2908 self.assertEquals(_bytes('<b></b>'),
2909 canonicalize(tostring(b, encoding=_unicode)))
2910 self.assertEquals(_bytes('<c><d></d></c>'),
2911 canonicalize(tostring(c, encoding=_unicode)))
2912
2914 tostring = self.etree.tostring
2915 self.assertRaises(TypeError, self.etree.tostring,
2916 None, encoding=_unicode)
2917
2919 tostring = self.etree.tostring
2920 Element = self.etree.Element
2921 SubElement = self.etree.SubElement
2922
2923 a = Element('a')
2924 b = SubElement(a, 'b')
2925 c = SubElement(a, 'c')
2926 d = SubElement(c, 'd')
2927 b.tail = 'Foo'
2928
2929 self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
2930 self.assert_(tostring(b, encoding=_unicode) == '<b/>Foo' or
2931 tostring(b, encoding=_unicode) == '<b />Foo')
2932
2934 tostring = self.etree.tostring
2935 Element = self.etree.Element
2936 SubElement = self.etree.SubElement
2937
2938 a = Element('a')
2939 b = SubElement(a, 'b')
2940 c = SubElement(a, 'c')
2941
2942 result = tostring(a, encoding=_unicode)
2943 self.assertEquals(result, "<a><b/><c/></a>")
2944
2945 result = tostring(a, encoding=_unicode, pretty_print=False)
2946 self.assertEquals(result, "<a><b/><c/></a>")
2947
2948 result = tostring(a, encoding=_unicode, pretty_print=True)
2949 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2950
2951 # helper methods
2952
2954 """Write out element for comparison.
2955 """
2956 ElementTree = self.etree.ElementTree
2957 f = BytesIO()
2958 tree = ElementTree(element=element)
2959 tree.write(f, encoding=encoding, compression=compression)
2960 data = f.getvalue()
2961 if compression:
2962 data = zlib.decompress(data)
2963 return canonicalize(data)
2964
2965
2968 filename = fileInTestDir('test_broken.xml')
2969 root = etree.XML(_bytes('''\
2970 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
2971 <xi:include href="%s" parse="text"/>
2972 </doc>
2973 ''' % filename))
2974 old_text = root.text
2975 content = read_file(filename)
2976 old_tail = root[0].tail
2977
2978 self.include( etree.ElementTree(root) )
2979 self.assertEquals(old_text + content + old_tail,
2980 root.text)
2981
2983 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
2984 self.assertNotEquals(
2985 'a',
2986 tree.getroot()[1].tag)
2987 # process xincludes
2988 self.include( tree )
2989 # check whether we find it replaced with included data
2990 self.assertEquals(
2991 'a',
2992 tree.getroot()[1].tag)
2993
2995 class res(etree.Resolver):
2996 include_text = read_file(fileInTestDir('test.xml'))
2997 called = {}
2998 def resolve(self, url, id, context):
2999 if url.endswith(".dtd"):
3000 self.called["dtd"] = True
3001 return self.resolve_filename(
3002 fileInTestDir('test.dtd'), context)
3003 elif url.endswith("test_xinclude.xml"):
3004 self.called["input"] = True
3005 return None # delegate to default resolver
3006 else:
3007 self.called["include"] = True
3008 return self.resolve_string(self.include_text, context)
3009
3010 res_instance = res()
3011 parser = etree.XMLParser(load_dtd = True)
3012 parser.resolvers.add(res_instance)
3013
3014 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3015 parser = parser)
3016
3017 self.include(tree)
3018
3019 called = list(res_instance.called.items())
3020 called.sort()
3021 self.assertEquals(
3022 [("dtd", True), ("include", True), ("input", True)],
3023 called)
3024
3028
3029
3034
3035
3038 tree = self.parse(_bytes('<a><b/></a>'))
3039 f = BytesIO()
3040 tree.write_c14n(f)
3041 s = f.getvalue()
3042 self.assertEquals(_bytes('<a><b></b></a>'),
3043 s)
3044
3046 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3047 f = BytesIO()
3048 tree.write_c14n(f, compression=9)
3049 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3050 try:
3051 s = gzfile.read()
3052 finally:
3053 gzfile.close()
3054 self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
3055 s)
3056
3058 tree = self.parse(_bytes('<a><b/></a>'))
3059 handle, filename = tempfile.mkstemp()
3060 try:
3061 tree.write_c14n(filename)
3062 data = read_file(filename, 'rb')
3063 finally:
3064 os.close(handle)
3065 os.remove(filename)
3066 self.assertEquals(_bytes('<a><b></b></a>'),
3067 data)
3068
3070 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3071 handle, filename = tempfile.mkstemp()
3072 try:
3073 tree.write_c14n(filename, compression=9)
3074 f = gzip.open(filename, 'rb')
3075 try:
3076 data = f.read()
3077 finally:
3078 f.close()
3079 finally:
3080 os.close(handle)
3081 os.remove(filename)
3082 self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
3083 data)
3084
3086 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3087 f = BytesIO()
3088 tree.write_c14n(f)
3089 s = f.getvalue()
3090 self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3091 s)
3092 f = BytesIO()
3093 tree.write_c14n(f, with_comments=True)
3094 s = f.getvalue()
3095 self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3096 s)
3097 f = BytesIO()
3098 tree.write_c14n(f, with_comments=False)
3099 s = f.getvalue()
3100 self.assertEquals(_bytes('<a><b></b></a>'),
3101 s)
3102
3104 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3105 s = etree.tostring(tree, method='c14n')
3106 self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3107 s)
3108 s = etree.tostring(tree, method='c14n', with_comments=True)
3109 self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3110 s)
3111 s = etree.tostring(tree, method='c14n', with_comments=False)
3112 self.assertEquals(_bytes('<a><b></b></a>'),
3113 s)
3114
3116 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3117 s = etree.tostring(tree.getroot(), method='c14n')
3118 self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
3119 s)
3120 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
3121 self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
3122 s)
3123 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
3124 self.assertEquals(_bytes('<a><b></b></a>'),
3125 s)
3126
3128 tree = self.parse(_bytes(
3129 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3130 f = BytesIO()
3131 tree.write_c14n(f)
3132 s = f.getvalue()
3133 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3134 s)
3135 f = BytesIO()
3136 tree.write_c14n(f, exclusive=False)
3137 s = f.getvalue()
3138 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3139 s)
3140 f = BytesIO()
3141 tree.write_c14n(f, exclusive=True)
3142 s = f.getvalue()
3143 self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3144 s)
3145
3147 tree = self.parse(_bytes(
3148 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3149 s = etree.tostring(tree, method='c14n')
3150 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3151 s)
3152 s = etree.tostring(tree, method='c14n', exclusive=False)
3153 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3154 s)
3155 s = etree.tostring(tree, method='c14n', exclusive=True)
3156 self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3157 s)
3158
3160 tree = self.parse(_bytes(
3161 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3162 s = etree.tostring(tree.getroot(), method='c14n')
3163 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3164 s)
3165 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3166 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3167 s)
3168 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3169 self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3170 s)
3171
3172 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3173 self.assertEquals(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3174 s)
3175 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3176 self.assertEquals(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3177 s)
3178
3179
3182 tree = self.parse(_bytes('<a><b/></a>'))
3183 f = BytesIO()
3184 tree.write(f)
3185 s = f.getvalue()
3186 self.assertEquals(_bytes('<a><b/></a>'),
3187 s)
3188
3190 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3191 f = BytesIO()
3192 tree.write(f, compression=9)
3193 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3194 try:
3195 s = gzfile.read()
3196 finally:
3197 gzfile.close()
3198 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
3199 s)
3200
3202 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3203 f = BytesIO()
3204 tree.write(f, compression=0)
3205 s0 = f.getvalue()
3206
3207 f = BytesIO()
3208 tree.write(f)
3209 self.assertEquals(f.getvalue(), s0)
3210
3211 f = BytesIO()
3212 tree.write(f, compression=1)
3213 s = f.getvalue()
3214 self.assert_(len(s) <= len(s0))
3215 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3216 try:
3217 s1 = gzfile.read()
3218 finally:
3219 gzfile.close()
3220
3221 f = BytesIO()
3222 tree.write(f, compression=9)
3223 s = f.getvalue()
3224 self.assert_(len(s) <= len(s0))
3225 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3226 try:
3227 s9 = gzfile.read()
3228 finally:
3229 gzfile.close()
3230
3231 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
3232 s0)
3233 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
3234 s1)
3235 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
3236 s9)
3237
3239 tree = self.parse(_bytes('<a><b/></a>'))
3240 handle, filename = tempfile.mkstemp()
3241 try:
3242 tree.write(filename)
3243 data = read_file(filename, 'rb')
3244 finally:
3245 os.close(handle)
3246 os.remove(filename)
3247 self.assertEquals(_bytes('<a><b/></a>'),
3248 data)
3249
3251 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3252 handle, filename = tempfile.mkstemp()
3253 try:
3254 tree.write(filename, compression=9)
3255 f = gzip.open(filename, 'rb')
3256 try:
3257 data = f.read()
3258 finally:
3259 f.close()
3260 finally:
3261 os.close(handle)
3262 os.remove(filename)
3263 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
3264 data)
3265
3267 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3268 handle, filename = tempfile.mkstemp()
3269 try:
3270 tree.write(filename, compression=9)
3271 data = etree.tostring(etree.parse(filename))
3272 finally:
3273 os.close(handle)
3274 os.remove(filename)
3275 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
3276 data)
3277
3279 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3280 handle, filename = tempfile.mkstemp()
3281 try:
3282 tree.write(filename, compression=9)
3283 data = etree.tostring(etree.parse(
3284 gzip.GzipFile(filename)))
3285 finally:
3286 os.close(handle)
3287 os.remove(filename)
3288 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
3289 data)
3290
3292 etree = etree
3293
3295 parse = self.etree.parse
3296 f = BytesIO('<a><b></c></b></a>')
3297 self.etree.clear_error_log()
3298 try:
3299 parse(f)
3300 logs = None
3301 except SyntaxError:
3302 e = sys.exc_info()[1]
3303 logs = e.error_log
3304 f.close()
3305 self.assert_([ log for log in logs
3306 if 'mismatch' in log.message ])
3307 self.assert_([ log for log in logs
3308 if 'PARSER' in log.domain_name])
3309 self.assert_([ log for log in logs
3310 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
3311 self.assert_([ log for log in logs
3312 if 1 == log.line ])
3313 self.assert_([ log for log in logs
3314 if 15 == log.column ])
3315
3326
3327 self.etree.use_global_python_log(Logger())
3328 f = BytesIO('<a><b></c></b></a>')
3329 try:
3330 parse(f)
3331 except SyntaxError:
3332 pass
3333 f.close()
3334
3335 self.assert_([ message for message in messages
3336 if 'mismatch' in message ])
3337 self.assert_([ message for message in messages
3338 if ':PARSER:' in message])
3339 self.assert_([ message for message in messages
3340 if ':ERR_TAG_NAME_MISMATCH:' in message ])
3341 self.assert_([ message for message in messages
3342 if ':1:15:' in message ])
3343
3345 suite = unittest.TestSuite()
3346 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
3347 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
3348 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
3349 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
3350 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
3351 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
3352 suite.addTests(
3353 [make_doctest('../../../doc/tutorial.txt')])
3354 suite.addTests(
3355 [make_doctest('../../../doc/api.txt')])
3356 suite.addTests(
3357 [make_doctest('../../../doc/FAQ.txt')])
3358 suite.addTests(
3359 [make_doctest('../../../doc/parsing.txt')])
3360 suite.addTests(
3361 [make_doctest('../../../doc/resolvers.txt')])
3362 return suite
3363
3364 if __name__ == '__main__':
3365 print('to test use test.py %s' % __file__)
3366
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Mar 26 15:26:11 2012 | http://epydoc.sourceforge.net |