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.assertFalse(root[0].text) 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.assertFalse(root[0].text) 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 # TypeError in etree, AssertionError in ElementTree;
609 - def test_setitem_assert(self):
610 Element = self.etree.Element 611 SubElement = self.etree.SubElement 612 613 a = Element('a') 614 b = SubElement(a, 'b') 615 616 self.assertRaises(TypeError, 617 a.__setitem__, 0, 'foo')
618
619 - def test_append_None(self):
620 # raises AssertionError in ElementTree 621 Element = self.etree.Element 622 self.assertRaises(TypeError, Element('a').append, None)
623
624 - def test_addnext(self):
625 Element = self.etree.Element 626 SubElement = self.etree.SubElement 627 root = Element('root') 628 SubElement(root, 'a') 629 SubElement(root, 'b') 630 631 self.assertEquals(['a', 'b'], 632 [c.tag for c in root]) 633 root[1].addnext(root[0]) 634 self.assertEquals(['b', 'a'], 635 [c.tag for c in root])
636
637 - def test_addprevious(self):
638 Element = self.etree.Element 639 SubElement = self.etree.SubElement 640 root = Element('root') 641 SubElement(root, 'a') 642 SubElement(root, 'b') 643 644 self.assertEquals(['a', 'b'], 645 [c.tag for c in root]) 646 root[0].addprevious(root[1]) 647 self.assertEquals(['b', 'a'], 648 [c.tag for c in root])
649
650 - def test_addnext_root(self):
651 Element = self.etree.Element 652 a = Element('a') 653 b = Element('b') 654 self.assertRaises(TypeError, a.addnext, b)
655
656 - def test_addnext_root(self):
657 Element = self.etree.Element 658 a = Element('a') 659 b = Element('b') 660 self.assertRaises(TypeError, a.addnext, b)
661
662 - def test_addprevious_pi(self):
663 Element = self.etree.Element 664 SubElement = self.etree.SubElement 665 PI = self.etree.PI 666 root = Element('root') 667 SubElement(root, 'a') 668 pi = PI('TARGET', 'TEXT') 669 pi.tail = "TAIL" 670 671 self.assertEquals('<root><a></a></root>', 672 self._writeElement(root)) 673 root[0].addprevious(pi) 674 self.assertEquals('<root><?TARGET TEXT?>TAIL<a></a></root>', 675 self._writeElement(root))
676
677 - def test_addprevious_root_pi(self):
678 Element = self.etree.Element 679 PI = self.etree.PI 680 root = Element('root') 681 pi = PI('TARGET', 'TEXT') 682 pi.tail = "TAIL" 683 684 self.assertEquals('<root></root>', 685 self._writeElement(root)) 686 root.addprevious(pi) 687 self.assertEquals('<?TARGET TEXT?>\n<root></root>', 688 self._writeElement(root))
689
690 - def test_addnext_pi(self):
691 Element = self.etree.Element 692 SubElement = self.etree.SubElement 693 PI = self.etree.PI 694 root = Element('root') 695 SubElement(root, 'a') 696 pi = PI('TARGET', 'TEXT') 697 pi.tail = "TAIL" 698 699 self.assertEquals('<root><a></a></root>', 700 self._writeElement(root)) 701 root[0].addnext(pi) 702 self.assertEquals('<root><a></a><?TARGET TEXT?>TAIL</root>', 703 self._writeElement(root))
704
705 - def test_addnext_root_pi(self):
706 Element = self.etree.Element 707 PI = self.etree.PI 708 root = Element('root') 709 pi = PI('TARGET', 'TEXT') 710 pi.tail = "TAIL" 711 712 self.assertEquals('<root></root>', 713 self._writeElement(root)) 714 root.addnext(pi) 715 self.assertEquals('<root></root>\n<?TARGET TEXT?>', 716 self._writeElement(root))
717
718 - def test_addnext_comment(self):
719 Element = self.etree.Element 720 SubElement = self.etree.SubElement 721 Comment = self.etree.Comment 722 root = Element('root') 723 SubElement(root, 'a') 724 comment = Comment('TEXT ') 725 comment.tail = "TAIL" 726 727 self.assertEquals('<root><a></a></root>', 728 self._writeElement(root)) 729 root[0].addnext(comment) 730 self.assertEquals('<root><a></a><!--TEXT -->TAIL</root>', 731 self._writeElement(root))
732
733 - def test_addnext_root_comment(self):
734 Element = self.etree.Element 735 Comment = self.etree.Comment 736 root = Element('root') 737 comment = Comment('TEXT ') 738 comment.tail = "TAIL" 739 740 self.assertEquals('<root></root>', 741 self._writeElement(root)) 742 root.addnext(comment) 743 self.assertEquals('<root></root>\n<!--TEXT -->', 744 self._writeElement(root))
745
746 - def test_addprevious_comment(self):
747 Element = self.etree.Element 748 SubElement = self.etree.SubElement 749 Comment = self.etree.Comment 750 root = Element('root') 751 SubElement(root, 'a') 752 comment = Comment('TEXT ') 753 comment.tail = "TAIL" 754 755 self.assertEquals('<root><a></a></root>', 756 self._writeElement(root)) 757 root[0].addprevious(comment) 758 self.assertEquals('<root><!--TEXT -->TAIL<a></a></root>', 759 self._writeElement(root))
760
761 - def test_addprevious_root_comment(self):
762 Element = self.etree.Element 763 Comment = self.etree.Comment 764 root = Element('root') 765 comment = Comment('TEXT ') 766 comment.tail = "TAIL" 767 768 self.assertEquals('<root></root>', 769 self._writeElement(root)) 770 root.addprevious(comment) 771 self.assertEquals('<!--TEXT -->\n<root></root>', 772 self._writeElement(root))
773 774 # ET's Elements have items() and key(), but not values()
775 - def test_attribute_values(self):
776 XML = self.etree.XML 777 778 root = XML('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>') 779 values = root.values() 780 values.sort() 781 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
782 783 # gives error in ElementTree
784 - def test_comment_empty(self):
785 Element = self.etree.Element 786 Comment = self.etree.Comment 787 788 a = Element('a') 789 a.append(Comment()) 790 self.assertEquals( 791 '<a><!----></a>', 792 self._writeElement(a))
793 794 # ElementTree ignores comments
795 - def test_comment_parse_empty(self):
796 ElementTree = self.etree.ElementTree 797 tostring = self.etree.tostring 798 799 xml = '<a><b/><!----><c/></a>' 800 f = StringIO(xml) 801 doc = ElementTree(file=f) 802 a = doc.getroot() 803 self.assertEquals( 804 '', 805 a[1].text) 806 self.assertEquals( 807 xml, 808 tostring(a))
809 810 # ElementTree ignores comments
811 - def test_comment_no_proxy_yet(self):
812 ElementTree = self.etree.ElementTree 813 814 f = StringIO('<a><b></b><!-- hoi --><c></c></a>') 815 doc = ElementTree(file=f) 816 a = doc.getroot() 817 self.assertEquals( 818 ' hoi ', 819 a[1].text)
820 821 # ElementTree adds whitespace around comments
822 - def test_comment_text(self):
823 Element = self.etree.Element 824 Comment = self.etree.Comment 825 tostring = self.etree.tostring 826 827 a = Element('a') 828 a.append(Comment('foo')) 829 self.assertEquals( 830 '<a><!--foo--></a>', 831 tostring(a)) 832 833 a[0].text = "TEST" 834 self.assertEquals( 835 '<a><!--TEST--></a>', 836 tostring(a))
837 838 # ElementTree adds whitespace around comments
839 - def test_comment_whitespace(self):
840 Element = self.etree.Element 841 Comment = self.etree.Comment 842 tostring = self.etree.tostring 843 844 a = Element('a') 845 a.append(Comment(' foo ')) 846 self.assertEquals( 847 '<a><!-- foo --></a>', 848 tostring(a))
849 850 # does not raise an exception in ElementTree
851 - def test_comment_immutable(self):
852 Element = self.etree.Element 853 Comment = self.etree.Comment 854 855 c = Comment() 856 el = Element('myel') 857 858 self.assertRaises(TypeError, c.append, el) 859 self.assertRaises(TypeError, c.insert, 0, el) 860 self.assertRaises(TypeError, c.set, "myattr", "test")
861 862 # test weird dictionary interaction leading to segfault previously
863 - def test_weird_dict_interaction(self):
864 root = self.etree.Element('root') 865 add = self.etree.ElementTree(file=StringIO('<foo>Foo</foo>')) 866 root.append(self.etree.Element('baz'))
867 868 # test passing 'None' to dump
869 - def test_dump_none(self):
870 self.assertRaises(TypeError, etree.dump, None)
871
872 - def test_prefix(self):
873 ElementTree = self.etree.ElementTree 874 875 f = StringIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 876 doc = ElementTree(file=f) 877 a = doc.getroot() 878 self.assertEquals( 879 None, 880 a.prefix) 881 self.assertEquals( 882 'foo', 883 a[0].prefix)
884
885 - def test_prefix_default_ns(self):
886 ElementTree = self.etree.ElementTree 887 888 f = StringIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 889 doc = ElementTree(file=f) 890 a = doc.getroot() 891 self.assertEquals( 892 None, 893 a.prefix) 894 self.assertEquals( 895 None, 896 a[0].prefix)
897
898 - def test_getparent(self):
899 Element = self.etree.Element 900 SubElement = self.etree.SubElement 901 902 a = Element('a') 903 b = SubElement(a, 'b') 904 c = SubElement(a, 'c') 905 d = SubElement(b, 'd') 906 self.assertEquals( 907 None, 908 a.getparent()) 909 self.assertEquals( 910 a, 911 b.getparent()) 912 self.assertEquals( 913 b.getparent(), 914 c.getparent()) 915 self.assertEquals( 916 b, 917 d.getparent())
918
919 - def test_iterchildren(self):
920 XML = self.etree.XML 921 922 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>') 923 result = [] 924 for el in root.iterchildren(): 925 result.append(el.tag) 926 self.assertEquals(['one', 'two', 'three'], result)
927
928 - def test_iterchildren_reversed(self):
929 XML = self.etree.XML 930 931 root = XML('<doc><one/><two>Two</two>Hm<three/></doc>') 932 result = [] 933 for el in root.iterchildren(reversed=True): 934 result.append(el.tag) 935 self.assertEquals(['three', 'two', 'one'], result)
936
937 - def test_iterchildren_tag(self):
938 XML = self.etree.XML 939 940 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>') 941 result = [] 942 for el in root.iterchildren(tag='two'): 943 result.append(el.text) 944 self.assertEquals(['Two', 'Bla'], result)
945
946 - def test_iterchildren_tag_reversed(self):
947 XML = self.etree.XML 948 949 root = XML('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>') 950 result = [] 951 for el in root.iterchildren(reversed=True, tag='two'): 952 result.append(el.text) 953 self.assertEquals(['Bla', 'Two'], result)
954
955 - def test_iterancestors(self):
956 Element = self.etree.Element 957 SubElement = self.etree.SubElement 958 959 a = Element('a') 960 b = SubElement(a, 'b') 961 c = SubElement(a, 'c') 962 d = SubElement(b, 'd') 963 self.assertEquals( 964 [], 965 list(a.iterancestors())) 966 self.assertEquals( 967 [a], 968 list(b.iterancestors())) 969 self.assertEquals( 970 a, 971 c.iterancestors().next()) 972 self.assertEquals( 973 [b, a], 974 list(d.iterancestors()))
975
976 - def test_iterancestors_tag(self):
977 Element = self.etree.Element 978 SubElement = self.etree.SubElement 979 980 a = Element('a') 981 b = SubElement(a, 'b') 982 c = SubElement(a, 'c') 983 d = SubElement(b, 'd') 984 self.assertEquals( 985 [a], 986 list(d.iterancestors(tag='a')))
987
988 - def test_iterdescendants(self):
989 Element = self.etree.Element 990 SubElement = self.etree.SubElement 991 992 a = Element('a') 993 b = SubElement(a, 'b') 994 c = SubElement(a, 'c') 995 d = SubElement(b, 'd') 996 e = SubElement(c, 'e') 997 998 self.assertEquals( 999 [b, d, c, e], 1000 list(a.iterdescendants())) 1001 self.assertEquals( 1002 [], 1003 list(d.iterdescendants()))
1004
1005 - def test_iterdescendants_tag(self):
1006 Element = self.etree.Element 1007 SubElement = self.etree.SubElement 1008 1009 a = Element('a') 1010 b = SubElement(a, 'b') 1011 c = SubElement(a, 'c') 1012 d = SubElement(b, 'd') 1013 e = SubElement(c, 'e') 1014 1015 self.assertEquals( 1016 [], 1017 list(a.iterdescendants('a'))) 1018 a2 = SubElement(e, 'a') 1019 self.assertEquals( 1020 [a2], 1021 list(a.iterdescendants('a'))) 1022 self.assertEquals( 1023 [a2], 1024 list(c.iterdescendants('a')))
1025
1026 - def test_getroottree(self):
1027 Element = self.etree.Element 1028 SubElement = self.etree.SubElement 1029 1030 a = Element('a') 1031 b = SubElement(a, 'b') 1032 c = SubElement(a, 'c') 1033 d = SubElement(b, 'd') 1034 self.assertEquals( 1035 a, 1036 a.getroottree().getroot()) 1037 self.assertEquals( 1038 a, 1039 b.getroottree().getroot()) 1040 self.assertEquals( 1041 a, 1042 d.getroottree().getroot())
1043
1044 - def test_getnext(self):
1045 Element = self.etree.Element 1046 SubElement = self.etree.SubElement 1047 1048 a = Element('a') 1049 b = SubElement(a, 'b') 1050 c = SubElement(a, 'c') 1051 self.assertEquals( 1052 None, 1053 a.getnext()) 1054 self.assertEquals( 1055 c, 1056 b.getnext()) 1057 self.assertEquals( 1058 None, 1059 c.getnext())
1060
1061 - def test_getprevious(self):
1062 Element = self.etree.Element 1063 SubElement = self.etree.SubElement 1064 1065 a = Element('a') 1066 b = SubElement(a, 'b') 1067 c = SubElement(a, 'c') 1068 d = SubElement(b, 'd') 1069 self.assertEquals( 1070 None, 1071 a.getprevious()) 1072 self.assertEquals( 1073 b, 1074 c.getprevious()) 1075 self.assertEquals( 1076 None, 1077 b.getprevious())
1078
1079 - def test_itersiblings(self):
1080 Element = self.etree.Element 1081 SubElement = self.etree.SubElement 1082 1083 a = Element('a') 1084 b = SubElement(a, 'b') 1085 c = SubElement(a, 'c') 1086 d = SubElement(b, 'd') 1087 self.assertEquals( 1088 [], 1089 list(a.itersiblings())) 1090 self.assertEquals( 1091 [c], 1092 list(b.itersiblings())) 1093 self.assertEquals( 1094 c, 1095 b.itersiblings().next()) 1096 self.assertEquals( 1097 [], 1098 list(c.itersiblings())) 1099 self.assertEquals( 1100 [b], 1101 list(c.itersiblings(preceding=True))) 1102 self.assertEquals( 1103 [], 1104 list(b.itersiblings(preceding=True)))
1105
1106 - def test_itersiblings_tag(self):
1107 Element = self.etree.Element 1108 SubElement = self.etree.SubElement 1109 1110 a = Element('a') 1111 b = SubElement(a, 'b') 1112 c = SubElement(a, 'c') 1113 d = SubElement(b, 'd') 1114 self.assertEquals( 1115 [], 1116 list(a.itersiblings(tag='XXX'))) 1117 self.assertEquals( 1118 [c], 1119 list(b.itersiblings(tag='c'))) 1120 self.assertEquals( 1121 [b], 1122 list(c.itersiblings(preceding=True, tag='b'))) 1123 self.assertEquals( 1124 [], 1125 list(c.itersiblings(preceding=True, tag='c')))
1126
1127 - def test_parseid(self):
1128 parseid = self.etree.parseid 1129 XML = self.etree.XML 1130 xml_text = ''' 1131 <!DOCTYPE document [ 1132 <!ELEMENT document (h1,p)*> 1133 <!ELEMENT h1 (#PCDATA)> 1134 <!ATTLIST h1 myid ID #REQUIRED> 1135 <!ELEMENT p (#PCDATA)> 1136 <!ATTLIST p someid ID #REQUIRED> 1137 ]> 1138 <document> 1139 <h1 myid="chapter1">...</h1> 1140 <p id="note1" class="note">...</p> 1141 <p>Regular paragraph.</p> 1142 <p xml:id="xmlid">XML:ID paragraph.</p> 1143 <p someid="warn1" class="warning">...</p> 1144 </document> 1145 ''' 1146 1147 tree, dic = parseid(StringIO(xml_text)) 1148 root = tree.getroot() 1149 root2 = XML(xml_text) 1150 self.assertEquals(self._writeElement(root), 1151 self._writeElement(root2)) 1152 expected = { 1153 "chapter1" : root[0], 1154 "xmlid" : root[3], 1155 "warn1" : root[4] 1156 } 1157 self.assert_("chapter1" in dic) 1158 self.assert_("warn1" in dic) 1159 self.assert_("xmlid" in dic) 1160 self._checkIDDict(dic, expected)
1161
1162 - def test_XMLDTDID(self):
1163 XMLDTDID = self.etree.XMLDTDID 1164 XML = self.etree.XML 1165 xml_text = ''' 1166 <!DOCTYPE document [ 1167 <!ELEMENT document (h1,p)*> 1168 <!ELEMENT h1 (#PCDATA)> 1169 <!ATTLIST h1 myid ID #REQUIRED> 1170 <!ELEMENT p (#PCDATA)> 1171 <!ATTLIST p someid ID #REQUIRED> 1172 ]> 1173 <document> 1174 <h1 myid="chapter1">...</h1> 1175 <p id="note1" class="note">...</p> 1176 <p>Regular paragraph.</p> 1177 <p xml:id="xmlid">XML:ID paragraph.</p> 1178 <p someid="warn1" class="warning">...</p> 1179 </document> 1180 ''' 1181 1182 root, dic = XMLDTDID(xml_text) 1183 root2 = XML(xml_text) 1184 self.assertEquals(self._writeElement(root), 1185 self._writeElement(root2)) 1186 expected = { 1187 "chapter1" : root[0], 1188 "xmlid" : root[3], 1189 "warn1" : root[4] 1190 } 1191 self.assert_("chapter1" in dic) 1192 self.assert_("warn1" in dic) 1193 self.assert_("xmlid" in dic) 1194 self._checkIDDict(dic, expected)
1195
1196 - def test_XMLDTDID_empty(self):
1197 XMLDTDID = self.etree.XMLDTDID 1198 XML = self.etree.XML 1199 xml_text = ''' 1200 <document> 1201 <h1 myid="chapter1">...</h1> 1202 <p id="note1" class="note">...</p> 1203 <p>Regular paragraph.</p> 1204 <p someid="warn1" class="warning">...</p> 1205 </document> 1206 ''' 1207 1208 root, dic = XMLDTDID(xml_text) 1209 root2 = XML(xml_text) 1210 self.assertEquals(self._writeElement(root), 1211 self._writeElement(root2)) 1212 expected = {} 1213 self._checkIDDict(dic, expected)
1214
1215 - def _checkIDDict(self, dic, expected):
1216 self.assertEquals(dic, expected) 1217 self.assertEquals(len(dic), 1218 len(expected)) 1219 self.assertEquals(sorted(dic.items()), 1220 sorted(expected.items())) 1221 self.assertEquals(sorted(dic.iteritems()), 1222 sorted(expected.iteritems())) 1223 self.assertEquals(sorted(dic.keys()), 1224 sorted(expected.keys())) 1225 self.assertEquals(sorted(dic.iterkeys()), 1226 sorted(expected.iterkeys())) 1227 self.assertEquals(sorted(dic.values()), 1228 sorted(expected.values())) 1229 self.assertEquals(sorted(dic.itervalues()), 1230 sorted(expected.itervalues()))
1231
1232 - def test_namespaces(self):
1233 etree = self.etree 1234 1235 r = {'foo': 'http://ns.infrae.com/foo'} 1236 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1237 self.assertEquals( 1238 'foo', 1239 e.prefix) 1240 self.assertEquals( 1241 '<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>', 1242 self._writeElement(e))
1243
1244 - def test_namespaces_default(self):
1245 etree = self.etree 1246 1247 r = {None: 'http://ns.infrae.com/foo'} 1248 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1249 self.assertEquals( 1250 None, 1251 e.prefix) 1252 self.assertEquals( 1253 '{http://ns.infrae.com/foo}bar', 1254 e.tag) 1255 self.assertEquals( 1256 '<bar xmlns="http://ns.infrae.com/foo"></bar>', 1257 self._writeElement(e))
1258
1259 - def test_namespaces_default_and_attr(self):
1260 etree = self.etree 1261 1262 r = {None: 'http://ns.infrae.com/foo', 1263 'hoi': 'http://ns.infrae.com/hoi'} 1264 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1265 e.set('{http://ns.infrae.com/hoi}test', 'value') 1266 self.assertEquals( 1267 '<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>', 1268 self._writeElement(e))
1269
1270 - def test_namespaces_elementtree(self):
1271 etree = self.etree 1272 r = {None: 'http://ns.infrae.com/foo', 1273 'hoi': 'http://ns.infrae.com/hoi'} 1274 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 1275 tree = etree.ElementTree(element=e) 1276 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 1277 self.assertEquals( 1278 '<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>', 1279 self._writeElement(e))
1280
1281 - def test_namespaces_default_copy_element(self):
1282 etree = self.etree 1283 1284 r = {None: 'http://ns.infrae.com/foo'} 1285 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1286 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1287 1288 e1.append(e2) 1289 1290 self.assertEquals( 1291 None, 1292 e1.prefix) 1293 self.assertEquals( 1294 None, 1295 e1[0].prefix) 1296 self.assertEquals( 1297 '{http://ns.infrae.com/foo}bar', 1298 e1.tag) 1299 self.assertEquals( 1300 '{http://ns.infrae.com/foo}bar', 1301 e1[0].tag)
1302
1303 - def test_namespaces_copy_element(self):
1304 etree = self.etree 1305 1306 r = {None: 'http://ns.infrae.com/BAR'} 1307 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 1308 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1309 1310 e1.append(e2) 1311 1312 self.assertEquals( 1313 None, 1314 e1.prefix) 1315 self.assertNotEquals( 1316 None, 1317 e2.prefix) 1318 self.assertEquals( 1319 '{http://ns.infrae.com/BAR}bar', 1320 e1.tag) 1321 self.assertEquals( 1322 '{http://ns.infrae.com/foo}bar', 1323 e2.tag)
1324
1325 - def test_namespaces_reuse_after_move(self):
1326 ns_href = "http://a.b.c" 1327 one = self.etree.fromstring( 1328 '<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href) 1329 baz = one[0][0] 1330 1331 two = self.etree.fromstring( 1332 '<root xmlns:ns="%s"/>' % ns_href) 1333 two.append(baz) 1334 del one # make sure the source document is deallocated 1335 1336 self.assertEquals('{%s}baz' % ns_href, baz.tag) 1337 self.assertEquals( 1338 '<root xmlns:ns="%s"><ns:baz/></root>' % ns_href, 1339 self.etree.tostring(two))
1340
1341 - def _test_namespaces_after_serialize(self):
1342 # FIXME: this currently fails - fix serializer.pxi! 1343 parse = self.etree.parse 1344 tostring = self.etree.tostring 1345 1346 ns_href = "http://a.b.c" 1347 one = parse( 1348 StringIO('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 1349 baz = one.getroot()[0][0] 1350 1351 print tostring(baz) 1352 parsed = parse(StringIO( tostring(baz) )).getroot() 1353 1354 self.assertEquals('{%s}baz' % ns_href, parsed.tag)
1355
1356 - def test_element_nsmap(self):
1357 etree = self.etree 1358 1359 r = {None: 'http://ns.infrae.com/foo', 1360 'hoi': 'http://ns.infrae.com/hoi'} 1361 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1362 self.assertEquals( 1363 r, 1364 e.nsmap)
1365
1366 - def test_subelement_nsmap(self):
1367 etree = self.etree 1368 1369 re = {None: 'http://ns.infrae.com/foo', 1370 'hoi': 'http://ns.infrae.com/hoi'} 1371 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 1372 1373 rs = {None: 'http://ns.infrae.com/honk', 1374 'top': 'http://ns.infrae.com/top'} 1375 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 1376 1377 r = re.copy() 1378 r.update(rs) 1379 self.assertEquals( 1380 re, 1381 e.nsmap) 1382 self.assertEquals( 1383 r, 1384 s.nsmap)
1385
1386 - def test_getiterator_filter_namespace(self):
1387 Element = self.etree.Element 1388 SubElement = self.etree.SubElement 1389 1390 a = Element('{a}a') 1391 b = SubElement(a, '{a}b') 1392 c = SubElement(a, '{a}c') 1393 d = SubElement(b, '{b}d') 1394 e = SubElement(c, '{a}e') 1395 f = SubElement(c, '{b}f') 1396 1397 self.assertEquals( 1398 [a], 1399 list(a.getiterator('{a}a'))) 1400 self.assertEquals( 1401 [], 1402 list(a.getiterator('{b}a'))) 1403 self.assertEquals( 1404 [], 1405 list(a.getiterator('a'))) 1406 self.assertEquals( 1407 [f], 1408 list(c.getiterator('{b}*'))) 1409 self.assertEquals( 1410 [d, f], 1411 list(a.getiterator('{b}*')))
1412
1413 - def test_getiterator_filter_entities(self):
1414 Element = self.etree.Element 1415 Entity = self.etree.Entity 1416 SubElement = self.etree.SubElement 1417 1418 a = Element('a') 1419 b = SubElement(a, 'b') 1420 entity_b = Entity("TEST-b") 1421 b.append(entity_b) 1422 1423 self.assertEquals( 1424 [entity_b], 1425 list(a.getiterator(Entity))) 1426 1427 entity_a = Entity("TEST-a") 1428 a.append(entity_a) 1429 1430 self.assertEquals( 1431 [entity_b, entity_a], 1432 list(a.getiterator(Entity))) 1433 1434 self.assertEquals( 1435 [entity_b], 1436 list(b.getiterator(Entity)))
1437
1438 - def test_getiterator_filter_element(self):
1439 Element = self.etree.Element 1440 Comment = self.etree.Comment 1441 PI = self.etree.PI 1442 SubElement = self.etree.SubElement 1443 1444 a = Element('a') 1445 b = SubElement(a, 'b') 1446 a.append(Comment("test")) 1447 a.append(PI("pi", "content")) 1448 c = SubElement(a, 'c') 1449 1450 self.assertEquals( 1451 [a, b, c], 1452 list(a.getiterator(Element)))
1453
1454 - def test_getiterator_filter_all_comment_pi(self):
1455 # ElementTree iterates over everything here 1456 Element = self.etree.Element 1457 Comment = self.etree.Comment 1458 PI = self.etree.PI 1459 SubElement = self.etree.SubElement 1460 1461 a = Element('a') 1462 b = SubElement(a, 'b') 1463 a.append(Comment("test")) 1464 a.append(PI("pi", "content")) 1465 c = SubElement(a, 'c') 1466 1467 self.assertEquals( 1468 [a, b, c], 1469 list(a.getiterator('*')))
1470
1471 - def test_itertext(self):
1472 # ET 1.3+ 1473 XML = self.etree.XML 1474 root = XML("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>") 1475 1476 text = list(root.itertext()) 1477 self.assertEquals(["RTEXT", "ATAIL", "CTEXT", "CTAIL"], 1478 text)
1479
1480 - def test_itertext_child(self):
1481 # ET 1.3+ 1482 XML = self.etree.XML 1483 root = XML("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>") 1484 1485 text = list(root[2].itertext()) 1486 self.assertEquals(["CTEXT"], 1487 text)
1488
1489 - def test_findall_ns(self):
1490 XML = self.etree.XML 1491 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>') 1492 self.assertEquals(len(root.findall(".//{X}b")), 2) 1493 self.assertEquals(len(root.findall(".//{X}*")), 2) 1494 self.assertEquals(len(root.findall(".//b")), 3)
1495
1496 - def test_index(self):
1497 etree = self.etree 1498 e = etree.Element('foo') 1499 for i in range(10): 1500 etree.SubElement(e, 'a%s' % i) 1501 for i in range(10): 1502 self.assertEquals( 1503 i, 1504 e.index(e[i])) 1505 self.assertEquals( 1506 3, e.index(e[3], 3)) 1507 self.assertRaises( 1508 ValueError, e.index, e[3], 4) 1509 self.assertRaises( 1510 ValueError, e.index, e[3], 0, 2) 1511 self.assertRaises( 1512 ValueError, e.index, e[8], 0, -3) 1513 self.assertRaises( 1514 ValueError, e.index, e[8], -5, -3) 1515 self.assertEquals( 1516 8, e.index(e[8], 0, -1)) 1517 self.assertEquals( 1518 8, e.index(e[8], -12, -1)) 1519 self.assertEquals( 1520 0, e.index(e[0], -12, -1))
1521
1522 - def test_replace(self):
1523 etree = self.etree 1524 e = etree.Element('foo') 1525 for i in range(10): 1526 el = etree.SubElement(e, 'a%s' % i) 1527 el.text = "text%d" % i 1528 el.tail = "tail%d" % i 1529 1530 child0 = e[0] 1531 child1 = e[1] 1532 child2 = e[2] 1533 1534 e.replace(e[0], e[1]) 1535 self.assertEquals( 1536 9, len(e)) 1537 self.assertEquals( 1538 child1, e[0]) 1539 self.assertEquals( 1540 child1.text, "text1") 1541 self.assertEquals( 1542 child1.tail, "tail1") 1543 self.assertEquals( 1544 child0.tail, "tail0") 1545 self.assertEquals( 1546 child2, e[1]) 1547 1548 e.replace(e[-1], e[0]) 1549 self.assertEquals( 1550 child1, e[-1]) 1551 self.assertEquals( 1552 child1.text, "text1") 1553 self.assertEquals( 1554 child1.tail, "tail1") 1555 self.assertEquals( 1556 child2, e[0])
1557
1558 - def test_replace_new(self):
1559 etree = self.etree 1560 e = etree.Element('foo') 1561 for i in range(10): 1562 etree.SubElement(e, 'a%s' % i) 1563 1564 new_element = etree.Element("test") 1565 new_element.text = "TESTTEXT" 1566 new_element.tail = "TESTTAIL" 1567 child1 = e[1] 1568 e.replace(e[0], new_element) 1569 self.assertEquals( 1570 new_element, e[0]) 1571 self.assertEquals( 1572 "TESTTEXT", 1573 e[0].text) 1574 self.assertEquals( 1575 "TESTTAIL", 1576 e[0].tail) 1577 self.assertEquals( 1578 child1, e[1])
1579
1580 - def test_setslice_all_empty_reversed(self):
1581 Element = self.etree.Element 1582 SubElement = self.etree.SubElement 1583 1584 a = Element('a') 1585 1586 e = Element('e') 1587 f = Element('f') 1588 g = Element('g') 1589 1590 s = [e, f, g] 1591 a[::-1] = s 1592 self.assertEquals( 1593 [g, f, e], 1594 list(a))
1595
1596 - def test_setslice_step(self):
1597 Element = self.etree.Element 1598 SubElement = self.etree.SubElement 1599 1600 a = Element('a') 1601 b = SubElement(a, 'b') 1602 c = SubElement(a, 'c') 1603 d = SubElement(a, 'd') 1604 e = SubElement(a, 'e') 1605 1606 x = Element('x') 1607 y = Element('y') 1608 1609 a[1::2] = [x, y] 1610 self.assertEquals( 1611 [b, x, d, y], 1612 list(a))
1613
1614 - def test_setslice_step_negative(self):
1615 Element = self.etree.Element 1616 SubElement = self.etree.SubElement 1617 1618 a = Element('a') 1619 b = SubElement(a, 'b') 1620 c = SubElement(a, 'c') 1621 d = SubElement(a, 'd') 1622 e = SubElement(a, 'e') 1623 1624 x = Element('x') 1625 y = Element('y') 1626 1627 a[1::-1] = [x, y] 1628 self.assertEquals( 1629 [y, x, d, e], 1630 list(a))
1631
1632 - def test_setslice_step_negative2(self):
1633 Element = self.etree.Element 1634 SubElement = self.etree.SubElement 1635 1636 a = Element('a') 1637 b = SubElement(a, 'b') 1638 c = SubElement(a, 'c') 1639 d = SubElement(a, 'd') 1640 e = SubElement(a, 'e') 1641 1642 x = Element('x') 1643 y = Element('y') 1644 1645 a[::-2] = [x, y] 1646 self.assertEquals( 1647 [b, y, d, x], 1648 list(a))
1649
1650 - def test_setslice_step_overrun(self):
1651 Element = self.etree.Element 1652 SubElement = self.etree.SubElement 1653 try: 1654 slice 1655 except NameError: 1656 print "slice() not found" 1657 return 1658 1659 a = Element('a') 1660 b = SubElement(a, 'b') 1661 c = SubElement(a, 'c') 1662 d = SubElement(a, 'd') 1663 e = SubElement(a, 'e') 1664 1665 x = Element('x') 1666 y = Element('y') 1667 z = Element('z') 1668 1669 self.assertRaises( 1670 ValueError, 1671 operator.setitem, a, slice(1,None,2), [x, y, z]) 1672 1673 self.assertEquals( 1674 [b, c, d, e], 1675 list(a))
1676
1677 - def test_extend(self):
1678 etree = self.etree 1679 root = etree.Element('foo') 1680 for i in range(3): 1681 element = etree.SubElement(root, 'a%s' % i) 1682 element.text = "text%d" % i 1683 element.tail = "tail%d" % i 1684 1685 elements = [] 1686 for i in range(3): 1687 new_element = etree.Element("test%s" % i) 1688 new_element.text = "TEXT%s" % i 1689 new_element.tail = "TAIL%s" % i 1690 elements.append(new_element) 1691 1692 root.extend(elements) 1693 1694 self.assertEquals( 1695 ["a0", "a1", "a2", "test0", "test1", "test2"], 1696 [ el.tag for el in root ]) 1697 self.assertEquals( 1698 ["text0", "text1", "text2", "TEXT0", "TEXT1", "TEXT2"], 1699 [ el.text for el in root ]) 1700 self.assertEquals( 1701 ["tail0", "tail1", "tail2", "TAIL0", "TAIL1", "TAIL2"], 1702 [ el.tail for el in root ])
1703
1704 - def test_sourceline_XML(self):
1705 XML = self.etree.XML 1706 root = XML('''<?xml version="1.0"?> 1707 <root><test> 1708 1709 <bla/></test> 1710 </root> 1711 ''') 1712 1713 self.assertEquals( 1714 [2, 2, 4], 1715 [ el.sourceline for el in root.getiterator() ])
1716
1717 - def test_sourceline_parse(self):
1718 parse = self.etree.parse 1719 tree = parse(fileInTestDir('include/test_xinclude.xml')) 1720 1721 self.assertEquals( 1722 [1, 2, 3], 1723 [ el.sourceline for el in tree.getiterator() ])
1724
1725 - def test_sourceline_iterparse_end(self):
1726 iterparse = self.etree.iterparse 1727 lines = list( 1728 el.sourceline for (event, el) in 1729 iterparse(fileInTestDir('include/test_xinclude.xml'))) 1730 1731 self.assertEquals( 1732 [2, 3, 1], 1733 lines)
1734
1735 - def test_sourceline_iterparse_start(self):
1736 iterparse = self.etree.iterparse 1737 lines = list( 1738 el.sourceline for (event, el) in 1739 iterparse(fileInTestDir('include/test_xinclude.xml'), 1740 events=("start",))) 1741 1742 self.assertEquals( 1743 [1, 2, 3], 1744 lines)
1745
1746 - def test_sourceline_element(self):
1747 Element = self.etree.Element 1748 SubElement = self.etree.SubElement 1749 el = Element("test") 1750 self.assertEquals(None, el.sourceline) 1751 1752 child = SubElement(el, "test") 1753 self.assertEquals(None, el.sourceline) 1754 self.assertEquals(None, child.sourceline)
1755
1756 - def test_XML_base_url_docinfo(self):
1757 etree = self.etree 1758 root = etree.XML("<root/>", base_url="http://no/such/url") 1759 docinfo = root.getroottree().docinfo 1760 self.assertEquals(docinfo.URL, "http://no/such/url")
1761
1762 - def test_HTML_base_url_docinfo(self):
1763 etree = self.etree 1764 root = etree.HTML("<html/>", base_url="http://no/such/url") 1765 docinfo = root.getroottree().docinfo 1766 self.assertEquals(docinfo.URL, "http://no/such/url")
1767
1768 - def test_docinfo_public(self):
1769 etree = self.etree 1770 xml_header = '<?xml version="1.0" encoding="ascii"?>' 1771 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 1772 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 1773 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 1774 1775 xml = xml_header + doctype_string + '<html><body></body></html>' 1776 1777 tree = etree.parse(StringIO(xml)) 1778 docinfo = tree.docinfo 1779 self.assertEquals(docinfo.encoding, "ascii") 1780 self.assertEquals(docinfo.xml_version, "1.0") 1781 self.assertEquals(docinfo.public_id, pub_id) 1782 self.assertEquals(docinfo.system_url, sys_id) 1783 self.assertEquals(docinfo.root_name, 'html') 1784 self.assertEquals(docinfo.doctype, doctype_string)
1785
1786 - def test_docinfo_system(self):
1787 etree = self.etree 1788 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 1789 sys_id = "some.dtd" 1790 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 1791 xml = xml_header + doctype_string + '<html><body></body></html>' 1792 1793 tree = etree.parse(StringIO(xml)) 1794 docinfo = tree.docinfo 1795 self.assertEquals(docinfo.encoding, "UTF-8") 1796 self.assertEquals(docinfo.xml_version, "1.0") 1797 self.assertEquals(docinfo.public_id, None) 1798 self.assertEquals(docinfo.system_url, sys_id) 1799 self.assertEquals(docinfo.root_name, 'html') 1800 self.assertEquals(docinfo.doctype, doctype_string)
1801
1802 - def test_docinfo_empty(self):
1803 etree = self.etree 1804 xml = '<html><body></body></html>' 1805 tree = etree.parse(StringIO(xml)) 1806 docinfo = tree.docinfo 1807 self.assertEquals(docinfo.encoding, None) 1808 self.assertEquals(docinfo.xml_version, "1.0") 1809 self.assertEquals(docinfo.public_id, None) 1810 self.assertEquals(docinfo.system_url, None) 1811 self.assertEquals(docinfo.root_name, 'html') 1812 self.assertEquals(docinfo.doctype, '')
1813
1814 - def test_dtd_io(self):
1815 # check that DTDs that go in also go back out 1816 xml = '''\ 1817 <!DOCTYPE test SYSTEM "test.dtd" [ 1818 <!ENTITY entity "tasty"> 1819 <!ELEMENT test (a)> 1820 <!ELEMENT a (#PCDATA)> 1821 ]> 1822 <test><a>test-test</a></test>\ 1823 ''' 1824 tree = self.etree.parse(StringIO(xml)) 1825 self.assertEqual(self.etree.tostring(tree).replace(" ", ""), 1826 xml.replace(" ", ""))
1827
1828 - def test_byte_zero(self):
1829 Element = self.etree.Element 1830 1831 a = Element('a') 1832 self.assertRaises(AssertionError, setattr, a, "text", 'ha\0ho') 1833 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\0ho') 1834 1835 self.assertRaises(AssertionError, Element, 'ha\0ho')
1836
1837 - def test_unicode_byte_zero(self):
1838 Element = self.etree.Element 1839 1840 a = Element('a') 1841 self.assertRaises(AssertionError, setattr, a, "text", u'ha\0ho') 1842 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\0ho') 1843 1844 self.assertRaises(AssertionError, Element, u'ha\0ho')
1845
1846 - def test_byte_invalid(self):
1847 Element = self.etree.Element 1848 1849 a = Element('a') 1850 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x07ho') 1851 self.assertRaises(AssertionError, setattr, a, "text", 'ha\x02ho') 1852 1853 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x07ho') 1854 self.assertRaises(AssertionError, setattr, a, "tail", 'ha\x02ho') 1855 1856 self.assertRaises(AssertionError, Element, 'ha\x07ho') 1857 self.assertRaises(AssertionError, Element, 'ha\x02ho')
1858
1859 - def test_unicode_byte_invalid(self):
1860 Element = self.etree.Element 1861 1862 a = Element('a') 1863 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x07ho') 1864 self.assertRaises(AssertionError, setattr, a, "text", u'ha\x02ho') 1865 1866 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x07ho') 1867 self.assertRaises(AssertionError, setattr, a, "tail", u'ha\x02ho') 1868 1869 self.assertRaises(AssertionError, Element, u'ha\x07ho') 1870 self.assertRaises(AssertionError, Element, u'ha\x02ho')
1871
1872 - def test_encoding_tostring_utf16(self):
1873 # ElementTree fails to serialize this 1874 tostring = self.etree.tostring 1875 Element = self.etree.Element 1876 SubElement = self.etree.SubElement 1877 1878 a = Element('a') 1879 b = SubElement(a, 'b') 1880 c = SubElement(a, 'c') 1881 1882 result = unicode(tostring(a, encoding='UTF-16'), 'UTF-16') 1883 self.assertEquals('<a><b></b><c></c></a>', 1884 canonicalize(result))
1885
1886 - def test_tostring_none(self):
1887 # ElementTree raises an AssertionError here 1888 tostring = self.etree.tostring 1889 self.assertRaises(TypeError, self.etree.tostring, None)
1890
1891 - def test_tostring_pretty(self):
1892 tostring = self.etree.tostring 1893 Element = self.etree.Element 1894 SubElement = self.etree.SubElement 1895 1896 a = Element('a') 1897 b = SubElement(a, 'b') 1898 c = SubElement(a, 'c') 1899 1900 result = tostring(a) 1901 self.assertEquals(result, "<a><b/><c/></a>") 1902 1903 result = tostring(a, pretty_print=False) 1904 self.assertEquals(result, "<a><b/><c/></a>") 1905 1906 result = tostring(a, pretty_print=True) 1907 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
1908
1909 - def test_tostring_method_text_encoding(self):
1910 tostring = self.etree.tostring 1911 Element = self.etree.Element 1912 SubElement = self.etree.SubElement 1913 1914 a = Element('a') 1915 a.text = "A" 1916 a.tail = "tail" 1917 b = SubElement(a, 'b') 1918 b.text = "B" 1919 b.tail = u"Søk på nettet" 1920 c = SubElement(a, 'c') 1921 c.text = "C" 1922 1923 result = tostring(a, method="text", encoding="UTF-16") 1924 1925 self.assertEquals(u'ABSøk på nettetCtail'.encode("UTF-16"), 1926 result)
1927
1928 - def test_tounicode(self):
1929 tounicode = self.etree.tounicode 1930 Element = self.etree.Element 1931 SubElement = self.etree.SubElement 1932 1933 a = Element('a') 1934 b = SubElement(a, 'b') 1935 c = SubElement(a, 'c') 1936 1937 self.assert_(isinstance(tounicode(a), unicode)) 1938 self.assertEquals('<a><b></b><c></c></a>', 1939 canonicalize(tounicode(a)))
1940
1941 - def test_tounicode_element(self):
1942 tounicode = self.etree.tounicode 1943 Element = self.etree.Element 1944 SubElement = self.etree.SubElement 1945 1946 a = Element('a') 1947 b = SubElement(a, 'b') 1948 c = SubElement(a, 'c') 1949 d = SubElement(c, 'd') 1950 self.assert_(isinstance(tounicode(b), unicode)) 1951 self.assert_(isinstance(tounicode(c), unicode)) 1952 self.assertEquals('<b></b>', 1953 canonicalize(tounicode(b))) 1954 self.assertEquals('<c><d></d></c>', 1955 canonicalize(tounicode(c)))
1956
1957 - def test_tounicode_none(self):
1958 tounicode = self.etree.tounicode 1959 self.assertRaises(TypeError, self.etree.tounicode, None)
1960
1961 - def test_tounicode_element_tail(self):
1962 tounicode = self.etree.tounicode 1963 Element = self.etree.Element 1964 SubElement = self.etree.SubElement 1965 1966 a = Element('a') 1967 b = SubElement(a, 'b') 1968 c = SubElement(a, 'c') 1969 d = SubElement(c, 'd') 1970 b.tail = 'Foo' 1971 1972 self.assert_(isinstance(tounicode(b), unicode)) 1973 self.assert_(tounicode(b) == '<b/>Foo' or 1974 tounicode(b) == '<b />Foo')
1975
1976 - def test_tounicode_pretty(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 1985 result = tounicode(a) 1986 self.assertEquals(result, "<a><b/><c/></a>") 1987 1988 result = tounicode(a, pretty_print=False) 1989 self.assertEquals(result, "<a><b/><c/></a>") 1990 1991 result = tounicode(a, pretty_print=True) 1992 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
1993
1994 - def _writeElement(self, element, encoding='us-ascii'):
1995 """Write out element for comparison. 1996 """ 1997 ElementTree = self.etree.ElementTree 1998 f = StringIO() 1999 tree = ElementTree(element=element) 2000 tree.write(f, encoding=encoding) 2001 data = f.getvalue() 2002 return canonicalize(data)
2003 2004
2005 -class XIncludeTestCase(HelperTestCase):
2006 - def test_xinclude_text(self):
2007 filename = fileInTestDir('test_broken.xml') 2008 root = etree.XML('''\ 2009 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 2010 <xi:include href="%s" parse="text"/> 2011 </doc> 2012 ''' % filename) 2013 old_text = root.text 2014 content = open(filename).read() 2015 old_tail = root[0].tail 2016 2017 self.include( etree.ElementTree(root) ) 2018 self.assertEquals(old_text + content + old_tail, 2019 root.text)
2020
2021 - def test_xinclude(self):
2022 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 2023 self.assertNotEquals( 2024 'a', 2025 tree.getroot()[1].tag) 2026 # process xincludes 2027 self.include( tree ) 2028 # check whether we find it replaced with included data 2029 self.assertEquals( 2030 'a', 2031 tree.getroot()[1].tag)
2032
2033 -class ETreeXIncludeTestCase(XIncludeTestCase):
2034 - def include(self, tree):
2035 tree.xinclude()
2036 2037
2038 -class ElementIncludeTestCase(XIncludeTestCase):
2039 from lxml import ElementInclude
2040 - def include(self, tree):
2041 self.ElementInclude.include(tree.getroot())
2042 2043
2044 -class ETreeC14NTestCase(HelperTestCase):
2045 - def test_c14n(self):
2046 tree = self.parse('<a><b/></a>') 2047 f = StringIO() 2048 tree.write_c14n(f) 2049 s = f.getvalue() 2050 self.assertEquals('<a><b></b></a>', 2051 s)
2052
2053 -def test_suite():
2054 suite = unittest.TestSuite() 2055 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 2056 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 2057 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 2058 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 2059 suite.addTests( 2060 [doctest.DocFileSuite('../../../doc/tutorial.txt')]) 2061 suite.addTests( 2062 [doctest.DocFileSuite('../../../doc/api.txt')]) 2063 suite.addTests( 2064 [doctest.DocFileSuite('../../../doc/parsing.txt')]) 2065 suite.addTests( 2066 [doctest.DocFileSuite('../../../doc/resolvers.txt')]) 2067 return suite
2068 2069 if __name__ == '__main__': 2070 print 'to test use test.py %s' % __file__ 2071