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