1
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
11 import unittest, copy, sys, operator
12
13 from common_imports import etree, StringIO, HelperTestCase, fileInTestDir
14 from common_imports import SillyFileLike, canonicalize, doctest
15
16 print
17 print "TESTED VERSION:", etree.__version__
18 print " Python: ", sys.version_info
19 print " lxml.etree: ", etree.LXML_VERSION
20 print " libxml used: ", etree.LIBXML_VERSION
21 print " libxml compiled: ", etree.LIBXML_COMPILED_VERSION
22 print " libxslt used: ", etree.LIBXSLT_VERSION
23 print " libxslt compiled: ", etree.LIBXSLT_COMPILED_VERSION
24 print
25
26 try:
27 sorted
28 except NameError:
29
31 seq = list(seq)
32 seq.sort()
33 return seq
34
36 """Tests only for etree, not ElementTree"""
37 etree = etree
38
49
58
65
67 Element = self.etree.Element
68 el = Element('name')
69 self.assertRaises(ValueError, Element, '{}')
70 self.assertRaises(ValueError, setattr, el, 'tag', '{}')
71
72 self.assertRaises(ValueError, Element, '{test}')
73 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
74
82
84 Element = self.etree.Element
85 self.assertRaises(ValueError, Element, "p'name")
86 self.assertRaises(ValueError, Element, 'p"name')
87
88 self.assertRaises(ValueError, Element, "{test}p'name")
89 self.assertRaises(ValueError, Element, '{test}p"name')
90
91 el = Element('name')
92 self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
93 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
94
96 Element = self.etree.Element
97 self.assertRaises(ValueError, Element, ' name ')
98 self.assertRaises(ValueError, Element, 'na me')
99 self.assertRaises(ValueError, Element, '{test} name')
100
101 el = Element('name')
102 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
103
111
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
128 self.assertRaises(ValueError, SubElement, el, 'p"name')
129 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
130
139
141 QName = self.etree.QName
142 self.assertRaises(ValueError, QName, '')
143 self.assertRaises(ValueError, QName, 'test', '')
144
146 QName = self.etree.QName
147 self.assertRaises(ValueError, QName, 'p:name')
148 self.assertRaises(ValueError, QName, 'test', 'p:name')
149
151 QName = self.etree.QName
152 self.assertRaises(ValueError, QName, ' name ')
153 self.assertRaises(ValueError, QName, 'na me')
154 self.assertRaises(ValueError, QName, 'test', ' name')
155
157
158 etree = self.etree
159 qname = etree.QName('http://myns', 'a')
160 a = etree.Element(qname, nsmap={'p' : 'http://myns'})
161 a.text = qname
162
163 self.assertEquals("p:a", a.text)
164
166 etree = self.etree
167 self.assertRaises(ValueError,
168 etree.Element, "root", nsmap={'"' : 'testns'})
169 self.assertRaises(ValueError,
170 etree.Element, "root", nsmap={'&' : 'testns'})
171 self.assertRaises(ValueError,
172 etree.Element, "root", nsmap={'a:b' : 'testns'})
173
179
187
189
190 Element = self.etree.Element
191 SubElement = self.etree.SubElement
192 ProcessingInstruction = self.etree.ProcessingInstruction
193
194 a = Element('a')
195 a.append(ProcessingInstruction('foo', 'some more text'))
196 self.assertEquals(a[0].target, 'foo')
197 self.assertEquals(a[0].text, 'some more text')
198
200 XML = self.etree.XML
201 root = XML("<test><?mypi my test ?></test>")
202 self.assertEquals(root[0].target, "mypi")
203 self.assertEquals(root[0].text, "my test ")
204
206
207 ProcessingInstruction = self.etree.ProcessingInstruction
208
209 a = ProcessingInstruction("PI", "ONE")
210 b = copy.deepcopy(a)
211 b.text = "ANOTHER"
212
213 self.assertEquals('ONE', a.text)
214 self.assertEquals('ANOTHER', b.text)
215
225
237
256
261
263 parse = self.etree.parse
264
265 f = StringIO('<a><b></c></b></a>')
266 self.etree.clear_error_log()
267 try:
268 parse(f)
269 logs = None
270 except SyntaxError, e:
271 logs = e.error_log
272 f.close()
273 self.assert_([ log for log in logs
274 if 'mismatch' in log.message ])
275 self.assert_([ log for log in logs
276 if 'PARSER' in log.domain_name])
277 self.assert_([ log for log in logs
278 if 'TAG_NAME_MISMATCH' in log.type_name ])
279 self.assert_([ log for log in logs
280 if 1 == log.line ])
281 self.assert_([ log for log in logs
282 if 15 == log.column ])
283
296
307
308 f = StringIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
309 events = list(iterparse(f, events=('end', 'comment')))
310 root = events[-1][1]
311 self.assertEquals(6, len(events))
312 self.assertEquals(['A', ' B ', 'c', 'b', 'C', 'a'],
313 [ name(*item) for item in events ])
314 self.assertEquals(
315 '<a><!--A--><b><!-- B --><c/></b><!--C--></a>',
316 tostring(root))
317
329
330 f = StringIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
331 events = list(iterparse(f, events=('end', 'pi')))
332 root = events[-2][1]
333 self.assertEquals(8, len(events))
334 self.assertEquals([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
335 ('pid','d'), 'a', ('pie','e')],
336 [ name(*item) for item in events ])
337 self.assertEquals(
338 '<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>',
339 tostring(ElementTree(root)))
340
355
361
363 iterparse = self.etree.iterparse
364 f = StringIO("""
365 <a> \n \n <b> b test </b> \n
366
367 \n\t <c> \n </c> </a> \n """)
368 iterator = iterparse(f, remove_blank_text=True)
369 text = [ (element.text, element.tail)
370 for event, element in iterator ]
371 self.assertEquals(
372 [(" b test ", None), (" \n ", None), (None, None)],
373 text)
374
376 iterparse = self.etree.iterparse
377 f = StringIO('<a><b><d/></b><c/></a>')
378
379 iterator = iterparse(f, tag="b", events=('start', 'end'))
380 events = list(iterator)
381 root = iterator.root
382 self.assertEquals(
383 [('start', root[0]), ('end', root[0])],
384 events)
385
387 iterparse = self.etree.iterparse
388 f = StringIO('<a><b><d/></b><c/></a>')
389
390 iterator = iterparse(f, tag="*", events=('start', 'end'))
391 events = list(iterator)
392 self.assertEquals(
393 8,
394 len(events))
395
397 text = u'Søk på nettet'
398 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
399 xml_latin1 = (u'%s<a>%s</a>' % (wrong_declaration, text)
400 ).encode('iso-8859-1')
401
402 self.assertRaises(self.etree.ParseError,
403 list, self.etree.iterparse(StringIO(xml_latin1)))
404
405 iterator = self.etree.iterparse(StringIO(xml_latin1),
406 encoding="iso-8859-1")
407 self.assertEquals(1, len(list(iterator)))
408
409 a = iterator.root
410 self.assertEquals(a.text, text)
411
413 tostring = self.etree.tostring
414 f = StringIO('<root><![CDATA[test]]></root>')
415 context = self.etree.iterparse(f, strip_cdata=False)
416 content = [ el.text for event,el in context ]
417
418 self.assertEquals(['test'], content)
419 self.assertEquals('<root><![CDATA[test]]></root>',
420 tostring(context.root))
421
425
431 def end(self, tag):
432 events.append("end-" + tag)
433 def data(self, data):
434 events.append("data-" + data)
435 def comment(self, text):
436 events.append("comment-" + text)
437 def close(self):
438 return "DONE"
439
440 parser = self.etree.XMLParser(target=Target())
441
442 parser.feed('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')
443 done = parser.close()
444
445 self.assertEquals("DONE", done)
446 self.assertEquals(["comment-a", "start-root", "data-A", "comment-b",
447 "start-sub", "end-sub", "comment-c", "data-B",
448 "end-root", "comment-d"],
449 events)
450
452 events = []
453 class Target(object):
454 def start(self, tag, attrib):
455 events.append("start-" + tag)
456 def end(self, tag):
457 events.append("end-" + tag)
458 def data(self, data):
459 events.append("data-" + data)
460 def pi(self, target, data):
461 events.append("pi-" + target + "-" + data)
462 def close(self):
463 return "DONE"
464
465 parser = self.etree.XMLParser(target=Target())
466
467 parser.feed('<?test a?><root>A<?test b?>B</root><?test c?>')
468 done = parser.close()
469
470 self.assertEquals("DONE", done)
471 self.assertEquals(["pi-test-a", "start-root", "data-A", "pi-test-b",
472 "data-B", "end-root", "pi-test-c"],
473 events)
474
476 events = []
477 class Target(object):
478 def start(self, tag, attrib):
479 events.append("start-" + tag)
480 def end(self, tag):
481 events.append("end-" + tag)
482 def data(self, data):
483 events.append("data-" + data)
484 def close(self):
485 return "DONE"
486
487 parser = self.etree.XMLParser(target=Target(),
488 strip_cdata=False)
489
490 parser.feed('<root>A<a><![CDATA[ca]]></a>B</root>')
491 done = parser.close()
492
493 self.assertEquals("DONE", done)
494 self.assertEquals(["start-root", "data-A", "start-a",
495 "data-ca", "end-a", "data-B", "end-root"],
496 events)
497
507
517
526
536
538 iterwalk = self.etree.iterwalk
539 root = self.etree.XML('<a><b></b><c/></a>')
540
541 iterator = iterwalk(root, events=('start','end'))
542 events = list(iterator)
543 self.assertEquals(
544 [('start', root), ('start', root[0]), ('end', root[0]),
545 ('start', root[1]), ('end', root[1]), ('end', root)],
546 events)
547
558
560 iterwalk = self.etree.iterwalk
561 root = self.etree.XML('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')
562
563 attr_name = '{testns}bla'
564 events = []
565 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
566 for event, elem in iterator:
567 events.append(event)
568 if event == 'start':
569 if elem.tag != '{ns1}a':
570 elem.set(attr_name, 'value')
571
572 self.assertEquals(
573 ['start-ns', 'start', 'start', 'start-ns', 'start',
574 'end', 'end-ns', 'end', 'end', 'end-ns'],
575 events)
576
577 self.assertEquals(
578 None,
579 root.get(attr_name))
580 self.assertEquals(
581 'value',
582 root[0].get(attr_name))
583
585 iterwalk = self.etree.iterwalk
586 root = self.etree.XML('<a><b><d/></b><c/></a>')
587
588 counts = []
589 for event, elem in iterwalk(root):
590 counts.append(len(list(elem.getiterator())))
591 self.assertEquals(
592 [1,2,1,4],
593 counts)
594
596 parse = self.etree.parse
597 parser = self.etree.XMLParser(dtd_validation=True)
598 assertEqual = self.assertEqual
599 test_url = u"__nosuch.dtd"
600
601 class MyResolver(self.etree.Resolver):
602 def resolve(self, url, id, context):
603 assertEqual(url, test_url)
604 return self.resolve_string(
605 u'''<!ENTITY myentity "%s">
606 <!ELEMENT doc ANY>''' % url, context)
607
608 parser.resolvers.add(MyResolver())
609
610 xml = u'<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>' % test_url
611 tree = parse(StringIO(xml), parser)
612 root = tree.getroot()
613 self.assertEquals(root.text, test_url)
614
616 parse = self.etree.parse
617 parser = self.etree.XMLParser(attribute_defaults=True)
618 assertEqual = self.assertEqual
619 test_url = u"__nosuch.dtd"
620
621 class MyResolver(self.etree.Resolver):
622 def resolve(self, url, id, context):
623 assertEqual(url, test_url)
624 return self.resolve_filename(
625 fileInTestDir('test.dtd'), context)
626
627 parser.resolvers.add(MyResolver())
628
629 xml = u'<!DOCTYPE a SYSTEM "%s"><a><b/></a>' % test_url
630 tree = parse(StringIO(xml), parser)
631 root = tree.getroot()
632 self.assertEquals(
633 root.attrib, {'default': 'valueA'})
634 self.assertEquals(
635 root[0].attrib, {'default': 'valueB'})
636
638 parse = self.etree.parse
639 parser = self.etree.XMLParser(load_dtd=True)
640 assertEqual = self.assertEqual
641 test_url = u"__nosuch.dtd"
642
643 class check(object):
644 resolved = False
645
646 class MyResolver(self.etree.Resolver):
647 def resolve(self, url, id, context):
648 assertEqual(url, test_url)
649 check.resolved = True
650 return self.resolve_empty(context)
651
652 parser.resolvers.add(MyResolver())
653
654 xml = u'<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>' % test_url
655 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
656 self.assert_(check.resolved)
657
665
666 class MyResolver(self.etree.Resolver):
667 def resolve(self, url, id, context):
668 raise _LocalException
669
670 parser.resolvers.add(MyResolver())
671
672 xml = u'<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
673 self.assertRaises(_LocalException, parse, StringIO(xml), parser)
674
675 if etree.LIBXML_VERSION > (2,6,20):
692
708
715
717 Entity = self.etree.Entity
718 self.assertRaises(ValueError, Entity, 'a b c')
719 self.assertRaises(ValueError, Entity, 'a,b')
720 self.assertRaises(AssertionError, Entity, 'a\0b')
721 self.assertRaises(ValueError, Entity, '#abc')
722 self.assertRaises(ValueError, Entity, '#xxyz')
723
736
749
751 CDATA = self.etree.CDATA
752 Element = self.etree.Element
753
754 root = Element("root")
755 cdata = CDATA('test')
756
757 self.assertRaises(TypeError,
758 setattr, root, 'tail', cdata)
759 self.assertRaises(TypeError,
760 root.set, 'attr', cdata)
761 self.assertRaises(TypeError,
762 operator.setitem, root.attrib, 'attr', cdata)
763
772
773
783
788
801
814
820
826
841
843 Element = self.etree.Element
844 PI = self.etree.PI
845 root = Element('root')
846 pi = PI('TARGET', 'TEXT')
847 pi.tail = "TAIL"
848
849 self.assertEquals('<root></root>',
850 self._writeElement(root))
851 root.addprevious(pi)
852 self.assertEquals('<?TARGET TEXT?>\n<root></root>',
853 self._writeElement(root))
854
869
882
897
910
925
938
939
941 XML = self.etree.XML
942
943 root = XML('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')
944 values = root.values()
945 values.sort()
946 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
947
948
958
959
974
975
985
986
997
998
1000 self.assertRaises(TypeError, self.etree.dump, None)
1001
1003 ElementTree = self.etree.ElementTree
1004
1005 f = StringIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
1006 doc = ElementTree(file=f)
1007 a = doc.getroot()
1008 self.assertEquals(
1009 None,
1010 a.prefix)
1011 self.assertEquals(
1012 'foo',
1013 a[0].prefix)
1014
1016 ElementTree = self.etree.ElementTree
1017
1018 f = StringIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
1019 doc = ElementTree(file=f)
1020 a = doc.getroot()
1021 self.assertEquals(
1022 None,
1023 a.prefix)
1024 self.assertEquals(
1025 None,
1026 a[0].prefix)
1027
1029 Element = self.etree.Element
1030 SubElement = self.etree.SubElement
1031
1032 a = Element('a')
1033 b = SubElement(a, 'b')
1034 c = SubElement(a, 'c')
1035 d = SubElement(b, 'd')
1036 self.assertEquals(
1037 None,
1038 a.getparent())
1039 self.assertEquals(
1040 a,
1041 b.getparent())
1042 self.assertEquals(
1043 b.getparent(),
1044 c.getparent())
1045 self.assertEquals(
1046 b,
1047 d.getparent())
1048
1050 XML = self.etree.XML
1051
1052 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>')
1053 result = []
1054 for el in root.iterchildren():
1055 result.append(el.tag)
1056 self.assertEquals(['one', 'two', 'three'], result)
1057
1059 XML = self.etree.XML
1060
1061 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>')
1062 result = []
1063 for el in root.iterchildren(reversed=True):
1064 result.append(el.tag)
1065 self.assertEquals(['three', 'two', 'one'], result)
1066
1068 XML = self.etree.XML
1069
1070 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')
1071 result = []
1072 for el in root.iterchildren(tag='two'):
1073 result.append(el.text)
1074 self.assertEquals(['Two', 'Bla'], result)
1075
1077 XML = self.etree.XML
1078
1079 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')
1080 result = []
1081 for el in root.iterchildren(reversed=True, tag='two'):
1082 result.append(el.text)
1083 self.assertEquals(['Bla', 'Two'], result)
1084
1086 Element = self.etree.Element
1087 SubElement = self.etree.SubElement
1088
1089 a = Element('a')
1090 b = SubElement(a, 'b')
1091 c = SubElement(a, 'c')
1092 d = SubElement(b, 'd')
1093 self.assertEquals(
1094 [],
1095 list(a.iterancestors()))
1096 self.assertEquals(
1097 [a],
1098 list(b.iterancestors()))
1099 self.assertEquals(
1100 a,
1101 c.iterancestors().next())
1102 self.assertEquals(
1103 [b, a],
1104 list(d.iterancestors()))
1105
1117
1134
1155
1173
1190
1208
1210 Element = self.etree.Element
1211 SubElement = self.etree.SubElement
1212
1213 a = Element('a')
1214 b = SubElement(a, 'b')
1215 c = SubElement(a, 'c')
1216 d = SubElement(b, 'd')
1217 self.assertEquals(
1218 [],
1219 list(a.itersiblings()))
1220 self.assertEquals(
1221 [c],
1222 list(b.itersiblings()))
1223 self.assertEquals(
1224 c,
1225 b.itersiblings().next())
1226 self.assertEquals(
1227 [],
1228 list(c.itersiblings()))
1229 self.assertEquals(
1230 [b],
1231 list(c.itersiblings(preceding=True)))
1232 self.assertEquals(
1233 [],
1234 list(b.itersiblings(preceding=True)))
1235
1237 Element = self.etree.Element
1238 SubElement = self.etree.SubElement
1239
1240 a = Element('a')
1241 b = SubElement(a, 'b')
1242 c = SubElement(a, 'c')
1243 d = SubElement(b, 'd')
1244 self.assertEquals(
1245 [],
1246 list(a.itersiblings(tag='XXX')))
1247 self.assertEquals(
1248 [c],
1249 list(b.itersiblings(tag='c')))
1250 self.assertEquals(
1251 [b],
1252 list(c.itersiblings(preceding=True, tag='b')))
1253 self.assertEquals(
1254 [],
1255 list(c.itersiblings(preceding=True, tag='c')))
1256
1258 parseid = self.etree.parseid
1259 XML = self.etree.XML
1260 xml_text = '''
1261 <!DOCTYPE document [
1262 <!ELEMENT document (h1,p)*>
1263 <!ELEMENT h1 (#PCDATA)>
1264 <!ATTLIST h1 myid ID #REQUIRED>
1265 <!ELEMENT p (#PCDATA)>
1266 <!ATTLIST p someid ID #REQUIRED>
1267 ]>
1268 <document>
1269 <h1 myid="chapter1">...</h1>
1270 <p id="note1" class="note">...</p>
1271 <p>Regular paragraph.</p>
1272 <p xml:id="xmlid">XML:ID paragraph.</p>
1273 <p someid="warn1" class="warning">...</p>
1274 </document>
1275 '''
1276
1277 tree, dic = parseid(StringIO(xml_text))
1278 root = tree.getroot()
1279 root2 = XML(xml_text)
1280 self.assertEquals(self._writeElement(root),
1281 self._writeElement(root2))
1282 expected = {
1283 "chapter1" : root[0],
1284 "xmlid" : root[3],
1285 "warn1" : root[4]
1286 }
1287 self.assert_("chapter1" in dic)
1288 self.assert_("warn1" in dic)
1289 self.assert_("xmlid" in dic)
1290 self._checkIDDict(dic, expected)
1291
1293 XMLDTDID = self.etree.XMLDTDID
1294 XML = self.etree.XML
1295 xml_text = '''
1296 <!DOCTYPE document [
1297 <!ELEMENT document (h1,p)*>
1298 <!ELEMENT h1 (#PCDATA)>
1299 <!ATTLIST h1 myid ID #REQUIRED>
1300 <!ELEMENT p (#PCDATA)>
1301 <!ATTLIST p someid ID #REQUIRED>
1302 ]>
1303 <document>
1304 <h1 myid="chapter1">...</h1>
1305 <p id="note1" class="note">...</p>
1306 <p>Regular paragraph.</p>
1307 <p xml:id="xmlid">XML:ID paragraph.</p>
1308 <p someid="warn1" class="warning">...</p>
1309 </document>
1310 '''
1311
1312 root, dic = XMLDTDID(xml_text)
1313 root2 = XML(xml_text)
1314 self.assertEquals(self._writeElement(root),
1315 self._writeElement(root2))
1316 expected = {
1317 "chapter1" : root[0],
1318 "xmlid" : root[3],
1319 "warn1" : root[4]
1320 }
1321 self.assert_("chapter1" in dic)
1322 self.assert_("warn1" in dic)
1323 self.assert_("xmlid" in dic)
1324 self._checkIDDict(dic, expected)
1325
1327 XMLDTDID = self.etree.XMLDTDID
1328 XML = self.etree.XML
1329 xml_text = '''
1330 <document>
1331 <h1 myid="chapter1">...</h1>
1332 <p id="note1" class="note">...</p>
1333 <p>Regular paragraph.</p>
1334 <p someid="warn1" class="warning">...</p>
1335 </document>
1336 '''
1337
1338 root, dic = XMLDTDID(xml_text)
1339 root2 = XML(xml_text)
1340 self.assertEquals(self._writeElement(root),
1341 self._writeElement(root2))
1342 expected = {}
1343 self._checkIDDict(dic, expected)
1344
1346 self.assertEquals(dic, expected)
1347 self.assertEquals(len(dic),
1348 len(expected))
1349 self.assertEquals(sorted(dic.items()),
1350 sorted(expected.items()))
1351 self.assertEquals(sorted(dic.iteritems()),
1352 sorted(expected.iteritems()))
1353 self.assertEquals(sorted(dic.keys()),
1354 sorted(expected.keys()))
1355 self.assertEquals(sorted(dic.iterkeys()),
1356 sorted(expected.iterkeys()))
1357 self.assertEquals(sorted(dic.values()),
1358 sorted(expected.values()))
1359 self.assertEquals(sorted(dic.itervalues()),
1360 sorted(expected.itervalues()))
1361
1363 etree = self.etree
1364
1365 r = {'foo': 'http://ns.infrae.com/foo'}
1366 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1367 self.assertEquals(
1368 'foo',
1369 e.prefix)
1370 self.assertEquals(
1371 '<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>',
1372 self._writeElement(e))
1373
1375 etree = self.etree
1376
1377 r = {None: 'http://ns.infrae.com/foo'}
1378 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1379 self.assertEquals(
1380 None,
1381 e.prefix)
1382 self.assertEquals(
1383 '{http://ns.infrae.com/foo}bar',
1384 e.tag)
1385 self.assertEquals(
1386 '<bar xmlns="http://ns.infrae.com/foo"></bar>',
1387 self._writeElement(e))
1388
1390 etree = self.etree
1391
1392 r = {None: 'http://ns.infrae.com/foo',
1393 'hoi': 'http://ns.infrae.com/hoi'}
1394 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1395 e.set('{http://ns.infrae.com/hoi}test', 'value')
1396 self.assertEquals(
1397 '<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>',
1398 self._writeElement(e))
1399
1401 etree = self.etree
1402 r = {None: 'http://ns.infrae.com/foo',
1403 'hoi': 'http://ns.infrae.com/hoi'}
1404 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
1405 tree = etree.ElementTree(element=e)
1406 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
1407 self.assertEquals(
1408 '<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>',
1409 self._writeElement(e))
1410
1412 etree = self.etree
1413
1414 r = {None: 'http://ns.infrae.com/foo'}
1415 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1416 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1417
1418 e1.append(e2)
1419
1420 self.assertEquals(
1421 None,
1422 e1.prefix)
1423 self.assertEquals(
1424 None,
1425 e1[0].prefix)
1426 self.assertEquals(
1427 '{http://ns.infrae.com/foo}bar',
1428 e1.tag)
1429 self.assertEquals(
1430 '{http://ns.infrae.com/foo}bar',
1431 e1[0].tag)
1432
1434 etree = self.etree
1435
1436 r = {None: 'http://ns.infrae.com/BAR'}
1437 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
1438 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1439
1440 e1.append(e2)
1441
1442 self.assertEquals(
1443 None,
1444 e1.prefix)
1445 self.assertNotEquals(
1446 None,
1447 e2.prefix)
1448 self.assertEquals(
1449 '{http://ns.infrae.com/BAR}bar',
1450 e1.tag)
1451 self.assertEquals(
1452 '{http://ns.infrae.com/foo}bar',
1453 e2.tag)
1454
1456 ns_href = "http://a.b.c"
1457 one = self.etree.fromstring(
1458 '<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)
1459 baz = one[0][0]
1460
1461 two = self.etree.fromstring(
1462 '<root xmlns:ns="%s"/>' % ns_href)
1463 two.append(baz)
1464 del one
1465
1466 self.assertEquals('{%s}baz' % ns_href, baz.tag)
1467 self.assertEquals(
1468 '<root xmlns:ns="%s"><ns:baz/></root>' % ns_href,
1469 self.etree.tostring(two))
1470
1472 etree = self.etree
1473
1474 r = {None: 'http://ns.infrae.com/foo',
1475 'hoi': 'http://ns.infrae.com/hoi'}
1476 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1477 self.assertEquals(
1478 r,
1479 e.nsmap)
1480
1482 etree = self.etree
1483
1484 re = {None: 'http://ns.infrae.com/foo',
1485 'hoi': 'http://ns.infrae.com/hoi'}
1486 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
1487
1488 rs = {None: 'http://ns.infrae.com/honk',
1489 'top': 'http://ns.infrae.com/top'}
1490 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
1491
1492 r = re.copy()
1493 r.update(rs)
1494 self.assertEquals(
1495 re,
1496 e.nsmap)
1497 self.assertEquals(
1498 r,
1499 s.nsmap)
1500
1502 Element = self.etree.Element
1503 SubElement = self.etree.SubElement
1504
1505 a = Element('{a}a')
1506 b = SubElement(a, '{a}b')
1507 c = SubElement(a, '{a}c')
1508 d = SubElement(b, '{b}d')
1509 e = SubElement(c, '{a}e')
1510 f = SubElement(c, '{b}f')
1511
1512 self.assertEquals(
1513 [a],
1514 list(a.getiterator('{a}a')))
1515 self.assertEquals(
1516 [],
1517 list(a.getiterator('{b}a')))
1518 self.assertEquals(
1519 [],
1520 list(a.getiterator('a')))
1521 self.assertEquals(
1522 [f],
1523 list(c.getiterator('{b}*')))
1524 self.assertEquals(
1525 [d, f],
1526 list(a.getiterator('{b}*')))
1527
1552
1568
1585
1592
1599
1608
1610 XML = self.etree.XML
1611 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
1612 self.assertEquals(len(root.findall(".//{X}b")), 2)
1613 self.assertEquals(len(root.findall(".//{X}*")), 2)
1614 self.assertEquals(len(root.findall(".//b")), 3)
1615
1617 etree = self.etree
1618 e = etree.Element('foo')
1619 for i in range(10):
1620 etree.SubElement(e, 'a%s' % i)
1621 for i in range(10):
1622 self.assertEquals(
1623 i,
1624 e.index(e[i]))
1625 self.assertEquals(
1626 3, e.index(e[3], 3))
1627 self.assertRaises(
1628 ValueError, e.index, e[3], 4)
1629 self.assertRaises(
1630 ValueError, e.index, e[3], 0, 2)
1631 self.assertRaises(
1632 ValueError, e.index, e[8], 0, -3)
1633 self.assertRaises(
1634 ValueError, e.index, e[8], -5, -3)
1635 self.assertEquals(
1636 8, e.index(e[8], 0, -1))
1637 self.assertEquals(
1638 8, e.index(e[8], -12, -1))
1639 self.assertEquals(
1640 0, e.index(e[0], -12, -1))
1641
1643 etree = self.etree
1644 e = etree.Element('foo')
1645 for i in range(10):
1646 el = etree.SubElement(e, 'a%s' % i)
1647 el.text = "text%d" % i
1648 el.tail = "tail%d" % i
1649
1650 child0 = e[0]
1651 child1 = e[1]
1652 child2 = e[2]
1653
1654 e.replace(e[0], e[1])
1655 self.assertEquals(
1656 9, len(e))
1657 self.assertEquals(
1658 child1, e[0])
1659 self.assertEquals(
1660 child1.text, "text1")
1661 self.assertEquals(
1662 child1.tail, "tail1")
1663 self.assertEquals(
1664 child0.tail, "tail0")
1665 self.assertEquals(
1666 child2, e[1])
1667
1668 e.replace(e[-1], e[0])
1669 self.assertEquals(
1670 child1, e[-1])
1671 self.assertEquals(
1672 child1.text, "text1")
1673 self.assertEquals(
1674 child1.tail, "tail1")
1675 self.assertEquals(
1676 child2, e[0])
1677
1679 etree = self.etree
1680 e = etree.Element('foo')
1681 for i in range(10):
1682 etree.SubElement(e, 'a%s' % i)
1683
1684 new_element = etree.Element("test")
1685 new_element.text = "TESTTEXT"
1686 new_element.tail = "TESTTAIL"
1687 child1 = e[1]
1688 e.replace(e[0], new_element)
1689 self.assertEquals(
1690 new_element, e[0])
1691 self.assertEquals(
1692 "TESTTEXT",
1693 e[0].text)
1694 self.assertEquals(
1695 "TESTTAIL",
1696 e[0].tail)
1697 self.assertEquals(
1698 child1, e[1])
1699
1715
1733
1751
1769
1771 Element = self.etree.Element
1772 SubElement = self.etree.SubElement
1773 try:
1774 slice
1775 except NameError:
1776 print "slice() not found"
1777 return
1778
1779 a = Element('a')
1780 b = SubElement(a, 'b')
1781 c = SubElement(a, 'c')
1782 d = SubElement(a, 'd')
1783 e = SubElement(a, 'e')
1784
1785 x = Element('x')
1786 y = Element('y')
1787 z = Element('z')
1788
1789 self.assertRaises(
1790 ValueError,
1791 operator.setitem, a, slice(1,None,2), [x, y, z])
1792
1793 self.assertEquals(
1794 [b, c, d, e],
1795 list(a))
1796
1798 XML = self.etree.XML
1799 root = XML('''<?xml version="1.0"?>
1800 <root><test>
1801
1802 <bla/></test>
1803 </root>
1804 ''')
1805
1806 self.assertEquals(
1807 [2, 2, 4],
1808 [ el.sourceline for el in root.getiterator() ])
1809
1811 parse = self.etree.parse
1812 tree = parse(fileInTestDir('include/test_xinclude.xml'))
1813
1814 self.assertEquals(
1815 [1, 2, 3],
1816 [ el.sourceline for el in tree.getiterator() ])
1817
1826
1828 iterparse = self.etree.iterparse
1829 lines = [ el.sourceline for (event, el) in
1830 iterparse(fileInTestDir('include/test_xinclude.xml'),
1831 events=("start",)) ]
1832
1833 self.assertEquals(
1834 [1, 2, 3],
1835 lines)
1836
1846
1848 etree = self.etree
1849 root = etree.XML("<root/>", base_url="http://no/such/url")
1850 docinfo = root.getroottree().docinfo
1851 self.assertEquals(docinfo.URL, "http://no/such/url")
1852
1854 etree = self.etree
1855 root = etree.XML("<root/>", base_url="http://no/such/url")
1856 docinfo = root.getroottree().docinfo
1857 self.assertEquals(docinfo.URL, "http://no/such/url")
1858 docinfo.URL = "https://secret/url"
1859 self.assertEquals(docinfo.URL, "https://secret/url")
1860
1862 etree = self.etree
1863 tree = etree.parse(StringIO("<root/>"), base_url="http://no/such/url")
1864 docinfo = tree.docinfo
1865 self.assertEquals(docinfo.URL, "http://no/such/url")
1866
1868 etree = self.etree
1869 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
1870 base_url="http://no/such/url")
1871 docinfo = tree.docinfo
1872 self.assertEquals(docinfo.URL, "http://no/such/url")
1873
1875 etree = self.etree
1876 root = etree.HTML("<html/>", base_url="http://no/such/url")
1877 docinfo = root.getroottree().docinfo
1878 self.assertEquals(docinfo.URL, "http://no/such/url")
1879
1881 etree = self.etree
1882 xml_header = '<?xml version="1.0" encoding="ascii"?>'
1883 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
1884 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
1885 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
1886
1887 xml = xml_header + doctype_string + '<html><body></body></html>'
1888
1889 tree = etree.parse(StringIO(xml))
1890 docinfo = tree.docinfo
1891 self.assertEquals(docinfo.encoding, "ascii")
1892 self.assertEquals(docinfo.xml_version, "1.0")
1893 self.assertEquals(docinfo.public_id, pub_id)
1894 self.assertEquals(docinfo.system_url, sys_id)
1895 self.assertEquals(docinfo.root_name, 'html')
1896 self.assertEquals(docinfo.doctype, doctype_string)
1897
1899 etree = self.etree
1900 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
1901 sys_id = "some.dtd"
1902 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
1903 xml = xml_header + doctype_string + '<html><body></body></html>'
1904
1905 tree = etree.parse(StringIO(xml))
1906 docinfo = tree.docinfo
1907 self.assertEquals(docinfo.encoding, "UTF-8")
1908 self.assertEquals(docinfo.xml_version, "1.0")
1909 self.assertEquals(docinfo.public_id, None)
1910 self.assertEquals(docinfo.system_url, sys_id)
1911 self.assertEquals(docinfo.root_name, 'html')
1912 self.assertEquals(docinfo.doctype, doctype_string)
1913
1915 etree = self.etree
1916 xml = '<html><body></body></html>'
1917 tree = etree.parse(StringIO(xml))
1918 docinfo = tree.docinfo
1919 self.assertEquals(docinfo.encoding, None)
1920 self.assertEquals(docinfo.xml_version, "1.0")
1921 self.assertEquals(docinfo.public_id, None)
1922 self.assertEquals(docinfo.system_url, None)
1923 self.assertEquals(docinfo.root_name, 'html')
1924 self.assertEquals(docinfo.doctype, '')
1925
1927 etree = self.etree
1928 root = etree.XML("<root/>", base_url="http://no/such/url")
1929 self.assertEquals(root.base, "http://no/such/url")
1930 self.assertEquals(
1931 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
1932 root.base = "https://secret/url"
1933 self.assertEquals(root.base, "https://secret/url")
1934 self.assertEquals(
1935 root.get('{http://www.w3.org/XML/1998/namespace}base'),
1936 "https://secret/url")
1937
1939 etree = self.etree
1940 root = etree.XML("<root/>", base_url="http://no/such/url")
1941 self.assertEquals(root.base, "http://no/such/url")
1942 self.assertEquals(
1943 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
1944 root.set('{http://www.w3.org/XML/1998/namespace}base',
1945 "https://secret/url")
1946 self.assertEquals(root.base, "https://secret/url")
1947 self.assertEquals(
1948 root.get('{http://www.w3.org/XML/1998/namespace}base'),
1949 "https://secret/url")
1950
1952 etree = self.etree
1953 root = etree.HTML("<html><body></body></html>",
1954 base_url="http://no/such/url")
1955 self.assertEquals(root.base, "http://no/such/url")
1956
1958 etree = self.etree
1959 root = etree.HTML('<html><head><base href="http://no/such/url"></head></html>')
1960 self.assertEquals(root.base, "http://no/such/url")
1961
1963
1964 xml = '''\
1965 <!DOCTYPE test SYSTEM "test.dtd" [
1966 <!ENTITY entity "tasty">
1967 <!ELEMENT test (a)>
1968 <!ELEMENT a (#PCDATA)>
1969 ]>
1970 <test><a>test-test</a></test>\
1971 '''
1972 tree = self.etree.parse(StringIO(xml))
1973 self.assertEqual(self.etree.tostring(tree).replace(" ", ""),
1974 xml.replace(" ", ""))
1975
1977 Element = self.etree.Element
1978
1979 a = Element('a')
1980 self.assertRaises(AssertionError, setattr, a, "text", 'ha\0ho')
1981 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\0ho')
1982
1983 self.assertRaises(AssertionError, Element, 'ha\0ho')
1984
1986 Element = self.etree.Element
1987
1988 a = Element('a')
1989 self.assertRaises(AssertionError, setattr, a, "text", u'ha\0ho')
1990 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\0ho')
1991
1992 self.assertRaises(AssertionError, Element, u'ha\0ho')
1993
1995 Element = self.etree.Element
1996
1997 a = Element('a')
1998 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x07ho')
1999 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x02ho')
2000
2001 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x07ho')
2002 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x02ho')
2003
2004 self.assertRaises(AssertionError, Element, 'ha\x07ho')
2005 self.assertRaises(AssertionError, Element, 'ha\x02ho')
2006
2008 Element = self.etree.Element
2009
2010 a = Element('a')
2011 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x07ho')
2012 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x02ho')
2013
2014 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x07ho')
2015 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x02ho')
2016
2017 self.assertRaises(AssertionError, Element, u'ha\x07ho')
2018 self.assertRaises(AssertionError, Element, u'ha\x02ho')
2019
2033
2038
2056
2076
2078 tostring = self.etree.tostring
2079 Element = self.etree.Element
2080 SubElement = self.etree.SubElement
2081
2082 a = Element('a')
2083 a.text = "A"
2084 a.tail = "tail"
2085 b = SubElement(a, 'b')
2086 b.text = "B"
2087 b.tail = u"Søk på nettet"
2088 c = SubElement(a, 'c')
2089 c.text = "C"
2090
2091 result = tostring(a, method="text", encoding="UTF-16")
2092
2093 self.assertEquals(u'ABSøk på nettetCtail'.encode("UTF-16"),
2094 result)
2095
2097 tostring = self.etree.tostring
2098 Element = self.etree.Element
2099 SubElement = self.etree.SubElement
2100
2101 a = Element('a')
2102 a.text = u'Søk på nettetA'
2103 a.tail = "tail"
2104 b = SubElement(a, 'b')
2105 b.text = "B"
2106 b.tail = u'Søk på nettetB'
2107 c = SubElement(a, 'c')
2108 c.text = "C"
2109
2110 self.assertRaises(UnicodeEncodeError,
2111 tostring, a, method="text")
2112
2113 self.assertEquals(
2114 u'Søk på nettetABSøk på nettetBCtail'.encode('utf-8'),
2115 tostring(a, encoding="UTF-8", method="text"))
2116
2129
2145
2149
2164
2182
2195
2197 tostring = self.etree.tostring
2198 Element = self.etree.Element
2199 SubElement = self.etree.SubElement
2200
2201 a = Element('a')
2202 b = SubElement(a, 'b')
2203 c = SubElement(a, 'c')
2204 d = SubElement(c, 'd')
2205 self.assert_(isinstance(tostring(b, encoding=unicode), unicode))
2206 self.assert_(isinstance(tostring(c, encoding=unicode), unicode))
2207 self.assertEquals('<b></b>',
2208 canonicalize(tostring(b, encoding=unicode)))
2209 self.assertEquals('<c><d></d></c>',
2210 canonicalize(tostring(c, encoding=unicode)))
2211
2216
2231
2233 tostring = self.etree.tostring
2234 Element = self.etree.Element
2235 SubElement = self.etree.SubElement
2236
2237 a = Element('a')
2238 b = SubElement(a, 'b')
2239 c = SubElement(a, 'c')
2240
2241 result = tostring(a, encoding=unicode)
2242 self.assertEquals(result, "<a><b/><c/></a>")
2243
2244 result = tostring(a, encoding=unicode, pretty_print=False)
2245 self.assertEquals(result, "<a><b/><c/></a>")
2246
2247 result = tostring(a, encoding=unicode, pretty_print=True)
2248 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2249
2250
2251
2261
2262
2265 filename = fileInTestDir('test_broken.xml')
2266 root = etree.XML('''\
2267 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
2268 <xi:include href="%s" parse="text"/>
2269 </doc>
2270 ''' % filename)
2271 old_text = root.text
2272 content = open(filename).read()
2273 old_tail = root[0].tail
2274
2275 self.include( etree.ElementTree(root) )
2276 self.assertEquals(old_text + content + old_tail,
2277 root.text)
2278
2280 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
2281 self.assertNotEquals(
2282 'a',
2283 tree.getroot()[1].tag)
2284
2285 self.include( tree )
2286
2287 self.assertEquals(
2288 'a',
2289 tree.getroot()[1].tag)
2290
2294
2295
2300
2301
2304 tree = self.parse('<a><b/></a>')
2305 f = StringIO()
2306 tree.write_c14n(f)
2307 s = f.getvalue()
2308 self.assertEquals('<a><b></b></a>',
2309 s)
2310
2312 suite = unittest.TestSuite()
2313 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
2314 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
2315 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
2316 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
2317 suite.addTests(
2318 [doctest.DocFileSuite('../../../doc/tutorial.txt')])
2319 suite.addTests(
2320 [doctest.DocFileSuite('../../../doc/api.txt')])
2321 suite.addTests(
2322 [doctest.DocFileSuite('../../../doc/parsing.txt')])
2323 suite.addTests(
2324 [doctest.DocFileSuite('../../../doc/resolvers.txt')])
2325 return suite
2326
2327 if __name__ == '__main__':
2328 print 'to test use test.py %s' % __file__
2329