Package lxml :: Package tests :: Module test_etree
[hide private]
[frames] | no frames]

Source Code for Module lxml.tests.test_etree

   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   
  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      # Python 2.3 
30 - def sorted(seq):
31 seq = list(seq) 32 seq.sort() 33 return seq
34
35 -class ETreeOnlyTestCase(HelperTestCase):
36 """Tests only for etree, not ElementTree""" 37 etree = etree 38
39 - def test_version(self):
40 self.assert_(isinstance(etree.__version__, str)) 41 self.assert_(isinstance(etree.LXML_VERSION, tuple)) 42 self.assertEqual(len(etree.LXML_VERSION), 4) 43 self.assert_(isinstance(etree.LXML_VERSION[0], int)) 44 self.assert_(isinstance(etree.LXML_VERSION[1], int)) 45 self.assert_(isinstance(etree.LXML_VERSION[2], int)) 46 self.assert_(isinstance(etree.LXML_VERSION[3], int)) 47 self.assert_(etree.__version__.startswith( 48 str(etree.LXML_VERSION[0])))
49
50 - def test_c_api(self):
51 if hasattr(self.etree, '__pyx_capi__'): 52 # newer Pyrex compatible C-API 53 self.assert_(isinstance(self.etree.__pyx_capi__, dict)) 54 self.assert_(len(self.etree.__pyx_capi__) > 0) 55 else: 56 # older C-API mechanism 57 self.assert_(hasattr(self.etree, '_import_c_api'))
58
59 - def test_element_names(self):
60 Element = self.etree.Element 61 el = Element('name') 62 self.assertEquals(el.tag, 'name') 63 el = Element('{}name') 64 self.assertEquals(el.tag, 'name')
65
66 - def test_element_name_empty(self):
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
75 - def test_element_name_colon(self):
76 Element = self.etree.Element 77 self.assertRaises(ValueError, Element, 'p:name') 78 self.assertRaises(ValueError, Element, '{test}p:name') 79 80 el = Element('name') 81 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
82
83 - def test_element_name_quote(self):
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
95 - def test_element_name_space(self):
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
104 - def test_subelement_name_empty(self):
105 Element = self.etree.Element 106 SubElement = self.etree.SubElement 107 108 el = Element('name') 109 self.assertRaises(ValueError, SubElement, el, '{}') 110 self.assertRaises(ValueError, SubElement, el, '{test}')
111
112 - def test_subelement_name_colon(self):
113 Element = self.etree.Element 114 SubElement = self.etree.SubElement 115 116 el = Element('name') 117 self.assertRaises(ValueError, SubElement, el, 'p:name') 118 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
119
120 - def test_subelement_name_quote(self):
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
131 - def test_subelement_name_space(self):
132 Element = self.etree.Element 133 SubElement = self.etree.SubElement 134 135 el = Element('name') 136 self.assertRaises(ValueError, SubElement, el, ' name ') 137 self.assertRaises(ValueError, SubElement, el, 'na me') 138 self.assertRaises(ValueError, SubElement, el, '{test} name')
139
140 - def test_qname_empty(self):
141 QName = self.etree.QName 142 self.assertRaises(ValueError, QName, '') 143 self.assertRaises(ValueError, QName, 'test', '')
144
145 - def test_qname_colon(self):
146 QName = self.etree.QName 147 self.assertRaises(ValueError, QName, 'p:name') 148 self.assertRaises(ValueError, QName, 'test', 'p:name')
149
150 - def test_qname_space(self):
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
156 - def test_qname_text_resolve(self):
157 # ET doesn't resove QNames as text values 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
165 - def test_attribute_set(self):
166 Element = self.etree.Element 167 root = Element("root") 168 root.set("attr", "TEST") 169 self.assertEquals("TEST", root.get("attr"))
170
171 - def test_attribute_set_invalid(self):
172 # ElementTree accepts arbitrary attribute values 173 # lxml.etree allows only strings 174 Element = self.etree.Element 175 root = Element("root") 176 self.assertRaises(TypeError, root.set, "newattr", 5) 177 self.assertRaises(TypeError, root.set, "newattr", None)
178
179 - def test_attrib_pop(self):
180 ElementTree = self.etree.ElementTree 181 182 f = StringIO('<doc one="One" two="Two"/>') 183 doc = ElementTree(file=f) 184 root = doc.getroot() 185 self.assertEquals('One', root.attrib['one']) 186 self.assertEquals('Two', root.attrib['two']) 187 188 self.assertEquals('One', root.attrib.pop('one')) 189 190 self.assertEquals(None, root.attrib.get('one')) 191 self.assertEquals('Two', root.attrib['two'])
192
193 - def test_attrib_pop_unknown(self):
194 root = self.etree.XML('<doc one="One" two="Two"/>') 195 self.assertRaises(KeyError, root.attrib.pop, 'NONE') 196 197 self.assertEquals('One', root.attrib['one']) 198 self.assertEquals('Two', root.attrib['two'])
199
200 - def test_attrib_pop_default(self):
201 root = self.etree.XML('<doc one="One" two="Two"/>') 202 self.assertEquals('Three', root.attrib.pop('three', 'Three'))
203
205 root = self.etree.XML('<doc/>') 206 self.assertEquals('Three', root.attrib.pop('three', 'Three'))
207
209 root = self.etree.XML('<doc one="One" two="Two"/>') 210 self.assertRaises(TypeError, root.attrib.pop, 'One', None, None)
211
212 - def test_pi(self):
213 # lxml.etree separates target and text 214 Element = self.etree.Element 215 SubElement = self.etree.SubElement 216 ProcessingInstruction = self.etree.ProcessingInstruction 217 218 a = Element('a') 219 a.append(ProcessingInstruction('foo', 'some more text')) 220 self.assertEquals(a[0].target, 'foo') 221 self.assertEquals(a[0].text, 'some more text')
222
223 - def test_pi_parse(self):
224 XML = self.etree.XML 225 root = XML("<test><?mypi my test ?></test>") 226 self.assertEquals(root[0].target, "mypi") 227 self.assertEquals(root[0].text, "my test ")
228
229 - def test_deepcopy_pi(self):
230 # previously caused a crash 231 ProcessingInstruction = self.etree.ProcessingInstruction 232 233 a = ProcessingInstruction("PI", "ONE") 234 b = copy.deepcopy(a) 235 b.text = "ANOTHER" 236 237 self.assertEquals('ONE', a.text) 238 self.assertEquals('ANOTHER', b.text)
239
240 - def test_deepcopy_comment(self):
241 # previously caused a crash 242 # not supported by ET! 243 Comment = self.etree.Comment 244 245 a = Comment("ONE") 246 b = copy.deepcopy(a) 247 b.text = "ANOTHER" 248 249 self.assertEquals('ONE', a.text) 250 self.assertEquals('ANOTHER', b.text)
251
252 - def test_attribute_set(self):
253 # ElementTree accepts arbitrary attribute values 254 # lxml.etree allows only strings 255 Element = self.etree.Element 256 257 root = Element("root") 258 root.set("attr", "TEST") 259 self.assertEquals("TEST", root.get("attr")) 260 self.assertRaises(TypeError, root.set, "newattr", 5)
261
262 - def test_parse_error(self):
263 # ET raises ExpatError 264 parse = self.etree.parse 265 # from StringIO 266 f = StringIO('<a><b></c></b></a>') 267 self.assertRaises(SyntaxError, parse, f) 268 f.close()
269
270 - def test_parse_remove_comments(self):
271 fromstring = self.etree.fromstring 272 tostring = self.etree.tostring 273 XMLParser = self.etree.XMLParser 274 275 xml = '<a><!--A--><b><!-- B --><c/></b><!--C--></a>' 276 parser = XMLParser(remove_comments=True) 277 root = fromstring(xml, parser) 278 self.assertEquals( 279 '<a><b><c/></b></a>', 280 tostring(root))
281
282 - def test_parse_remove_pis(self):
283 parse = self.etree.parse 284 tostring = self.etree.tostring 285 XMLParser = self.etree.XMLParser 286 287 xml = '<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>' 288 289 f = StringIO(xml) 290 tree = parse(f) 291 self.assertEquals( 292 xml, 293 tostring(tree)) 294 295 parser = XMLParser(remove_pis=True) 296 tree = parse(f, parser) 297 self.assertEquals( 298 '<a><b><c/></b></a>', 299 tostring(tree))
300
302 # ET raises IOError only 303 parse = self.etree.parse 304 self.assertRaises(TypeError, parse, 'notthere.xml', object())
305
306 - def test_parse_error_logging(self):
307 parse = self.etree.parse 308 # from StringIO 309 f = StringIO('<a><b></c></b></a>') 310 self.etree.clearErrorLog() 311 try: 312 parse(f) 313 logs = None 314 except SyntaxError, e: 315 logs = e.error_log 316 f.close() 317 self.assert_([ log for log in logs 318 if 'mismatch' in log.message ]) 319 self.assert_([ log for log in logs 320 if 'PARSER' in log.domain_name]) 321 self.assert_([ log for log in logs 322 if 'TAG_NAME_MISMATCH' in log.type_name ]) 323 self.assert_([ log for log in logs 324 if 1 == log.line ]) 325 self.assert_([ log for log in logs 326 if 15 == log.column ])
327
328 - def test_parse_error_from_file(self):
329 parse = self.etree.parse 330 # from file 331 f = open(fileInTestDir('test_broken.xml'), 'r') 332 self.assertRaises(SyntaxError, parse, f) 333 f.close()
334
335 - def test_iterparse_comments(self):
336 # ET removes comments 337 iterparse = self.etree.iterparse 338 tostring = self.etree.tostring 339 340 f = StringIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 341 events = list(iterparse(f)) 342 root = events[-1][1] 343 self.assertEquals(3, len(events)) 344 self.assertEquals( 345 '<a><!--A--><b><!-- B --><c/></b><!--C--></a>', 346 tostring(root))
347
349 iterparse = self.etree.iterparse 350 tostring = self.etree.tostring 351 352 f = StringIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 353 events = list(iterparse(f, remove_comments=True)) 354 root = events[-1][1] 355 self.assertEquals( 356 '<a><b><c/></b></a>', 357 tostring(root))
358
359 - def test_iterparse_broken(self):
360 iterparse = self.etree.iterparse 361 f = StringIO('<a><b><c/></a>') 362 # ET raises ExpatError, lxml raises XMLSyntaxError 363 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
364
365 - def test_iterparse_strip(self):
366 iterparse = self.etree.iterparse 367 f = StringIO(""" 368 <a> \n \n <b> b test </b> \n 369 370 \n\t <c> \n </c> </a> \n """) 371 iterator = iterparse(f, remove_blank_text=True) 372 text = [ (element.text, element.tail) 373 for event, element in iterator ] 374 self.assertEquals( 375 [(" b test ", None), (" \n ", None), (None, None)], 376 text)
377
378 - def test_iterparse_tag(self):
379 iterparse = self.etree.iterparse 380 f = StringIO('<a><b><d/></b><c/></a>') 381 382 iterator = iterparse(f, tag="b", events=('start', 'end')) 383 events = list(iterator) 384 root = iterator.root 385 self.assertEquals( 386 [('start', root[0]), ('end', root[0])], 387 events)
388
389 - def test_iterparse_tag_all(self):
390 iterparse = self.etree.iterparse 391 f = StringIO('<a><b><d/></b><c/></a>') 392 393 iterator = iterparse(f, tag="*", events=('start', 'end')) 394 events = list(iterator) 395 self.assertEquals( 396 8, 397 len(events))
398
400 text = u'Søk på nettet' 401 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 402 xml_latin1 = (u'%s<a>%s</a>' % (wrong_declaration, text) 403 ).encode('iso-8859-1') 404 405 self.assertRaises(self.etree.ParseError, 406 list, self.etree.iterparse(StringIO(xml_latin1))) 407 408 iterator = self.etree.iterparse(StringIO(xml_latin1), 409 encoding="iso-8859-1") 410 self.assertEquals(1, len(list(iterator))) 411 412 a = iterator.root 413 self.assertEquals(a.text, text)
414
416 self.assertRaises( 417 LookupError, self.etree.XMLParser, encoding="hopefully unknown")
418
419 - def test_iterwalk_tag(self):
420 iterwalk = self.etree.iterwalk 421 root = self.etree.XML('<a><b><d/></b><c/></a>') 422 423 iterator = iterwalk(root, tag="b", events=('start', 'end')) 424 events = list(iterator) 425 self.assertEquals( 426 [('start', root[0]), ('end', root[0])], 427 events)
428
429 - def test_iterwalk_tag_all(self):
430 iterwalk = self.etree.iterwalk 431 root = self.etree.XML('<a><b><d/></b><c/></a>') 432 433 iterator = iterwalk(root, tag="*", events=('start', 'end')) 434 events = list(iterator) 435 self.assertEquals( 436 8, 437 len(events))
438
439 - def test_iterwalk(self):
440 iterwalk = self.etree.iterwalk 441 root = self.etree.XML('<a><b></b><c/></a>') 442 443 events = list(iterwalk(root)) 444 self.assertEquals( 445 [('end', root[0]), ('end', root[1]), ('end', root)], 446 events)
447
448 - def test_iterwalk_start(self):
449 iterwalk = self.etree.iterwalk 450 root = self.etree.XML('<a><b></b><c/></a>') 451 452 iterator = iterwalk(root, events=('start',)) 453 events = list(iterator) 454 self.assertEquals( 455 [('start', root), ('start', root[0]), ('start', root[1])], 456 events)
457
458 - def test_iterwalk_start_end(self):
459 iterwalk = self.etree.iterwalk 460 root = self.etree.XML('<a><b></b><c/></a>') 461 462 iterator = iterwalk(root, events=('start','end')) 463 events = list(iterator) 464 self.assertEquals( 465 [('start', root), ('start', root[0]), ('end', root[0]), 466 ('start', root[1]), ('end', root[1]), ('end', root)], 467 events)
468
469 - def test_iterwalk_clear(self):
470 iterwalk = self.etree.iterwalk 471 root = self.etree.XML('<a><b></b><c/></a>') 472 473 iterator = iterwalk(root) 474 for event, elem in iterator: 475 elem.clear() 476 477 self.assertEquals(0, 478 len(root))
479
480 - def test_iterwalk_attrib_ns(self):
481 iterwalk = self.etree.iterwalk 482 root = self.etree.XML('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>') 483 484 attr_name = '{testns}bla' 485 events = [] 486 iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 487 for event, elem in iterator: 488 events.append(event) 489 if event == 'start': 490 if elem.tag != '{ns1}a': 491 elem.set(attr_name, 'value') 492 493 self.assertEquals( 494 ['start-ns', 'start', 'start', 'start-ns', 'start', 495 'end', 'end-ns', 'end', 'end', 'end-ns'], 496 events) 497 498 self.assertEquals( 499 None, 500 root.get(attr_name)) 501 self.assertEquals( 502 'value', 503 root[0].get(attr_name))
504
505 - def test_iterwalk_getiterator(self):
506 iterwalk = self.etree.iterwalk 507 root = self.etree.XML('<a><b><d/></b><c/></a>') 508 509 counts = [] 510 for event, elem in iterwalk(root): 511 counts.append(len(list(elem.getiterator()))) 512 self.assertEquals( 513 [1,2,1,4], 514 counts)
515
516 - def test_resolve_string_dtd(self):
517 parse = self.etree.parse 518 parser = self.etree.XMLParser(dtd_validation=True) 519 assertEqual = self.assertEqual 520 test_url = u"__nosuch.dtd" 521 522 class MyResolver(self.etree.Resolver): 523 def resolve(self, url, id, context): 524 assertEqual(url, test_url) 525 return self.resolve_string( 526 u'''<!ENTITY myentity "%s"> 527 <!ELEMENT doc ANY>''' % url, context)
528 529 parser.resolvers.add(MyResolver()) 530 531 xml = u'<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>' % test_url 532 tree = parse(StringIO(xml), parser) 533 root = tree.getroot() 534 self.assertEquals(root.text, test_url) 535
536 - def test_resolve_empty(self):
537 parse = self.etree.parse 538 parser = self.etree.XMLParser(load_dtd=True) 539 assertEqual = self.assertEqual 540 test_url = u"__nosuch.dtd" 541 542 class check(object): 543 resolved = False
544 545 class MyResolver(self.etree.Resolver): 546 def resolve(self, url, id, context): 547 assertEqual(url, test_url) 548 check.resolved = True 549 return self.resolve_empty(context) 550 551 parser.resolvers.add(MyResolver()) 552 553 xml = u'<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>' % test_url 554 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 555 self.assert_(check.resolved) 556
557 - def test_resolve_error(self):
558 parse = self.etree.parse 559 parser = self.etree.XMLParser(dtd_validation=True) 560 test_url = u"__nosuch.dtd" 561 562 class _LocalException(Exception): 563 pass
564 565 class MyResolver(self.etree.Resolver): 566 def resolve(self, url, id, context): 567 raise _LocalException 568 569 parser.resolvers.add(MyResolver()) 570 571 xml = u'<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 572 self.assertRaises(_LocalException, parse, StringIO(xml), parser) 573 574 if etree.LIBXML_VERSION > (2,6,20):
575 - def test_entity_parse(self):
576 parse = self.etree.parse 577 tostring = self.etree.tostring 578 parser = self.etree.XMLParser(resolve_entities=False) 579 Entity = self.etree.Entity 580 581 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 582 tree = parse(StringIO(xml), parser) 583 root = tree.getroot() 584 self.assertEquals(root[0].tag, Entity) 585 self.assertEquals(root[0].text, "&myentity;") 586 self.assertEquals(root[0].tail, None) 587 self.assertEquals(root[0].name, "myentity") 588 589 self.assertEquals('<doc>&myentity;</doc>', 590 tostring(root))
591
592 - def test_entity_append(self):
593 Entity = self.etree.Entity 594 Element = self.etree.Element 595 tostring = self.etree.tostring 596 597 root = Element("root") 598 root.append( Entity("test") ) 599 600 self.assertEquals(root[0].tag, Entity) 601 self.assertEquals(root[0].text, "&test;") 602 self.assertEquals(root[0].tail, None) 603 self.assertEquals(root[0].name, "test") 604 605 self.assertEquals('<root>&test;</root>', 606 tostring(root))
607
608 - def test_entity_values(self):
609 Entity = self.etree.Entity 610 self.assertEquals(Entity("test").text, '&test;') 611 self.assertEquals(Entity("#17683").text, '&#17683;') 612 self.assertEquals(Entity("#x1768").text, '&#x1768;') 613 self.assertEquals(Entity("#x98AF").text, '&#x98AF;')
614
615 - def test_entity_error(self):
616 Entity = self.etree.Entity 617 self.assertRaises(ValueError, Entity, 'a b c') 618 self.assertRaises(ValueError, Entity, 'a,b') 619 self.assertRaises(AssertionError, Entity, 'a\0b') 620 self.assertRaises(ValueError, Entity, '#abc') 621 self.assertRaises(ValueError, Entity, '#xxyz')
622 623 # TypeError in etree, AssertionError in ElementTree;
624 - def test_setitem_assert(self):
625 Element = self.etree.Element 626 SubElement = self.etree.SubElement 627 628 a = Element('a') 629 b = SubElement(a, 'b') 630 631 self.assertRaises(TypeError, 632 a.__setitem__, 0, 'foo')
633
634 - def test_append_None(self):
635 # raises AssertionError in ElementTree 636 Element = self.etree.Element 637 self.assertRaises(TypeError, Element('a').append, None)
638
639 - def test_addnext(self):
640 Element = self.etree.Element 641 SubElement = self.etree.SubElement 642 root = Element('root') 643 SubElement(root, 'a') 644 SubElement(root, 'b') 645 646 self.assertEquals(['a', 'b'], 647 [c.tag for c in root]) 648 root[1].addnext(root[0]) 649 self.assertEquals(['b', 'a'], 650 [c.tag for c in root])
651
652 - def test_addprevious(self):
653 Element = self.etree.Element 654 SubElement = self.etree.SubElement 655 root = Element('root') 656 SubElement(root, 'a') 657 SubElement(root, 'b') 658 659 self.assertEquals(['a', 'b'], 660 [c.tag for c in root]) 661 root[0].addprevious(root[1]) 662 self.assertEquals(['b', 'a'], 663 [c.tag for c in root])
664
665 - def test_addnext_root(self):
666 Element = self.etree.Element 667 a = Element('a') 668 b = Element('b') 669 self.assertRaises(TypeError, a.addnext, b)
670
671 - def test_addnext_root(self):
672 Element = self.etree.Element 673 a = Element('a') 674 b = Element('b') 675 self.assertRaises(TypeError, a.addnext, b)
676
677 - def test_addprevious_pi(self):
678 Element = self.etree.Element 679 SubElement = self.etree.SubElement 680 PI = self.etree.PI 681 root = Element('root') 682 SubElement(root, 'a') 683 pi = PI('TARGET', 'TEXT') 684 pi.tail = "TAIL" 685 686 self.assertEquals('<root><a></a></root>', 687 self._writeElement(root)) 688 root[0].addprevious(pi) 689 self.assertEquals('<root><?TARGET TEXT?>TAIL<a></a></root>', 690 self._writeElement(root))
691
692 - def test_addprevious_root_pi(self):
693 Element = self.etree.Element 694 PI = self.etree.PI 695 root = Element('root') 696 pi = PI('TARGET', 'TEXT') 697 pi.tail = "TAIL" 698 699 self.assertEquals('<root></root>', 700 self._writeElement(root)) 701 root.addprevious(pi) 702 self.assertEquals('<?TARGET TEXT?>\n<root></root>', 703 self._writeElement(root))
704
705 - def test_addnext_pi(self):
706 Element = self.etree.Element 707 SubElement = self.etree.SubElement 708 PI = self.etree.PI 709 root = Element('root') 710 SubElement(root, 'a') 711 pi = PI('TARGET', 'TEXT') 712 pi.tail = "TAIL" 713 714 self.assertEquals('<root><a></a></root>', 715 self._writeElement(root)) 716 root[0].addnext(pi) 717 self.assertEquals('<root><a></a><?TARGET TEXT?>TAIL</root>', 718 self._writeElement(root))
719
720 - def test_addnext_root_pi(self):
721 Element = self.etree.Element 722 PI = self.etree.PI 723 root = Element('root') 724 pi = PI('TARGET', 'TEXT') 725 pi.tail = "TAIL" 726 727 self.assertEquals('<root></root>', 728 self._writeElement(root)) 729 root.addnext(pi) 730 self.assertEquals('<root></root>\n<?TARGET TEXT?>', 731 self._writeElement(root))
732
733 - def test_addnext_comment(self):
734 Element = self.etree.Element 735 SubElement = self.etree.SubElement 736 Comment = self.etree.Comment 737 root = Element('root') 738 SubElement(root, 'a') 739 comment = Comment('TEXT ') 740 comment.tail = "TAIL" 741 742 self.assertEquals('<root><a></a></root>', 743 self._writeElement(root)) 744 root[0].addnext(comment) 745 self.assertEquals('<root><a></a><!--TEXT -->TAIL</root>', 746 self._writeElement(root))
747
748 - def test_addnext_root_comment(self):
749 Element = self.etree.Element 750 Comment = self.etree.Comment 751 root = Element('root') 752 comment = Comment('TEXT ') 753 comment.tail = "TAIL" 754 755 self.assertEquals('<root></root>', 756 self._writeElement(root)) 757 root.addnext(comment) 758 self.assertEquals('<root></root>\n<!--TEXT -->', 759 self._writeElement(root))
760
761 - def test_addprevious_comment(self):
762 Element = self.etree.Element 763 SubElement = self.etree.SubElement 764 Comment = self.etree.Comment 765 root = Element('root') 766 SubElement(root, 'a') 767 comment = Comment('TEXT ') 768 comment.tail = "TAIL" 769 770 self.assertEquals('<root><a></a></root>', 771 self._writeElement(root)) 772 root[0].addprevious(comment) 773 self.assertEquals('<root><!--TEXT -->TAIL<a></a></root>', 774 self._writeElement(root))
775
776 - def test_addprevious_root_comment(self):
777 Element = self.etree.Element 778 Comment = self.etree.Comment 779 root = Element('root') 780 comment = Comment('TEXT ') 781 comment.tail = "TAIL" 782 783 self.assertEquals('<root></root>', 784 self._writeElement(root)) 785 root.addprevious(comment) 786 self.assertEquals('<!--TEXT -->\n<root></root>', 787 self._writeElement(root))
788 789 # ET's Elements have items() and key(), but not values()
790 - def test_attribute_values(self):
791 XML = self.etree.XML 792 793 root = XML('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>') 794 values = root.values() 795 values.sort() 796 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
797 798 # gives error in ElementTree
799 - def test_comment_empty(self):
800 Element = self.etree.Element 801 Comment = self.etree.Comment 802 803 a = Element('a') 804 a.append(Comment()) 805 self.assertEquals( 806 '<a><!----></a>', 807 self._writeElement(a))
808 809 # ElementTree ignores comments
810 - def test_comment_parse_empty(self):
811 ElementTree = self.etree.ElementTree 812 tostring = self.etree.tostring 813 814 xml = '<a><b/><!----><c/></a>' 815 f = StringIO(xml) 816 doc = ElementTree(file=f) 817 a = doc.getroot() 818 self.assertEquals( 819 '', 820 a[1].text) 821 self.assertEquals( 822 xml, 823 tostring(a))
824 825 # ElementTree ignores comments
826 - def test_comment_no_proxy_yet(self):
827 ElementTree = self.etree.ElementTree 828 829 f = StringIO('<a><b></b><!-- hoi --><c></c></a>') 830 doc = ElementTree(file=f) 831 a = doc.getroot() 832 self.assertEquals( 833 ' hoi ', 834 a[1].text)
835 836 # ElementTree adds whitespace around comments
837 - def test_comment_text(self):
838 Element = self.etree.Element 839 Comment = self.etree.Comment 840 tostring = self.etree.tostring 841 842 a = Element('a') 843 a.append(Comment('foo')) 844 self.assertEquals( 845 '<a><!--foo--></a>', 846 tostring(a)) 847 848 a[0].text = "TEST" 849 self.assertEquals( 850 '<a><!--TEST--></a>', 851 tostring(a))
852 853 # ElementTree adds whitespace around comments
854 - def test_comment_whitespace(self):
855 Element = self.etree.Element 856 Comment = self.etree.Comment 857 tostring = self.etree.tostring 858 859 a = Element('a') 860 a.append(Comment(' foo ')) 861 self.assertEquals( 862 '<a><!-- foo --></a>', 863 tostring(a))
864 865 # does not raise an exception in ElementTree
866 - def test_comment_immutable(self):
867 Element = self.etree.Element 868 Comment = self.etree.Comment 869 870 c = Comment() 871 el = Element('myel') 872 873 self.assertRaises(TypeError, c.append, el) 874 self.assertRaises(TypeError, c.insert, 0, el) 875 self.assertRaises(TypeError, c.set, "myattr", "test")
876 877 # test weird dictionary interaction leading to segfault previously
878 - def test_weird_dict_interaction(self):
879 root = self.etree.Element('root') 880 add = self.etree.ElementTree(file=StringIO('<foo>Foo</foo>')) 881 root.append(self.etree.Element('baz'))
882 883 # test passing 'None' to dump
884 - def test_dump_none(self):
885 self.assertRaises(TypeError, etree.dump, None)
886
887 - def test_prefix(self):
888 ElementTree = self.etree.ElementTree 889 890 f = StringIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 891 doc = ElementTree(file=f) 892 a = doc.getroot() 893 self.assertEquals( 894 None, 895 a.prefix) 896 self.assertEquals( 897 'foo', 898 a[0].prefix)
899
900 - def test_prefix_default_ns(self):
901 ElementTree = self.etree.ElementTree 902 903 f = StringIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 904 doc = ElementTree(file=f) 905 a = doc.getroot() 906 self.assertEquals( 907 None, 908 a.prefix) 909 self.assertEquals( 910 None, 911 a[0].prefix)
912
913 - def test_getparent(self):
914 Element = self.etree.Element 915 SubElement = self.etree.SubElement 916 917 a = Element('a') 918 b = SubElement(a, 'b') 919 c = SubElement(a, 'c') 920 d = SubElement(b, 'd') 921 self.assertEquals( 922 None, 923 a.getparent()) 924 self.assertEquals( 925 a, 926 b.getparent()) 927 self.assertEquals( 928 b.getparent(), 929 c.getparent()) 930 self.assertEquals( 931 b, 932 d.getparent())
933
934 - def test_iterchildren(self):
935 XML = self.etree.XML 936 937 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>') 938 result = [] 939 for el in root.iterchildren(): 940 result.append(el.tag) 941 self.assertEquals(['one', 'two', 'three'], result)
942
943 - def test_iterchildren_reversed(self):
944 XML = self.etree.XML 945 946 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>') 947 result = [] 948 for el in root.iterchildren(reversed=True): 949 result.append(el.tag) 950 self.assertEquals(['three', 'two', 'one'], result)
951
952 - def test_iterchildren_tag(self):
953 XML = self.etree.XML 954 955 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>') 956 result = [] 957 for el in root.iterchildren(tag='two'): 958 result.append(el.text) 959 self.assertEquals(['Two', 'Bla'], result)
960
961 - def test_iterchildren_tag_reversed(self):
962 XML = self.etree.XML 963 964 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>') 965 result = [] 966 for el in root.iterchildren(reversed=True, tag='two'): 967 result.append(el.text) 968 self.assertEquals(['Bla', 'Two'], result)
969
970 - def test_iterancestors(self):
971 Element = self.etree.Element 972 SubElement = self.etree.SubElement 973 974 a = Element('a') 975 b = SubElement(a, 'b') 976 c = SubElement(a, 'c') 977 d = SubElement(b, 'd') 978 self.assertEquals( 979 [], 980 list(a.iterancestors())) 981 self.assertEquals( 982 [a], 983 list(b.iterancestors())) 984 self.assertEquals( 985 a, 986 c.iterancestors().next()) 987 self.assertEquals( 988 [b, a], 989 list(d.iterancestors()))
990
991 - def test_iterancestors_tag(self):
992 Element = self.etree.Element 993 SubElement = self.etree.SubElement 994 995 a = Element('a') 996 b = SubElement(a, 'b') 997 c = SubElement(a, 'c') 998 d = SubElement(b, 'd') 999 self.assertEquals( 1000 [a], 1001 list(d.iterancestors(tag='a')))
1002
1003 - def test_iterdescendants(self):
1004 Element = self.etree.Element 1005 SubElement = self.etree.SubElement 1006 1007 a = Element('a') 1008 b = SubElement(a, 'b') 1009 c = SubElement(a, 'c') 1010 d = SubElement(b, 'd') 1011 e = SubElement(c, 'e') 1012 1013 self.assertEquals( 1014 [b, d, c, e], 1015 list(a.iterdescendants())) 1016 self.assertEquals( 1017 [], 1018 list(d.iterdescendants()))
1019
1020 - def test_iterdescendants_tag(self):
1021 Element = self.etree.Element 1022 SubElement = self.etree.SubElement 1023 1024 a = Element('a') 1025 b = SubElement(a, 'b') 1026 c = SubElement(a, 'c') 1027 d = SubElement(b, 'd') 1028 e = SubElement(c, 'e') 1029 1030 self.assertEquals( 1031 [], 1032 list(a.iterdescendants('a'))) 1033 a2 = SubElement(e, 'a') 1034 self.assertEquals( 1035 [a2], 1036 list(a.iterdescendants('a'))) 1037 self.assertEquals( 1038 [a2], 1039 list(c.iterdescendants('a')))
1040
1041 - def test_getroottree(self):
1042 Element = self.etree.Element 1043 SubElement = self.etree.SubElement 1044 1045 a = Element('a') 1046 b = SubElement(a, 'b') 1047 c = SubElement(a, 'c') 1048 d = SubElement(b, 'd') 1049 self.assertEquals( 1050 a, 1051 a.getroottree().getroot()) 1052 self.assertEquals( 1053 a, 1054 b.getroottree().getroot()) 1055 self.assertEquals( 1056 a, 1057 d.getroottree().getroot())
1058
1059 - def test_getnext(self):
1060 Element = self.etree.Element 1061 SubElement = self.etree.SubElement 1062 1063 a = Element('a') 1064 b = SubElement(a, 'b') 1065 c = SubElement(a, 'c') 1066 self.assertEquals( 1067 None, 1068 a.getnext()) 1069 self.assertEquals( 1070 c, 1071 b.getnext()) 1072 self.assertEquals( 1073 None, 1074 c.getnext())
1075
1076 - def test_getprevious(self):
1077 Element = self.etree.Element 1078 SubElement = self.etree.SubElement 1079 1080 a = Element('a') 1081 b = SubElement(a, 'b') 1082 c = SubElement(a, 'c') 1083 d = SubElement(b, 'd') 1084 self.assertEquals( 1085 None, 1086 a.getprevious()) 1087 self.assertEquals( 1088 b, 1089 c.getprevious()) 1090 self.assertEquals( 1091 None, 1092 b.getprevious())
1093
1094 - def test_itersiblings(self):
1095 Element = self.etree.Element 1096 SubElement = self.etree.SubElement 1097 1098 a = Element('a') 1099 b = SubElement(a, 'b') 1100 c = SubElement(a, 'c') 1101 d = SubElement(b, 'd') 1102 self.assertEquals( 1103 [], 1104 list(a.itersiblings())) 1105 self.assertEquals( 1106 [c], 1107 list(b.itersiblings())) 1108 self.assertEquals( 1109 c, 1110 b.itersiblings().next()) 1111 self.assertEquals( 1112 [], 1113 list(c.itersiblings())) 1114 self.assertEquals( 1115 [b], 1116 list(c.itersiblings(preceding=True))) 1117 self.assertEquals( 1118 [], 1119 list(b.itersiblings(preceding=True)))
1120
1121 - def test_itersiblings_tag(self):
1122 Element = self.etree.Element 1123 SubElement = self.etree.SubElement 1124 1125 a = Element('a') 1126 b = SubElement(a, 'b') 1127 c = SubElement(a, 'c') 1128 d = SubElement(b, 'd') 1129 self.assertEquals( 1130 [], 1131 list(a.itersiblings(tag='XXX'))) 1132 self.assertEquals( 1133 [c], 1134 list(b.itersiblings(tag='c'))) 1135 self.assertEquals( 1136 [b], 1137 list(c.itersiblings(preceding=True, tag='b'))) 1138 self.assertEquals( 1139 [], 1140 list(c.itersiblings(preceding=True, tag='c')))
1141
1142 - def test_parseid(self):
1143 parseid = self.etree.parseid 1144 XML = self.etree.XML 1145 xml_text = ''' 1146 <!DOCTYPE document [ 1147 <!ELEMENT document (h1,p)*> 1148 <!ELEMENT h1 (#PCDATA)> 1149 <!ATTLIST h1 myid ID #REQUIRED> 1150 <!ELEMENT p (#PCDATA)> 1151 <!ATTLIST p someid ID #REQUIRED> 1152 ]> 1153 <document> 1154 <h1 myid="chapter1">...</h1> 1155 <p id="note1" class="note">...</p> 1156 <p>Regular paragraph.</p> 1157 <p xml:id="xmlid">XML:ID paragraph.</p> 1158 <p someid="warn1" class="warning">...</p> 1159 </document> 1160 ''' 1161 1162 tree, dic = parseid(StringIO(xml_text)) 1163 root = tree.getroot() 1164 root2 = XML(xml_text) 1165 self.assertEquals(self._writeElement(root), 1166 self._writeElement(root2)) 1167 expected = { 1168 "chapter1" : root[0], 1169 "xmlid" : root[3], 1170 "warn1" : root[4] 1171 } 1172 self.assert_("chapter1" in dic) 1173 self.assert_("warn1" in dic) 1174 self.assert_("xmlid" in dic) 1175 self._checkIDDict(dic, expected)
1176
1177 - def test_XMLDTDID(self):
1178 XMLDTDID = self.etree.XMLDTDID 1179 XML = self.etree.XML 1180 xml_text = ''' 1181 <!DOCTYPE document [ 1182 <!ELEMENT document (h1,p)*> 1183 <!ELEMENT h1 (#PCDATA)> 1184 <!ATTLIST h1 myid ID #REQUIRED> 1185 <!ELEMENT p (#PCDATA)> 1186 <!ATTLIST p someid ID #REQUIRED> 1187 ]> 1188 <document> 1189 <h1 myid="chapter1">...</h1> 1190 <p id="note1" class="note">...</p> 1191 <p>Regular paragraph.</p> 1192 <p xml:id="xmlid">XML:ID paragraph.</p> 1193 <p someid="warn1" class="warning">...</p> 1194 </document> 1195 ''' 1196 1197 root, dic = XMLDTDID(xml_text) 1198 root2 = XML(xml_text) 1199 self.assertEquals(self._writeElement(root), 1200 self._writeElement(root2)) 1201 expected = { 1202 "chapter1" : root[0], 1203 "xmlid" : root[3], 1204 "warn1" : root[4] 1205 } 1206 self.assert_("chapter1" in dic) 1207 self.assert_("warn1" in dic) 1208 self.assert_("xmlid" in dic) 1209 self._checkIDDict(dic, expected)
1210
1211 - def test_XMLDTDID_empty(self):
1212 XMLDTDID = self.etree.XMLDTDID 1213 XML = self.etree.XML 1214 xml_text = ''' 1215 <document> 1216 <h1 myid="chapter1">...</h1> 1217 <p id="note1" class="note">...</p> 1218 <p>Regular paragraph.</p> 1219 <p someid="warn1" class="warning">...</p> 1220 </document> 1221 ''' 1222 1223 root, dic = XMLDTDID(xml_text) 1224 root2 = XML(xml_text) 1225 self.assertEquals(self._writeElement(root), 1226 self._writeElement(root2)) 1227 expected = {} 1228 self._checkIDDict(dic, expected)
1229
1230 - def _checkIDDict(self, dic, expected):
1231 self.assertEquals(dic, expected) 1232 self.assertEquals(len(dic), 1233 len(expected)) 1234 self.assertEquals(sorted(dic.items()), 1235 sorted(expected.items())) 1236 self.assertEquals(sorted(dic.iteritems()), 1237 sorted(expected.iteritems())) 1238 self.assertEquals(sorted(dic.keys()), 1239 sorted(expected.keys())) 1240 self.assertEquals(sorted(dic.iterkeys()), 1241 sorted(expected.iterkeys())) 1242 self.assertEquals(sorted(dic.values()), 1243 sorted(expected.values())) 1244 self.assertEquals(sorted(dic.itervalues()), 1245 sorted(expected.itervalues()))
1246
1247 - def test_namespaces(self):
1248 etree = self.etree 1249 1250 r = {'foo': 'http://ns.infrae.com/foo'} 1251 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1252 self.assertEquals( 1253 'foo', 1254 e.prefix) 1255 self.assertEquals( 1256 '<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>', 1257 self._writeElement(e))
1258
1259 - def test_namespaces_default(self):
1260 etree = self.etree 1261 1262 r = {None: 'http://ns.infrae.com/foo'} 1263 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1264 self.assertEquals( 1265 None, 1266 e.prefix) 1267 self.assertEquals( 1268 '{http://ns.infrae.com/foo}bar', 1269 e.tag) 1270 self.assertEquals( 1271 '<bar xmlns="http://ns.infrae.com/foo"></bar>', 1272 self._writeElement(e))
1273
1274 - def test_namespaces_default_and_attr(self):
1275 etree = self.etree 1276 1277 r = {None: 'http://ns.infrae.com/foo', 1278 'hoi': 'http://ns.infrae.com/hoi'} 1279 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1280 e.set('{http://ns.infrae.com/hoi}test', 'value') 1281 self.assertEquals( 1282 '<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>', 1283 self._writeElement(e))
1284
1285 - def test_namespaces_elementtree(self):
1286 etree = self.etree 1287 r = {None: 'http://ns.infrae.com/foo', 1288 'hoi': 'http://ns.infrae.com/hoi'} 1289 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 1290 tree = etree.ElementTree(element=e) 1291 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 1292 self.assertEquals( 1293 '<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>', 1294 self._writeElement(e))
1295
1296 - def test_namespaces_default_copy_element(self):
1297 etree = self.etree 1298 1299 r = {None: 'http://ns.infrae.com/foo'} 1300 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1301 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1302 1303 e1.append(e2) 1304 1305 self.assertEquals( 1306 None, 1307 e1.prefix) 1308 self.assertEquals( 1309 None, 1310 e1[0].prefix) 1311 self.assertEquals( 1312 '{http://ns.infrae.com/foo}bar', 1313 e1.tag) 1314 self.assertEquals( 1315 '{http://ns.infrae.com/foo}bar', 1316 e1[0].tag)
1317
1318 - def test_namespaces_copy_element(self):
1319 etree = self.etree 1320 1321 r = {None: 'http://ns.infrae.com/BAR'} 1322 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 1323 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1324 1325 e1.append(e2) 1326 1327 self.assertEquals( 1328 None, 1329 e1.prefix) 1330 self.assertNotEquals( 1331 None, 1332 e2.prefix) 1333 self.assertEquals( 1334 '{http://ns.infrae.com/BAR}bar', 1335 e1.tag) 1336 self.assertEquals( 1337 '{http://ns.infrae.com/foo}bar', 1338 e2.tag)
1339
1340 - def test_namespaces_reuse_after_move(self):
1341 ns_href = "http://a.b.c" 1342 one = self.etree.fromstring( 1343 '<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href) 1344 baz = one[0][0] 1345 1346 two = self.etree.fromstring( 1347 '<root xmlns:ns="%s"/>' % ns_href) 1348 two.append(baz) 1349 del one # make sure the source document is deallocated 1350 1351 self.assertEquals('{%s}baz' % ns_href, baz.tag) 1352 self.assertEquals( 1353 '<root xmlns:ns="%s"><ns:baz/></root>' % ns_href, 1354 self.etree.tostring(two))
1355
1356 - def _test_namespaces_after_serialize(self):
1357 # FIXME: this currently fails - fix serializer.pxi! 1358 parse = self.etree.parse 1359 tostring = self.etree.tostring 1360 1361 ns_href = "http://a.b.c" 1362 one = parse( 1363 StringIO('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 1364 baz = one.getroot()[0][0] 1365 1366 print tostring(baz) 1367 parsed = parse(StringIO( tostring(baz) )).getroot() 1368 1369 self.assertEquals('{%s}baz' % ns_href, parsed.tag)
1370
1371 - def test_element_nsmap(self):
1372 etree = self.etree 1373 1374 r = {None: 'http://ns.infrae.com/foo', 1375 'hoi': 'http://ns.infrae.com/hoi'} 1376 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1377 self.assertEquals( 1378 r, 1379 e.nsmap)
1380
1381 - def test_subelement_nsmap(self):
1382 etree = self.etree 1383 1384 re = {None: 'http://ns.infrae.com/foo', 1385 'hoi': 'http://ns.infrae.com/hoi'} 1386 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 1387 1388 rs = {None: 'http://ns.infrae.com/honk', 1389 'top': 'http://ns.infrae.com/top'} 1390 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 1391 1392 r = re.copy() 1393 r.update(rs) 1394 self.assertEquals( 1395 re, 1396 e.nsmap) 1397 self.assertEquals( 1398 r, 1399 s.nsmap)
1400
1401 - def test_getiterator_filter_namespace(self):
1402 Element = self.etree.Element 1403 SubElement = self.etree.SubElement 1404 1405 a = Element('{a}a') 1406 b = SubElement(a, '{a}b') 1407 c = SubElement(a, '{a}c') 1408 d = SubElement(b, '{b}d') 1409 e = SubElement(c, '{a}e') 1410 f = SubElement(c, '{b}f') 1411 1412 self.assertEquals( 1413 [a], 1414 list(a.getiterator('{a}a'))) 1415 self.assertEquals( 1416 [], 1417 list(a.getiterator('{b}a'))) 1418 self.assertEquals( 1419 [], 1420 list(a.getiterator('a'))) 1421 self.assertEquals( 1422 [f], 1423 list(c.getiterator('{b}*'))) 1424 self.assertEquals( 1425 [d, f], 1426 list(a.getiterator('{b}*')))
1427
1428 - def test_getiterator_filter_entities(self):
1429 Element = self.etree.Element 1430 Entity = self.etree.Entity 1431 SubElement = self.etree.SubElement 1432 1433 a = Element('a') 1434 b = SubElement(a, 'b') 1435 entity_b = Entity("TEST-b") 1436 b.append(entity_b) 1437 1438 self.assertEquals( 1439 [entity_b], 1440 list(a.getiterator(Entity))) 1441 1442 entity_a = Entity("TEST-a") 1443 a.append(entity_a) 1444 1445 self.assertEquals( 1446 [entity_b, entity_a], 1447 list(a.getiterator(Entity))) 1448 1449 self.assertEquals( 1450 [entity_b], 1451 list(b.getiterator(Entity)))
1452
1453 - def test_getiterator_filter_element(self):
1454 Element = self.etree.Element 1455 Comment = self.etree.Comment 1456 PI = self.etree.PI 1457 SubElement = self.etree.SubElement 1458 1459 a = Element('a') 1460 b = SubElement(a, 'b') 1461 a.append(Comment("test")) 1462 a.append(PI("pi", "content")) 1463 c = SubElement(a, 'c') 1464 1465 self.assertEquals( 1466 [a, b, c], 1467 list(a.getiterator(Element)))
1468
1469 - def test_getiterator_filter_all_comment_pi(self):
1470 # ElementTree iterates over everything here 1471 Element = self.etree.Element 1472 Comment = self.etree.Comment 1473 PI = self.etree.PI 1474 SubElement = self.etree.SubElement 1475 1476 a = Element('a') 1477 b = SubElement(a, 'b') 1478 a.append(Comment("test")) 1479 a.append(PI("pi", "content")) 1480 c = SubElement(a, 'c') 1481 1482 self.assertEquals( 1483 [a, b, c], 1484 list(a.getiterator('*')))
1485
1486 - def test_itertext(self):
1487 # ET 1.3+ 1488 XML = self.etree.XML 1489 root = XML("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>") 1490 1491 text = list(root.itertext()) 1492 self.assertEquals(["RTEXT", "ATAIL", "CTEXT", "CTAIL"], 1493 text)
1494
1495 - def test_itertext_child(self):
1496 # ET 1.3+ 1497 XML = self.etree.XML 1498 root = XML("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>") 1499 1500 text = list(root[2].itertext()) 1501 self.assertEquals(["CTEXT"], 1502 text)
1503
1504 - def test_findall_ns(self):
1505 XML = self.etree.XML 1506 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>') 1507 self.assertEquals(len(root.findall(".//{X}b")), 2) 1508 self.assertEquals(len(root.findall(".//{X}*")), 2) 1509 self.assertEquals(len(root.findall(".//b")), 3)
1510
1511 - def test_index(self):
1512 etree = self.etree 1513 e = etree.Element('foo') 1514 for i in range(10): 1515 etree.SubElement(e, 'a%s' % i) 1516 for i in range(10): 1517 self.assertEquals( 1518 i, 1519 e.index(e[i])) 1520 self.assertEquals( 1521 3, e.index(e[3], 3)) 1522 self.assertRaises( 1523 ValueError, e.index, e[3], 4) 1524 self.assertRaises( 1525 ValueError, e.index, e[3], 0, 2) 1526 self.assertRaises( 1527 ValueError, e.index, e[8], 0, -3) 1528 self.assertRaises( 1529 ValueError, e.index, e[8], -5, -3) 1530 self.assertEquals( 1531 8, e.index(e[8], 0, -1)) 1532 self.assertEquals( 1533 8, e.index(e[8], -12, -1)) 1534 self.assertEquals( 1535 0, e.index(e[0], -12, -1))
1536
1537 - def test_replace(self):
1538 etree = self.etree 1539 e = etree.Element('foo') 1540 for i in range(10): 1541 el = etree.SubElement(e, 'a%s' % i) 1542 el.text = "text%d" % i 1543 el.tail = "tail%d" % i 1544 1545 child0 = e[0] 1546 child1 = e[1] 1547 child2 = e[2] 1548 1549 e.replace(e[0], e[1]) 1550 self.assertEquals( 1551 9, len(e)) 1552 self.assertEquals( 1553 child1, e[0]) 1554 self.assertEquals( 1555 child1.text, "text1") 1556 self.assertEquals( 1557 child1.tail, "tail1") 1558 self.assertEquals( 1559 child0.tail, "tail0") 1560 self.assertEquals( 1561 child2, e[1]) 1562 1563 e.replace(e[-1], e[0]) 1564 self.assertEquals( 1565 child1, e[-1]) 1566 self.assertEquals( 1567 child1.text, "text1") 1568 self.assertEquals( 1569 child1.tail, "tail1") 1570 self.assertEquals( 1571 child2, e[0])
1572
1573 - def test_replace_new(self):
1574 etree = self.etree 1575 e = etree.Element('foo') 1576 for i in range(10): 1577 etree.SubElement(e, 'a%s' % i) 1578 1579 new_element = etree.Element("test") 1580 new_element.text = "TESTTEXT" 1581 new_element.tail = "TESTTAIL" 1582 child1 = e[1] 1583 e.replace(e[0], new_element) 1584 self.assertEquals( 1585 new_element, e[0]) 1586 self.assertEquals( 1587 "TESTTEXT", 1588 e[0].text) 1589 self.assertEquals( 1590 "TESTTAIL", 1591 e[0].tail) 1592 self.assertEquals( 1593 child1, e[1])
1594
1595 - def test_setslice_all_empty_reversed(self):
1596 Element = self.etree.Element 1597 SubElement = self.etree.SubElement 1598 1599 a = Element('a') 1600 1601 e = Element('e') 1602 f = Element('f') 1603 g = Element('g') 1604 1605 s = [e, f, g] 1606 a[::-1] = s 1607 self.assertEquals( 1608 [g, f, e], 1609 list(a))
1610
1611 - def test_setslice_step(self):
1612 Element = self.etree.Element 1613 SubElement = self.etree.SubElement 1614 1615 a = Element('a') 1616 b = SubElement(a, 'b') 1617 c = SubElement(a, 'c') 1618 d = SubElement(a, 'd') 1619 e = SubElement(a, 'e') 1620 1621 x = Element('x') 1622 y = Element('y') 1623 1624 a[1::2] = [x, y] 1625 self.assertEquals( 1626 [b, x, d, y], 1627 list(a))
1628
1629 - def test_setslice_step_negative(self):
1630 Element = self.etree.Element 1631 SubElement = self.etree.SubElement 1632 1633 a = Element('a') 1634 b = SubElement(a, 'b') 1635 c = SubElement(a, 'c') 1636 d = SubElement(a, 'd') 1637 e = SubElement(a, 'e') 1638 1639 x = Element('x') 1640 y = Element('y') 1641 1642 a[1::-1] = [x, y] 1643 self.assertEquals( 1644 [y, x, d, e], 1645 list(a))
1646
1647 - def test_setslice_step_negative2(self):
1648 Element = self.etree.Element 1649 SubElement = self.etree.SubElement 1650 1651 a = Element('a') 1652 b = SubElement(a, 'b') 1653 c = SubElement(a, 'c') 1654 d = SubElement(a, 'd') 1655 e = SubElement(a, 'e') 1656 1657 x = Element('x') 1658 y = Element('y') 1659 1660 a[::-2] = [x, y] 1661 self.assertEquals( 1662 [b, y, d, x], 1663 list(a))
1664
1665 - def test_setslice_step_overrun(self):
1666 Element = self.etree.Element 1667 SubElement = self.etree.SubElement 1668 try: 1669 slice 1670 except NameError: 1671 print "slice() not found" 1672 return 1673 1674 a = Element('a') 1675 b = SubElement(a, 'b') 1676 c = SubElement(a, 'c') 1677 d = SubElement(a, 'd') 1678 e = SubElement(a, 'e') 1679 1680 x = Element('x') 1681 y = Element('y') 1682 z = Element('z') 1683 1684 self.assertRaises( 1685 ValueError, 1686 operator.setitem, a, slice(1,None,2), [x, y, z]) 1687 1688 self.assertEquals( 1689 [b, c, d, e], 1690 list(a))
1691
1692 - def test_extend(self):
1693 etree = self.etree 1694 root = etree.Element('foo') 1695 for i in range(3): 1696 element = etree.SubElement(root, 'a%s' % i) 1697 element.text = "text%d" % i 1698 element.tail = "tail%d" % i 1699 1700 elements = [] 1701 for i in range(3): 1702 new_element = etree.Element("test%s" % i) 1703 new_element.text = "TEXT%s" % i 1704 new_element.tail = "TAIL%s" % i 1705 elements.append(new_element) 1706 1707 root.extend(elements) 1708 1709 self.assertEquals( 1710 ["a0", "a1", "a2", "test0", "test1", "test2"], 1711 [ el.tag for el in root ]) 1712 self.assertEquals( 1713 ["text0", "text1", "text2", "TEXT0", "TEXT1", "TEXT2"], 1714 [ el.text for el in root ]) 1715 self.assertEquals( 1716 ["tail0", "tail1", "tail2", "TAIL0", "TAIL1", "TAIL2"], 1717 [ el.tail for el in root ])
1718
1719 - def test_sourceline_XML(self):
1720 XML = self.etree.XML 1721 root = XML('''<?xml version="1.0"?> 1722 <root><test> 1723 1724 <bla/></test> 1725 </root> 1726 ''') 1727 1728 self.assertEquals( 1729 [2, 2, 4], 1730 [ el.sourceline for el in root.getiterator() ])
1731
1732 - def test_sourceline_parse(self):
1733 parse = self.etree.parse 1734 tree = parse(fileInTestDir('include/test_xinclude.xml')) 1735 1736 self.assertEquals( 1737 [1, 2, 3], 1738 [ el.sourceline for el in tree.getiterator() ])
1739
1740 - def test_sourceline_iterparse_end(self):
1741 iterparse = self.etree.iterparse 1742 lines = list( 1743 el.sourceline for (event, el) in 1744 iterparse(fileInTestDir('include/test_xinclude.xml'))) 1745 1746 self.assertEquals( 1747 [2, 3, 1], 1748 lines)
1749
1750 - def test_sourceline_iterparse_start(self):
1751 iterparse = self.etree.iterparse 1752 lines = list( 1753 el.sourceline for (event, el) in 1754 iterparse(fileInTestDir('include/test_xinclude.xml'), 1755 events=("start",))) 1756 1757 self.assertEquals( 1758 [1, 2, 3], 1759 lines)
1760
1761 - def test_sourceline_element(self):
1762 Element = self.etree.Element 1763 SubElement = self.etree.SubElement 1764 el = Element("test") 1765 self.assertEquals(None, el.sourceline) 1766 1767 child = SubElement(el, "test") 1768 self.assertEquals(None, el.sourceline) 1769 self.assertEquals(None, child.sourceline)
1770
1771 - def test_XML_base_url_docinfo(self):
1772 etree = self.etree 1773 root = etree.XML("<root/>", base_url="http://no/such/url") 1774 docinfo = root.getroottree().docinfo 1775 self.assertEquals(docinfo.URL, "http://no/such/url")
1776
1777 - def test_HTML_base_url_docinfo(self):
1778 etree = self.etree 1779 root = etree.HTML("<html/>", base_url="http://no/such/url") 1780 docinfo = root.getroottree().docinfo 1781 self.assertEquals(docinfo.URL, "http://no/such/url")
1782
1783 - def test_docinfo_public(self):
1784 etree = self.etree 1785 xml_header = '<?xml version="1.0" encoding="ascii"?>' 1786 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 1787 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 1788 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 1789 1790 xml = xml_header + doctype_string + '<html><body></body></html>' 1791 1792 tree = etree.parse(StringIO(xml)) 1793 docinfo = tree.docinfo 1794 self.assertEquals(docinfo.encoding, "ascii") 1795 self.assertEquals(docinfo.xml_version, "1.0") 1796 self.assertEquals(docinfo.public_id, pub_id) 1797 self.assertEquals(docinfo.system_url, sys_id) 1798 self.assertEquals(docinfo.root_name, 'html') 1799 self.assertEquals(docinfo.doctype, doctype_string)
1800
1801 - def test_docinfo_system(self):
1802 etree = self.etree 1803 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 1804 sys_id = "some.dtd" 1805 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 1806 xml = xml_header + doctype_string + '<html><body></body></html>' 1807 1808 tree = etree.parse(StringIO(xml)) 1809 docinfo = tree.docinfo 1810 self.assertEquals(docinfo.encoding, "UTF-8") 1811 self.assertEquals(docinfo.xml_version, "1.0") 1812 self.assertEquals(docinfo.public_id, None) 1813 self.assertEquals(docinfo.system_url, sys_id) 1814 self.assertEquals(docinfo.root_name, 'html') 1815 self.assertEquals(docinfo.doctype, doctype_string)
1816
1817 - def test_docinfo_empty(self):
1818 etree = self.etree 1819 xml = '<html><body></body></html>' 1820 tree = etree.parse(StringIO(xml)) 1821 docinfo = tree.docinfo 1822 self.assertEquals(docinfo.encoding, None) 1823 self.assertEquals(docinfo.xml_version, "1.0") 1824 self.assertEquals(docinfo.public_id, None) 1825 self.assertEquals(docinfo.system_url, None) 1826 self.assertEquals(docinfo.root_name, 'html') 1827 self.assertEquals(docinfo.doctype, '')
1828
1829 - def test_dtd_io(self):
1830 # check that DTDs that go in also go back out 1831 xml = '''\ 1832 <!DOCTYPE test SYSTEM "test.dtd" [ 1833 <!ENTITY entity "tasty"> 1834 <!ELEMENT test (a)> 1835 <!ELEMENT a (#PCDATA)> 1836 ]> 1837 <test><a>test-test</a></test>\ 1838 ''' 1839 tree = self.etree.parse(StringIO(xml)) 1840 self.assertEqual(self.etree.tostring(tree).replace(" ", ""), 1841 xml.replace(" ", ""))
1842
1843 - def test_byte_zero(self):
1844 Element = self.etree.Element 1845 1846 a = Element('a') 1847 self.assertRaises(AssertionError, setattr, a, "text", 'ha\0ho') 1848 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\0ho') 1849 1850 self.assertRaises(AssertionError, Element, 'ha\0ho')
1851
1852 - def test_unicode_byte_zero(self):
1853 Element = self.etree.Element 1854 1855 a = Element('a') 1856 self.assertRaises(AssertionError, setattr, a, "text", u'ha\0ho') 1857 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\0ho') 1858 1859 self.assertRaises(AssertionError, Element, u'ha\0ho')
1860
1861 - def test_byte_invalid(self):
1862 Element = self.etree.Element 1863 1864 a = Element('a') 1865 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x07ho') 1866 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x02ho') 1867 1868 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x07ho') 1869 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x02ho') 1870 1871 self.assertRaises(AssertionError, Element, 'ha\x07ho') 1872 self.assertRaises(AssertionError, Element, 'ha\x02ho')
1873
1874 - def test_unicode_byte_invalid(self):
1875 Element = self.etree.Element 1876 1877 a = Element('a') 1878 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x07ho') 1879 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x02ho') 1880 1881 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x07ho') 1882 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x02ho') 1883 1884 self.assertRaises(AssertionError, Element, u'ha\x07ho') 1885 self.assertRaises(AssertionError, Element, u'ha\x02ho')
1886
1887 - def test_encoding_tostring_utf16(self):
1888 # ElementTree fails to serialize this 1889 tostring = self.etree.tostring 1890 Element = self.etree.Element 1891 SubElement = self.etree.SubElement 1892 1893 a = Element('a') 1894 b = SubElement(a, 'b') 1895 c = SubElement(a, 'c') 1896 1897 result = unicode(tostring(a, encoding='UTF-16'), 'UTF-16') 1898 self.assertEquals('<a><b></b><c></c></a>', 1899 canonicalize(result))
1900
1901 - def test_tostring_none(self):
1902 # ElementTree raises an AssertionError here 1903 tostring = self.etree.tostring 1904 self.assertRaises(TypeError, self.etree.tostring, None)
1905
1906 - def test_tostring_pretty(self):
1907 tostring = self.etree.tostring 1908 Element = self.etree.Element 1909 SubElement = self.etree.SubElement 1910 1911 a = Element('a') 1912 b = SubElement(a, 'b') 1913 c = SubElement(a, 'c') 1914 1915 result = tostring(a) 1916 self.assertEquals(result, "<a><b/><c/></a>") 1917 1918 result = tostring(a, pretty_print=False) 1919 self.assertEquals(result, "<a><b/><c/></a>") 1920 1921 result = tostring(a, pretty_print=True) 1922 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
1923
1924 - def test_tostring_method_text_encoding(self):
1925 tostring = self.etree.tostring 1926 Element = self.etree.Element 1927 SubElement = self.etree.SubElement 1928 1929 a = Element('a') 1930 a.text = "A" 1931 a.tail = "tail" 1932 b = SubElement(a, 'b') 1933 b.text = "B" 1934 b.tail = u"Søk på nettet" 1935 c = SubElement(a, 'c') 1936 c.text = "C" 1937 1938 result = tostring(a, method="text", encoding="UTF-16") 1939 1940 self.assertEquals(u'ABSøk på nettetCtail'.encode("UTF-16"), 1941 result)
1942
1943 - def test_tounicode(self):
1944 tounicode = self.etree.tounicode 1945 Element = self.etree.Element 1946 SubElement = self.etree.SubElement 1947 1948 a = Element('a') 1949 b = SubElement(a, 'b') 1950 c = SubElement(a, 'c') 1951 1952 self.assert_(isinstance(tounicode(a), unicode)) 1953 self.assertEquals('<a><b></b><c></c></a>', 1954 canonicalize(tounicode(a)))
1955
1956 - def test_tounicode_element(self):
1957 tounicode = self.etree.tounicode 1958 Element = self.etree.Element 1959 SubElement = self.etree.SubElement 1960 1961 a = Element('a') 1962 b = SubElement(a, 'b') 1963 c = SubElement(a, 'c') 1964 d = SubElement(c, 'd') 1965 self.assert_(isinstance(tounicode(b), unicode)) 1966 self.assert_(isinstance(tounicode(c), unicode)) 1967 self.assertEquals('<b></b>', 1968 canonicalize(tounicode(b))) 1969 self.assertEquals('<c><d></d></c>', 1970 canonicalize(tounicode(c)))
1971
1972 - def test_tounicode_none(self):
1973 tounicode = self.etree.tounicode 1974 self.assertRaises(TypeError, self.etree.tounicode, None)
1975
1976 - def test_tounicode_element_tail(self):
1977 tounicode = self.etree.tounicode 1978 Element = self.etree.Element 1979 SubElement = self.etree.SubElement 1980 1981 a = Element('a') 1982 b = SubElement(a, 'b') 1983 c = SubElement(a, 'c') 1984 d = SubElement(c, 'd') 1985 b.tail = 'Foo' 1986 1987 self.assert_(isinstance(tounicode(b), unicode)) 1988 self.assert_(tounicode(b) == '<b/>Foo' or 1989 tounicode(b) == '<b />Foo')
1990
1991 - def test_tounicode_pretty(self):
1992 tounicode = self.etree.tounicode 1993 Element = self.etree.Element 1994 SubElement = self.etree.SubElement 1995 1996 a = Element('a') 1997 b = SubElement(a, 'b') 1998 c = SubElement(a, 'c') 1999 2000 result = tounicode(a) 2001 self.assertEquals(result, "<a><b/><c/></a>") 2002 2003 result = tounicode(a, pretty_print=False) 2004 self.assertEquals(result, "<a><b/><c/></a>") 2005 2006 result = tounicode(a, pretty_print=True) 2007 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2008
2009 - def _writeElement(self, element, encoding='us-ascii'):
2010 """Write out element for comparison. 2011 """ 2012 ElementTree = self.etree.ElementTree 2013 f = StringIO() 2014 tree = ElementTree(element=element) 2015 tree.write(f, encoding=encoding) 2016 data = f.getvalue() 2017 return canonicalize(data)
2018 2019
2020 -class XIncludeTestCase(HelperTestCase):
2021 - def test_xinclude_text(self):
2022 filename = fileInTestDir('test_broken.xml') 2023 root = etree.XML('''\ 2024 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 2025 <xi:include href="%s" parse="text"/> 2026 </doc> 2027 ''' % filename) 2028 old_text = root.text 2029 content = open(filename).read() 2030 old_tail = root[0].tail 2031 2032 self.include( etree.ElementTree(root) ) 2033 self.assertEquals(old_text + content + old_tail, 2034 root.text)
2035
2036 - def test_xinclude(self):
2037 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 2038 self.assertNotEquals( 2039 'a', 2040 tree.getroot()[1].tag) 2041 # process xincludes 2042 self.include( tree ) 2043 # check whether we find it replaced with included data 2044 self.assertEquals( 2045 'a', 2046 tree.getroot()[1].tag)
2047
2048 -class ETreeXIncludeTestCase(XIncludeTestCase):
2049 - def include(self, tree):
2050 tree.xinclude()
2051 2052
2053 -class ElementIncludeTestCase(XIncludeTestCase):
2054 from lxml import ElementInclude
2055 - def include(self, tree):
2056 self.ElementInclude.include(tree.getroot())
2057 2058
2059 -class ETreeC14NTestCase(HelperTestCase):
2060 - def test_c14n(self):
2061 tree = self.parse('<a><b/></a>') 2062 f = StringIO() 2063 tree.write_c14n(f) 2064 s = f.getvalue() 2065 self.assertEquals('<a><b></b></a>', 2066 s)
2067
2068 -def test_suite():
2069 suite = unittest.TestSuite() 2070 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 2071 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 2072 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 2073 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 2074 suite.addTests( 2075 [doctest.DocFileSuite('../../../doc/tutorial.txt')]) 2076 suite.addTests( 2077 [doctest.DocFileSuite('../../../doc/api.txt')]) 2078 suite.addTests( 2079 [doctest.DocFileSuite('../../../doc/parsing.txt')]) 2080 suite.addTests( 2081 [doctest.DocFileSuite('../../../doc/resolvers.txt')]) 2082 return suite
2083 2084 if __name__ == '__main__': 2085 print 'to test use test.py %s' % __file__ 2086