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
170
178
180
181 Element = self.etree.Element
182 SubElement = self.etree.SubElement
183 ProcessingInstruction = self.etree.ProcessingInstruction
184
185 a = Element('a')
186 a.append(ProcessingInstruction('foo', 'some more text'))
187 self.assertEquals(a[0].target, 'foo')
188 self.assertEquals(a[0].text, 'some more text')
189
191 XML = self.etree.XML
192 root = XML("<test><?mypi my test ?></test>")
193 self.assertEquals(root[0].target, "mypi")
194 self.assertEquals(root[0].text, "my test ")
195
197
198 ProcessingInstruction = self.etree.ProcessingInstruction
199
200 a = ProcessingInstruction("PI", "ONE")
201 b = copy.deepcopy(a)
202 b.text = "ANOTHER"
203
204 self.assertEquals('ONE', a.text)
205 self.assertEquals('ANOTHER', b.text)
206
216
228
247
252
254 parse = self.etree.parse
255
256 f = StringIO('<a><b></c></b></a>')
257 self.etree.clear_error_log()
258 try:
259 parse(f)
260 logs = None
261 except SyntaxError, e:
262 logs = e.error_log
263 f.close()
264 self.assert_([ log for log in logs
265 if 'mismatch' in log.message ])
266 self.assert_([ log for log in logs
267 if 'PARSER' in log.domain_name])
268 self.assert_([ log for log in logs
269 if 'TAG_NAME_MISMATCH' in log.type_name ])
270 self.assert_([ log for log in logs
271 if 1 == log.line ])
272 self.assert_([ log for log in logs
273 if 15 == log.column ])
274
287
298
299 f = StringIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
300 events = list(iterparse(f, events=('end', 'comment')))
301 root = events[-1][1]
302 self.assertEquals(6, len(events))
303 self.assertEquals(['A', ' B ', 'c', 'b', 'C', 'a'],
304 [ name(*item) for item in events ])
305 self.assertEquals(
306 '<a><!--A--><b><!-- B --><c/></b><!--C--></a>',
307 tostring(root))
308
320
321 f = StringIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
322 events = list(iterparse(f, events=('end', 'pi')))
323 root = events[-2][1]
324 self.assertEquals(8, len(events))
325 self.assertEquals([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
326 ('pid','d'), 'a', ('pie','e')],
327 [ name(*item) for item in events ])
328 self.assertEquals(
329 '<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>',
330 tostring(ElementTree(root)))
331
346
352
354 iterparse = self.etree.iterparse
355 f = StringIO("""
356 <a> \n \n <b> b test </b> \n
357
358 \n\t <c> \n </c> </a> \n """)
359 iterator = iterparse(f, remove_blank_text=True)
360 text = [ (element.text, element.tail)
361 for event, element in iterator ]
362 self.assertEquals(
363 [(" b test ", None), (" \n ", None), (None, None)],
364 text)
365
367 iterparse = self.etree.iterparse
368 f = StringIO('<a><b><d/></b><c/></a>')
369
370 iterator = iterparse(f, tag="b", events=('start', 'end'))
371 events = list(iterator)
372 root = iterator.root
373 self.assertEquals(
374 [('start', root[0]), ('end', root[0])],
375 events)
376
378 iterparse = self.etree.iterparse
379 f = StringIO('<a><b><d/></b><c/></a>')
380
381 iterator = iterparse(f, tag="*", events=('start', 'end'))
382 events = list(iterator)
383 self.assertEquals(
384 8,
385 len(events))
386
388 text = u'Søk på nettet'
389 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
390 xml_latin1 = (u'%s<a>%s</a>' % (wrong_declaration, text)
391 ).encode('iso-8859-1')
392
393 self.assertRaises(self.etree.ParseError,
394 list, self.etree.iterparse(StringIO(xml_latin1)))
395
396 iterator = self.etree.iterparse(StringIO(xml_latin1),
397 encoding="iso-8859-1")
398 self.assertEquals(1, len(list(iterator)))
399
400 a = iterator.root
401 self.assertEquals(a.text, text)
402
406
412 def end(self, tag):
413 events.append("end-" + tag)
414 def data(self, data):
415 events.append("data-" + data)
416 def comment(self, text):
417 events.append("comment-" + text)
418 def close(self):
419 return "DONE"
420
421 parser = self.etree.XMLParser(target=Target())
422
423 parser.feed('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')
424 done = parser.close()
425
426 self.assertEquals("DONE", done)
427 self.assertEquals(["comment-a", "start-root", "data-A", "comment-b",
428 "start-sub", "end-sub", "comment-c", "data-B",
429 "end-root", "comment-d"],
430 events)
431
433 events = []
434 class Target(object):
435 def start(self, tag, attrib):
436 events.append("start-" + tag)
437 def end(self, tag):
438 events.append("end-" + tag)
439 def data(self, data):
440 events.append("data-" + data)
441 def pi(self, target, data):
442 events.append("pi-" + target + "-" + data)
443 def close(self):
444 return "DONE"
445
446 parser = self.etree.XMLParser(target=Target())
447
448 parser.feed('<?test a?><root>A<?test b?>B</root><?test c?>')
449 done = parser.close()
450
451 self.assertEquals("DONE", done)
452 self.assertEquals(["pi-test-a", "start-root", "data-A", "pi-test-b",
453 "data-B", "end-root", "pi-test-c"],
454 events)
455
465
475
484
494
496 iterwalk = self.etree.iterwalk
497 root = self.etree.XML('<a><b></b><c/></a>')
498
499 iterator = iterwalk(root, events=('start','end'))
500 events = list(iterator)
501 self.assertEquals(
502 [('start', root), ('start', root[0]), ('end', root[0]),
503 ('start', root[1]), ('end', root[1]), ('end', root)],
504 events)
505
516
518 iterwalk = self.etree.iterwalk
519 root = self.etree.XML('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')
520
521 attr_name = '{testns}bla'
522 events = []
523 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
524 for event, elem in iterator:
525 events.append(event)
526 if event == 'start':
527 if elem.tag != '{ns1}a':
528 elem.set(attr_name, 'value')
529
530 self.assertEquals(
531 ['start-ns', 'start', 'start', 'start-ns', 'start',
532 'end', 'end-ns', 'end', 'end', 'end-ns'],
533 events)
534
535 self.assertEquals(
536 None,
537 root.get(attr_name))
538 self.assertEquals(
539 'value',
540 root[0].get(attr_name))
541
543 iterwalk = self.etree.iterwalk
544 root = self.etree.XML('<a><b><d/></b><c/></a>')
545
546 counts = []
547 for event, elem in iterwalk(root):
548 counts.append(len(list(elem.getiterator())))
549 self.assertEquals(
550 [1,2,1,4],
551 counts)
552
554 parse = self.etree.parse
555 parser = self.etree.XMLParser(dtd_validation=True)
556 assertEqual = self.assertEqual
557 test_url = u"__nosuch.dtd"
558
559 class MyResolver(self.etree.Resolver):
560 def resolve(self, url, id, context):
561 assertEqual(url, test_url)
562 return self.resolve_string(
563 u'''<!ENTITY myentity "%s">
564 <!ELEMENT doc ANY>''' % url, context)
565
566 parser.resolvers.add(MyResolver())
567
568 xml = u'<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>' % test_url
569 tree = parse(StringIO(xml), parser)
570 root = tree.getroot()
571 self.assertEquals(root.text, test_url)
572
574 parse = self.etree.parse
575 parser = self.etree.XMLParser(load_dtd=True)
576 assertEqual = self.assertEqual
577 test_url = u"__nosuch.dtd"
578
579 class check(object):
580 resolved = False
581
582 class MyResolver(self.etree.Resolver):
583 def resolve(self, url, id, context):
584 assertEqual(url, test_url)
585 check.resolved = True
586 return self.resolve_empty(context)
587
588 parser.resolvers.add(MyResolver())
589
590 xml = u'<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>' % test_url
591 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
592 self.assert_(check.resolved)
593
601
602 class MyResolver(self.etree.Resolver):
603 def resolve(self, url, id, context):
604 raise _LocalException
605
606 parser.resolvers.add(MyResolver())
607
608 xml = u'<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
609 self.assertRaises(_LocalException, parse, StringIO(xml), parser)
610
611 if etree.LIBXML_VERSION > (2,6,20):
628
644
651
653 Entity = self.etree.Entity
654 self.assertRaises(ValueError, Entity, 'a b c')
655 self.assertRaises(ValueError, Entity, 'a,b')
656 self.assertRaises(AssertionError, Entity, 'a\0b')
657 self.assertRaises(ValueError, Entity, '#abc')
658 self.assertRaises(ValueError, Entity, '#xxyz')
659
660
670
675
688
701
707
713
728
730 Element = self.etree.Element
731 PI = self.etree.PI
732 root = Element('root')
733 pi = PI('TARGET', 'TEXT')
734 pi.tail = "TAIL"
735
736 self.assertEquals('<root></root>',
737 self._writeElement(root))
738 root.addprevious(pi)
739 self.assertEquals('<?TARGET TEXT?>\n<root></root>',
740 self._writeElement(root))
741
756
769
784
797
812
825
826
828 XML = self.etree.XML
829
830 root = XML('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')
831 values = root.values()
832 values.sort()
833 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
834
835
845
846
861
862
872
873
884
885
887 self.assertRaises(TypeError, self.etree.dump, None)
888
890 ElementTree = self.etree.ElementTree
891
892 f = StringIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
893 doc = ElementTree(file=f)
894 a = doc.getroot()
895 self.assertEquals(
896 None,
897 a.prefix)
898 self.assertEquals(
899 'foo',
900 a[0].prefix)
901
903 ElementTree = self.etree.ElementTree
904
905 f = StringIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
906 doc = ElementTree(file=f)
907 a = doc.getroot()
908 self.assertEquals(
909 None,
910 a.prefix)
911 self.assertEquals(
912 None,
913 a[0].prefix)
914
935
937 XML = self.etree.XML
938
939 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>')
940 result = []
941 for el in root.iterchildren():
942 result.append(el.tag)
943 self.assertEquals(['one', 'two', 'three'], result)
944
946 XML = self.etree.XML
947
948 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>')
949 result = []
950 for el in root.iterchildren(reversed=True):
951 result.append(el.tag)
952 self.assertEquals(['three', 'two', 'one'], result)
953
955 XML = self.etree.XML
956
957 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')
958 result = []
959 for el in root.iterchildren(tag='two'):
960 result.append(el.text)
961 self.assertEquals(['Two', 'Bla'], result)
962
964 XML = self.etree.XML
965
966 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')
967 result = []
968 for el in root.iterchildren(reversed=True, tag='two'):
969 result.append(el.text)
970 self.assertEquals(['Bla', 'Two'], result)
971
992
1004
1021
1042
1060
1077
1095
1097 Element = self.etree.Element
1098 SubElement = self.etree.SubElement
1099
1100 a = Element('a')
1101 b = SubElement(a, 'b')
1102 c = SubElement(a, 'c')
1103 d = SubElement(b, 'd')
1104 self.assertEquals(
1105 [],
1106 list(a.itersiblings()))
1107 self.assertEquals(
1108 [c],
1109 list(b.itersiblings()))
1110 self.assertEquals(
1111 c,
1112 b.itersiblings().next())
1113 self.assertEquals(
1114 [],
1115 list(c.itersiblings()))
1116 self.assertEquals(
1117 [b],
1118 list(c.itersiblings(preceding=True)))
1119 self.assertEquals(
1120 [],
1121 list(b.itersiblings(preceding=True)))
1122
1124 Element = self.etree.Element
1125 SubElement = self.etree.SubElement
1126
1127 a = Element('a')
1128 b = SubElement(a, 'b')
1129 c = SubElement(a, 'c')
1130 d = SubElement(b, 'd')
1131 self.assertEquals(
1132 [],
1133 list(a.itersiblings(tag='XXX')))
1134 self.assertEquals(
1135 [c],
1136 list(b.itersiblings(tag='c')))
1137 self.assertEquals(
1138 [b],
1139 list(c.itersiblings(preceding=True, tag='b')))
1140 self.assertEquals(
1141 [],
1142 list(c.itersiblings(preceding=True, tag='c')))
1143
1145 parseid = self.etree.parseid
1146 XML = self.etree.XML
1147 xml_text = '''
1148 <!DOCTYPE document [
1149 <!ELEMENT document (h1,p)*>
1150 <!ELEMENT h1 (#PCDATA)>
1151 <!ATTLIST h1 myid ID #REQUIRED>
1152 <!ELEMENT p (#PCDATA)>
1153 <!ATTLIST p someid ID #REQUIRED>
1154 ]>
1155 <document>
1156 <h1 myid="chapter1">...</h1>
1157 <p id="note1" class="note">...</p>
1158 <p>Regular paragraph.</p>
1159 <p xml:id="xmlid">XML:ID paragraph.</p>
1160 <p someid="warn1" class="warning">...</p>
1161 </document>
1162 '''
1163
1164 tree, dic = parseid(StringIO(xml_text))
1165 root = tree.getroot()
1166 root2 = XML(xml_text)
1167 self.assertEquals(self._writeElement(root),
1168 self._writeElement(root2))
1169 expected = {
1170 "chapter1" : root[0],
1171 "xmlid" : root[3],
1172 "warn1" : root[4]
1173 }
1174 self.assert_("chapter1" in dic)
1175 self.assert_("warn1" in dic)
1176 self.assert_("xmlid" in dic)
1177 self._checkIDDict(dic, expected)
1178
1180 XMLDTDID = self.etree.XMLDTDID
1181 XML = self.etree.XML
1182 xml_text = '''
1183 <!DOCTYPE document [
1184 <!ELEMENT document (h1,p)*>
1185 <!ELEMENT h1 (#PCDATA)>
1186 <!ATTLIST h1 myid ID #REQUIRED>
1187 <!ELEMENT p (#PCDATA)>
1188 <!ATTLIST p someid ID #REQUIRED>
1189 ]>
1190 <document>
1191 <h1 myid="chapter1">...</h1>
1192 <p id="note1" class="note">...</p>
1193 <p>Regular paragraph.</p>
1194 <p xml:id="xmlid">XML:ID paragraph.</p>
1195 <p someid="warn1" class="warning">...</p>
1196 </document>
1197 '''
1198
1199 root, dic = XMLDTDID(xml_text)
1200 root2 = XML(xml_text)
1201 self.assertEquals(self._writeElement(root),
1202 self._writeElement(root2))
1203 expected = {
1204 "chapter1" : root[0],
1205 "xmlid" : root[3],
1206 "warn1" : root[4]
1207 }
1208 self.assert_("chapter1" in dic)
1209 self.assert_("warn1" in dic)
1210 self.assert_("xmlid" in dic)
1211 self._checkIDDict(dic, expected)
1212
1214 XMLDTDID = self.etree.XMLDTDID
1215 XML = self.etree.XML
1216 xml_text = '''
1217 <document>
1218 <h1 myid="chapter1">...</h1>
1219 <p id="note1" class="note">...</p>
1220 <p>Regular paragraph.</p>
1221 <p someid="warn1" class="warning">...</p>
1222 </document>
1223 '''
1224
1225 root, dic = XMLDTDID(xml_text)
1226 root2 = XML(xml_text)
1227 self.assertEquals(self._writeElement(root),
1228 self._writeElement(root2))
1229 expected = {}
1230 self._checkIDDict(dic, expected)
1231
1233 self.assertEquals(dic, expected)
1234 self.assertEquals(len(dic),
1235 len(expected))
1236 self.assertEquals(sorted(dic.items()),
1237 sorted(expected.items()))
1238 self.assertEquals(sorted(dic.iteritems()),
1239 sorted(expected.iteritems()))
1240 self.assertEquals(sorted(dic.keys()),
1241 sorted(expected.keys()))
1242 self.assertEquals(sorted(dic.iterkeys()),
1243 sorted(expected.iterkeys()))
1244 self.assertEquals(sorted(dic.values()),
1245 sorted(expected.values()))
1246 self.assertEquals(sorted(dic.itervalues()),
1247 sorted(expected.itervalues()))
1248
1250 etree = self.etree
1251
1252 r = {'foo': 'http://ns.infrae.com/foo'}
1253 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1254 self.assertEquals(
1255 'foo',
1256 e.prefix)
1257 self.assertEquals(
1258 '<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>',
1259 self._writeElement(e))
1260
1262 etree = self.etree
1263
1264 r = {None: 'http://ns.infrae.com/foo'}
1265 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1266 self.assertEquals(
1267 None,
1268 e.prefix)
1269 self.assertEquals(
1270 '{http://ns.infrae.com/foo}bar',
1271 e.tag)
1272 self.assertEquals(
1273 '<bar xmlns="http://ns.infrae.com/foo"></bar>',
1274 self._writeElement(e))
1275
1277 etree = self.etree
1278
1279 r = {None: 'http://ns.infrae.com/foo',
1280 'hoi': 'http://ns.infrae.com/hoi'}
1281 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1282 e.set('{http://ns.infrae.com/hoi}test', 'value')
1283 self.assertEquals(
1284 '<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>',
1285 self._writeElement(e))
1286
1288 etree = self.etree
1289 r = {None: 'http://ns.infrae.com/foo',
1290 'hoi': 'http://ns.infrae.com/hoi'}
1291 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
1292 tree = etree.ElementTree(element=e)
1293 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
1294 self.assertEquals(
1295 '<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>',
1296 self._writeElement(e))
1297
1299 etree = self.etree
1300
1301 r = {None: 'http://ns.infrae.com/foo'}
1302 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1303 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1304
1305 e1.append(e2)
1306
1307 self.assertEquals(
1308 None,
1309 e1.prefix)
1310 self.assertEquals(
1311 None,
1312 e1[0].prefix)
1313 self.assertEquals(
1314 '{http://ns.infrae.com/foo}bar',
1315 e1.tag)
1316 self.assertEquals(
1317 '{http://ns.infrae.com/foo}bar',
1318 e1[0].tag)
1319
1321 etree = self.etree
1322
1323 r = {None: 'http://ns.infrae.com/BAR'}
1324 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
1325 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1326
1327 e1.append(e2)
1328
1329 self.assertEquals(
1330 None,
1331 e1.prefix)
1332 self.assertNotEquals(
1333 None,
1334 e2.prefix)
1335 self.assertEquals(
1336 '{http://ns.infrae.com/BAR}bar',
1337 e1.tag)
1338 self.assertEquals(
1339 '{http://ns.infrae.com/foo}bar',
1340 e2.tag)
1341
1343 ns_href = "http://a.b.c"
1344 one = self.etree.fromstring(
1345 '<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)
1346 baz = one[0][0]
1347
1348 two = self.etree.fromstring(
1349 '<root xmlns:ns="%s"/>' % ns_href)
1350 two.append(baz)
1351 del one
1352
1353 self.assertEquals('{%s}baz' % ns_href, baz.tag)
1354 self.assertEquals(
1355 '<root xmlns:ns="%s"><ns:baz/></root>' % ns_href,
1356 self.etree.tostring(two))
1357
1359 etree = self.etree
1360
1361 r = {None: 'http://ns.infrae.com/foo',
1362 'hoi': 'http://ns.infrae.com/hoi'}
1363 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
1364 self.assertEquals(
1365 r,
1366 e.nsmap)
1367
1369 etree = self.etree
1370
1371 re = {None: 'http://ns.infrae.com/foo',
1372 'hoi': 'http://ns.infrae.com/hoi'}
1373 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
1374
1375 rs = {None: 'http://ns.infrae.com/honk',
1376 'top': 'http://ns.infrae.com/top'}
1377 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
1378
1379 r = re.copy()
1380 r.update(rs)
1381 self.assertEquals(
1382 re,
1383 e.nsmap)
1384 self.assertEquals(
1385 r,
1386 s.nsmap)
1387
1389 Element = self.etree.Element
1390 SubElement = self.etree.SubElement
1391
1392 a = Element('{a}a')
1393 b = SubElement(a, '{a}b')
1394 c = SubElement(a, '{a}c')
1395 d = SubElement(b, '{b}d')
1396 e = SubElement(c, '{a}e')
1397 f = SubElement(c, '{b}f')
1398
1399 self.assertEquals(
1400 [a],
1401 list(a.getiterator('{a}a')))
1402 self.assertEquals(
1403 [],
1404 list(a.getiterator('{b}a')))
1405 self.assertEquals(
1406 [],
1407 list(a.getiterator('a')))
1408 self.assertEquals(
1409 [f],
1410 list(c.getiterator('{b}*')))
1411 self.assertEquals(
1412 [d, f],
1413 list(a.getiterator('{b}*')))
1414
1439
1455
1472
1474 XML = self.etree.XML
1475 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
1476 self.assertEquals(len(root.findall(".//{X}b")), 2)
1477 self.assertEquals(len(root.findall(".//{X}*")), 2)
1478 self.assertEquals(len(root.findall(".//b")), 3)
1479
1481 etree = self.etree
1482 e = etree.Element('foo')
1483 for i in range(10):
1484 etree.SubElement(e, 'a%s' % i)
1485 for i in range(10):
1486 self.assertEquals(
1487 i,
1488 e.index(e[i]))
1489 self.assertEquals(
1490 3, e.index(e[3], 3))
1491 self.assertRaises(
1492 ValueError, e.index, e[3], 4)
1493 self.assertRaises(
1494 ValueError, e.index, e[3], 0, 2)
1495 self.assertRaises(
1496 ValueError, e.index, e[8], 0, -3)
1497 self.assertRaises(
1498 ValueError, e.index, e[8], -5, -3)
1499 self.assertEquals(
1500 8, e.index(e[8], 0, -1))
1501 self.assertEquals(
1502 8, e.index(e[8], -12, -1))
1503 self.assertEquals(
1504 0, e.index(e[0], -12, -1))
1505
1507 etree = self.etree
1508 e = etree.Element('foo')
1509 for i in range(10):
1510 el = etree.SubElement(e, 'a%s' % i)
1511 el.text = "text%d" % i
1512 el.tail = "tail%d" % i
1513
1514 child0 = e[0]
1515 child1 = e[1]
1516 child2 = e[2]
1517
1518 e.replace(e[0], e[1])
1519 self.assertEquals(
1520 9, len(e))
1521 self.assertEquals(
1522 child1, e[0])
1523 self.assertEquals(
1524 child1.text, "text1")
1525 self.assertEquals(
1526 child1.tail, "tail1")
1527 self.assertEquals(
1528 child0.tail, "tail0")
1529 self.assertEquals(
1530 child2, e[1])
1531
1532 e.replace(e[-1], e[0])
1533 self.assertEquals(
1534 child1, e[-1])
1535 self.assertEquals(
1536 child1.text, "text1")
1537 self.assertEquals(
1538 child1.tail, "tail1")
1539 self.assertEquals(
1540 child2, e[0])
1541
1543 etree = self.etree
1544 e = etree.Element('foo')
1545 for i in range(10):
1546 etree.SubElement(e, 'a%s' % i)
1547
1548 new_element = etree.Element("test")
1549 new_element.text = "TESTTEXT"
1550 new_element.tail = "TESTTAIL"
1551 child1 = e[1]
1552 e.replace(e[0], new_element)
1553 self.assertEquals(
1554 new_element, e[0])
1555 self.assertEquals(
1556 "TESTTEXT",
1557 e[0].text)
1558 self.assertEquals(
1559 "TESTTAIL",
1560 e[0].tail)
1561 self.assertEquals(
1562 child1, e[1])
1563
1579
1597
1615
1633
1635 Element = self.etree.Element
1636 SubElement = self.etree.SubElement
1637 try:
1638 slice
1639 except NameError:
1640 print "slice() not found"
1641 return
1642
1643 a = Element('a')
1644 b = SubElement(a, 'b')
1645 c = SubElement(a, 'c')
1646 d = SubElement(a, 'd')
1647 e = SubElement(a, 'e')
1648
1649 x = Element('x')
1650 y = Element('y')
1651 z = Element('z')
1652
1653 self.assertRaises(
1654 ValueError,
1655 operator.setitem, a, slice(1,None,2), [x, y, z])
1656
1657 self.assertEquals(
1658 [b, c, d, e],
1659 list(a))
1660
1662 XML = self.etree.XML
1663 root = XML('''<?xml version="1.0"?>
1664 <root><test>
1665
1666 <bla/></test>
1667 </root>
1668 ''')
1669
1670 self.assertEquals(
1671 [2, 2, 4],
1672 [ el.sourceline for el in root.getiterator() ])
1673
1675 parse = self.etree.parse
1676 tree = parse(fileInTestDir('include/test_xinclude.xml'))
1677
1678 self.assertEquals(
1679 [1, 2, 3],
1680 [ el.sourceline for el in tree.getiterator() ])
1681
1690
1692 iterparse = self.etree.iterparse
1693 lines = [ el.sourceline for (event, el) in
1694 iterparse(fileInTestDir('include/test_xinclude.xml'),
1695 events=("start",)) ]
1696
1697 self.assertEquals(
1698 [1, 2, 3],
1699 lines)
1700
1710
1712 etree = self.etree
1713 root = etree.XML("<root/>", base_url="http://no/such/url")
1714 docinfo = root.getroottree().docinfo
1715 self.assertEquals(docinfo.URL, "http://no/such/url")
1716
1718 etree = self.etree
1719 root = etree.XML("<root/>", base_url="http://no/such/url")
1720 docinfo = root.getroottree().docinfo
1721 self.assertEquals(docinfo.URL, "http://no/such/url")
1722 docinfo.URL = "https://secret/url"
1723 self.assertEquals(docinfo.URL, "https://secret/url")
1724
1726 etree = self.etree
1727 tree = etree.parse(StringIO("<root/>"), base_url="http://no/such/url")
1728 docinfo = tree.docinfo
1729 self.assertEquals(docinfo.URL, "http://no/such/url")
1730
1732 etree = self.etree
1733 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
1734 base_url="http://no/such/url")
1735 docinfo = tree.docinfo
1736 self.assertEquals(docinfo.URL, "http://no/such/url")
1737
1739 etree = self.etree
1740 root = etree.HTML("<html/>", base_url="http://no/such/url")
1741 docinfo = root.getroottree().docinfo
1742 self.assertEquals(docinfo.URL, "http://no/such/url")
1743
1745 etree = self.etree
1746 xml_header = '<?xml version="1.0" encoding="ascii"?>'
1747 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
1748 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
1749 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
1750
1751 xml = xml_header + doctype_string + '<html><body></body></html>'
1752
1753 tree = etree.parse(StringIO(xml))
1754 docinfo = tree.docinfo
1755 self.assertEquals(docinfo.encoding, "ascii")
1756 self.assertEquals(docinfo.xml_version, "1.0")
1757 self.assertEquals(docinfo.public_id, pub_id)
1758 self.assertEquals(docinfo.system_url, sys_id)
1759 self.assertEquals(docinfo.root_name, 'html')
1760 self.assertEquals(docinfo.doctype, doctype_string)
1761
1763 etree = self.etree
1764 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
1765 sys_id = "some.dtd"
1766 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
1767 xml = xml_header + doctype_string + '<html><body></body></html>'
1768
1769 tree = etree.parse(StringIO(xml))
1770 docinfo = tree.docinfo
1771 self.assertEquals(docinfo.encoding, "UTF-8")
1772 self.assertEquals(docinfo.xml_version, "1.0")
1773 self.assertEquals(docinfo.public_id, None)
1774 self.assertEquals(docinfo.system_url, sys_id)
1775 self.assertEquals(docinfo.root_name, 'html')
1776 self.assertEquals(docinfo.doctype, doctype_string)
1777
1779 etree = self.etree
1780 xml = '<html><body></body></html>'
1781 tree = etree.parse(StringIO(xml))
1782 docinfo = tree.docinfo
1783 self.assertEquals(docinfo.encoding, None)
1784 self.assertEquals(docinfo.xml_version, "1.0")
1785 self.assertEquals(docinfo.public_id, None)
1786 self.assertEquals(docinfo.system_url, None)
1787 self.assertEquals(docinfo.root_name, 'html')
1788 self.assertEquals(docinfo.doctype, '')
1789
1791 etree = self.etree
1792 root = etree.XML("<root/>", base_url="http://no/such/url")
1793 self.assertEquals(root.base, "http://no/such/url")
1794 self.assertEquals(
1795 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
1796 root.base = "https://secret/url"
1797 self.assertEquals(root.base, "https://secret/url")
1798 self.assertEquals(
1799 root.get('{http://www.w3.org/XML/1998/namespace}base'),
1800 "https://secret/url")
1801
1803 etree = self.etree
1804 root = etree.XML("<root/>", base_url="http://no/such/url")
1805 self.assertEquals(root.base, "http://no/such/url")
1806 self.assertEquals(
1807 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
1808 root.set('{http://www.w3.org/XML/1998/namespace}base',
1809 "https://secret/url")
1810 self.assertEquals(root.base, "https://secret/url")
1811 self.assertEquals(
1812 root.get('{http://www.w3.org/XML/1998/namespace}base'),
1813 "https://secret/url")
1814
1816 etree = self.etree
1817 root = etree.HTML("<html><body></body></html>",
1818 base_url="http://no/such/url")
1819 self.assertEquals(root.base, "http://no/such/url")
1820
1822 etree = self.etree
1823 root = etree.HTML('<html><head><base href="http://no/such/url"></head></html>')
1824 self.assertEquals(root.base, "http://no/such/url")
1825
1827
1828 xml = '''\
1829 <!DOCTYPE test SYSTEM "test.dtd" [
1830 <!ENTITY entity "tasty">
1831 <!ELEMENT test (a)>
1832 <!ELEMENT a (#PCDATA)>
1833 ]>
1834 <test><a>test-test</a></test>\
1835 '''
1836 tree = self.etree.parse(StringIO(xml))
1837 self.assertEqual(self.etree.tostring(tree).replace(" ", ""),
1838 xml.replace(" ", ""))
1839
1841 Element = self.etree.Element
1842
1843 a = Element('a')
1844 self.assertRaises(AssertionError, setattr, a, "text", 'ha\0ho')
1845 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\0ho')
1846
1847 self.assertRaises(AssertionError, Element, 'ha\0ho')
1848
1850 Element = self.etree.Element
1851
1852 a = Element('a')
1853 self.assertRaises(AssertionError, setattr, a, "text", u'ha\0ho')
1854 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\0ho')
1855
1856 self.assertRaises(AssertionError, Element, u'ha\0ho')
1857
1859 Element = self.etree.Element
1860
1861 a = Element('a')
1862 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x07ho')
1863 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x02ho')
1864
1865 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x07ho')
1866 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x02ho')
1867
1868 self.assertRaises(AssertionError, Element, 'ha\x07ho')
1869 self.assertRaises(AssertionError, Element, 'ha\x02ho')
1870
1872 Element = self.etree.Element
1873
1874 a = Element('a')
1875 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x07ho')
1876 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x02ho')
1877
1878 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x07ho')
1879 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x02ho')
1880
1881 self.assertRaises(AssertionError, Element, u'ha\x07ho')
1882 self.assertRaises(AssertionError, Element, u'ha\x02ho')
1883
1897
1902
1920
1940
1942 tostring = self.etree.tostring
1943 Element = self.etree.Element
1944 SubElement = self.etree.SubElement
1945
1946 a = Element('a')
1947 a.text = "A"
1948 a.tail = "tail"
1949 b = SubElement(a, 'b')
1950 b.text = "B"
1951 b.tail = u"Søk på nettet"
1952 c = SubElement(a, 'c')
1953 c.text = "C"
1954
1955 result = tostring(a, method="text", encoding="UTF-16")
1956
1957 self.assertEquals(u'ABSøk på nettetCtail'.encode("UTF-16"),
1958 result)
1959
1961 tostring = self.etree.tostring
1962 Element = self.etree.Element
1963 SubElement = self.etree.SubElement
1964
1965 a = Element('a')
1966 a.text = u'Søk på nettetA'
1967 a.tail = "tail"
1968 b = SubElement(a, 'b')
1969 b.text = "B"
1970 b.tail = u'Søk på nettetB'
1971 c = SubElement(a, 'c')
1972 c.text = "C"
1973
1974 self.assertRaises(UnicodeEncodeError,
1975 tostring, a, method="text")
1976
1977 self.assertEquals(
1978 u'Søk på nettetABSøk på nettetBCtail'.encode('utf-8'),
1979 tostring(a, encoding="UTF-8", method="text"))
1980
1993
2009
2013
2028
2046
2059
2061 tostring = self.etree.tostring
2062 Element = self.etree.Element
2063 SubElement = self.etree.SubElement
2064
2065 a = Element('a')
2066 b = SubElement(a, 'b')
2067 c = SubElement(a, 'c')
2068 d = SubElement(c, 'd')
2069 self.assert_(isinstance(tostring(b, encoding=unicode), unicode))
2070 self.assert_(isinstance(tostring(c, encoding=unicode), unicode))
2071 self.assertEquals('<b></b>',
2072 canonicalize(tostring(b, encoding=unicode)))
2073 self.assertEquals('<c><d></d></c>',
2074 canonicalize(tostring(c, encoding=unicode)))
2075
2080
2095
2097 tostring = self.etree.tostring
2098 Element = self.etree.Element
2099 SubElement = self.etree.SubElement
2100
2101 a = Element('a')
2102 b = SubElement(a, 'b')
2103 c = SubElement(a, 'c')
2104
2105 result = tostring(a, encoding=unicode)
2106 self.assertEquals(result, "<a><b/><c/></a>")
2107
2108 result = tostring(a, encoding=unicode, pretty_print=False)
2109 self.assertEquals(result, "<a><b/><c/></a>")
2110
2111 result = tostring(a, encoding=unicode, pretty_print=True)
2112 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2113
2114
2115
2125
2126
2129 filename = fileInTestDir('test_broken.xml')
2130 root = etree.XML('''\
2131 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
2132 <xi:include href="%s" parse="text"/>
2133 </doc>
2134 ''' % filename)
2135 old_text = root.text
2136 content = open(filename).read()
2137 old_tail = root[0].tail
2138
2139 self.include( etree.ElementTree(root) )
2140 self.assertEquals(old_text + content + old_tail,
2141 root.text)
2142
2144 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
2145 self.assertNotEquals(
2146 'a',
2147 tree.getroot()[1].tag)
2148
2149 self.include( tree )
2150
2151 self.assertEquals(
2152 'a',
2153 tree.getroot()[1].tag)
2154
2158
2159
2164
2165
2168 tree = self.parse('<a><b/></a>')
2169 f = StringIO()
2170 tree.write_c14n(f)
2171 s = f.getvalue()
2172 self.assertEquals('<a><b></b></a>',
2173 s)
2174
2176 suite = unittest.TestSuite()
2177 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
2178 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
2179 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
2180 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
2181 suite.addTests(
2182 [doctest.DocFileSuite('../../../doc/tutorial.txt')])
2183 suite.addTests(
2184 [doctest.DocFileSuite('../../../doc/api.txt')])
2185 suite.addTests(
2186 [doctest.DocFileSuite('../../../doc/parsing.txt')])
2187 suite.addTests(
2188 [doctest.DocFileSuite('../../../doc/resolvers.txt')])
2189 return suite
2190
2191 if __name__ == '__main__':
2192 print 'to test use test.py %s' % __file__
2193