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, tempfile 
  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
158 # ET doesn't have namespace/localname properties on QNames 159 QName = self.etree.QName 160 namespace, localname = 'http://myns', 'a' 161 qname = QName(namespace, localname) 162 self.assertEquals(namespace, qname.namespace) 163 self.assertEquals(localname, qname.localname)
164
165 - def test_qname_element(self):
166 # ET doesn't have namespace/localname properties on QNames 167 QName = self.etree.QName 168 qname1 = QName('http://myns', 'a') 169 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'}) 170 171 qname2 = QName(a) 172 self.assertEquals(a.tag, qname1.text) 173 self.assertEquals(qname1.text, qname2.text) 174 self.assertEquals(qname1, qname2)
175
176 - def test_qname_text_resolve(self):
177 # ET doesn't resove QNames as text values 178 etree = self.etree 179 qname = etree.QName('http://myns', 'a') 180 a = etree.Element(qname, nsmap={'p' : 'http://myns'}) 181 a.text = qname 182 183 self.assertEquals("p:a", a.text)
184
185 - def test_nsmap_prefix_invalid(self):
186 etree = self.etree 187 self.assertRaises(ValueError, 188 etree.Element, "root", nsmap={'"' : 'testns'}) 189 self.assertRaises(ValueError, 190 etree.Element, "root", nsmap={'&' : 'testns'}) 191 self.assertRaises(ValueError, 192 etree.Element, "root", nsmap={'a:b' : 'testns'})
193
194 - def test_attribute_set(self):
195 Element = self.etree.Element 196 root = Element("root") 197 root.set("attr", "TEST") 198 self.assertEquals("TEST", root.get("attr"))
199
200 - def test_attribute_set_invalid(self):
201 # ElementTree accepts arbitrary attribute values 202 # lxml.etree allows only strings 203 Element = self.etree.Element 204 root = Element("root") 205 self.assertRaises(TypeError, root.set, "newattr", 5) 206 self.assertRaises(TypeError, root.set, "newattr", None)
207
208 - def test_pi(self):
209 # lxml.etree separates target and text 210 Element = self.etree.Element 211 SubElement = self.etree.SubElement 212 ProcessingInstruction = self.etree.ProcessingInstruction 213 214 a = Element('a') 215 a.append(ProcessingInstruction('foo', 'some more text')) 216 self.assertEquals(a[0].target, 'foo') 217 self.assertEquals(a[0].text, 'some more text')
218
219 - def test_pi_parse(self):
220 XML = self.etree.XML 221 root = XML(_bytes("<test><?mypi my test ?></test>")) 222 self.assertEquals(root[0].target, "mypi") 223 self.assertEquals(root[0].text, "my test ")
224
225 - def test_deepcopy_pi(self):
226 # previously caused a crash 227 ProcessingInstruction = self.etree.ProcessingInstruction 228 229 a = ProcessingInstruction("PI", "ONE") 230 b = copy.deepcopy(a) 231 b.text = "ANOTHER" 232 233 self.assertEquals('ONE', a.text) 234 self.assertEquals('ANOTHER', b.text)
235
236 - def test_attribute_set(self):
237 # ElementTree accepts arbitrary attribute values 238 # lxml.etree allows only strings 239 Element = self.etree.Element 240 241 root = Element("root") 242 root.set("attr", "TEST") 243 self.assertEquals("TEST", root.get("attr")) 244 self.assertRaises(TypeError, root.set, "newattr", 5)
245
246 - def test_parse_remove_comments(self):
247 fromstring = self.etree.fromstring 248 tostring = self.etree.tostring 249 XMLParser = self.etree.XMLParser 250 251 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 252 parser = XMLParser(remove_comments=True) 253 root = fromstring(xml, parser) 254 self.assertEquals( 255 _bytes('<a><b><c/></b></a>'), 256 tostring(root))
257
258 - def test_parse_remove_pis(self):
259 parse = self.etree.parse 260 tostring = self.etree.tostring 261 XMLParser = self.etree.XMLParser 262 263 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>') 264 265 f = BytesIO(xml) 266 tree = parse(f) 267 self.assertEquals( 268 xml, 269 tostring(tree)) 270 271 parser = XMLParser(remove_pis=True) 272 tree = parse(f, parser) 273 self.assertEquals( 274 _bytes('<a><b><c/></b></a>'), 275 tostring(tree))
276
278 # ET raises IOError only 279 parse = self.etree.parse 280 self.assertRaises(TypeError, parse, 'notthere.xml', object())
281
282 - def test_parse_error_logging(self):
283 parse = self.etree.parse 284 f = BytesIO('<a><b></c></b></a>') 285 self.etree.clear_error_log() 286 try: 287 parse(f) 288 logs = None 289 except SyntaxError: 290 e = sys.exc_info()[1] 291 logs = e.error_log 292 f.close() 293 self.assert_([ log for log in logs 294 if 'mismatch' in log.message ]) 295 self.assert_([ log for log in logs 296 if 'PARSER' in log.domain_name]) 297 self.assert_([ log for log in logs 298 if 'TAG_NAME_MISMATCH' in log.type_name ]) 299 self.assert_([ log for log in logs 300 if 1 == log.line ]) 301 self.assert_([ log for log in logs 302 if 15 == log.column ])
303
305 # ET removes comments 306 iterparse = self.etree.iterparse 307 tostring = self.etree.tostring 308 309 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 310 events = list(iterparse(f)) 311 root = events[-1][1] 312 self.assertEquals(3, len(events)) 313 self.assertEquals( 314 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 315 tostring(root))
316
317 - def test_iterparse_comments(self):
318 # ET removes comments 319 iterparse = self.etree.iterparse 320 tostring = self.etree.tostring 321 322 def name(event, el): 323 if event == 'comment': 324 return el.text 325 else: 326 return el.tag
327 328 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 329 events = list(iterparse(f, events=('end', 'comment'))) 330 root = events[-1][1] 331 self.assertEquals(6, len(events)) 332 self.assertEquals(['A', ' B ', 'c', 'b', 'C', 'a'], 333 [ name(*item) for item in events ]) 334 self.assertEquals( 335 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 336 tostring(root))
337
338 - def test_iterparse_pis(self):
339 # ET removes pis 340 iterparse = self.etree.iterparse 341 tostring = self.etree.tostring 342 ElementTree = self.etree.ElementTree 343 344 def name(event, el): 345 if event == 'pi': 346 return (el.target, el.text) 347 else: 348 return el.tag
349 350 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>') 351 events = list(iterparse(f, events=('end', 'pi'))) 352 root = events[-2][1] 353 self.assertEquals(8, len(events)) 354 self.assertEquals([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b', 355 ('pid','d'), 'a', ('pie','e')], 356 [ name(*item) for item in events ]) 357 self.assertEquals( 358 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'), 359 tostring(ElementTree(root))) 360
361 - def test_iterparse_remove_comments(self):
362 iterparse = self.etree.iterparse 363 tostring = self.etree.tostring 364 365 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 366 events = list(iterparse(f, remove_comments=True, 367 events=('end', 'comment'))) 368 root = events[-1][1] 369 self.assertEquals(3, len(events)) 370 self.assertEquals(['c', 'b', 'a'], 371 [ el.tag for (event, el) in events ]) 372 self.assertEquals( 373 _bytes('<a><b><c/></b></a>'), 374 tostring(root))
375
376 - def test_iterparse_broken(self):
377 iterparse = self.etree.iterparse 378 f = BytesIO('<a><b><c/></a>') 379 # ET raises ExpatError, lxml raises XMLSyntaxError 380 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
381
382 - def test_iterparse_strip(self):
383 iterparse = self.etree.iterparse 384 f = BytesIO(""" 385 <a> \n \n <b> b test </b> \n 386 387 \n\t <c> \n </c> </a> \n """) 388 iterator = iterparse(f, remove_blank_text=True) 389 text = [ (element.text, element.tail) 390 for event, element in iterator ] 391 self.assertEquals( 392 [(" b test ", None), (" \n ", None), (None, None)], 393 text)
394
395 - def test_iterparse_tag(self):
396 iterparse = self.etree.iterparse 397 f = BytesIO('<a><b><d/></b><c/></a>') 398 399 iterator = iterparse(f, tag="b", events=('start', 'end')) 400 events = list(iterator) 401 root = iterator.root 402 self.assertEquals( 403 [('start', root[0]), ('end', root[0])], 404 events)
405
406 - def test_iterparse_tag_all(self):
407 iterparse = self.etree.iterparse 408 f = BytesIO('<a><b><d/></b><c/></a>') 409 410 iterator = iterparse(f, tag="*", events=('start', 'end')) 411 events = list(iterator) 412 self.assertEquals( 413 8, 414 len(events))
415
416 - def test_iterparse_encoding_error(self):
417 text = _str('Søk på nettet') 418 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 419 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 420 ).encode('iso-8859-1') 421 422 self.assertRaises(self.etree.ParseError, 423 list, self.etree.iterparse(BytesIO(xml_latin1)))
424
425 - def test_iterparse_encoding_8bit_override(self):
426 text = _str('Søk på nettet', encoding="UTF-8") 427 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 428 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 429 ).encode('iso-8859-1') 430 431 iterator = self.etree.iterparse(BytesIO(xml_latin1), 432 encoding="iso-8859-1") 433 self.assertEquals(1, len(list(iterator))) 434 435 a = iterator.root 436 self.assertEquals(a.text, text)
437
438 - def test_iterparse_keep_cdata(self):
439 tostring = self.etree.tostring 440 f = BytesIO('<root><![CDATA[test]]></root>') 441 context = self.etree.iterparse(f, strip_cdata=False) 442 content = [ el.text for event,el in context ] 443 444 self.assertEquals(['test'], content) 445 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 446 tostring(context.root))
447
448 - def test_parser_encoding_unknown(self):
449 self.assertRaises( 450 LookupError, self.etree.XMLParser, encoding="hopefully unknown")
451
452 - def test_parser_encoding(self):
453 self.etree.XMLParser(encoding="ascii") 454 self.etree.XMLParser(encoding="utf-8") 455 self.etree.XMLParser(encoding="iso-8859-1")
456
457 - def test_elementtree_parser_target_type_error(self):
458 assertEquals = self.assertEquals 459 assertFalse = self.assertFalse 460 461 events = [] 462 class Target(object): 463 def start(self, tag, attrib): 464 events.append("start") 465 assertFalse(attrib) 466 assertEquals("TAG", tag)
467 def end(self, tag): 468 events.append("end") 469 assertEquals("TAG", tag) 470 def close(self): 471 return "DONE" # no Element! 472 473 parser = self.etree.XMLParser(target=Target()) 474 tree = self.etree.ElementTree() 475 476 self.assertRaises(TypeError, 477 tree.parse, BytesIO("<TAG/>"), parser=parser) 478 self.assertEquals(["start", "end"], events) 479
480 - def test_parser_target_comment(self):
481 events = [] 482 class Target(object): 483 def start(self, tag, attrib): 484 events.append("start-" + tag)
485 def end(self, tag): 486 events.append("end-" + tag) 487 def data(self, data): 488 events.append("data-" + data) 489 def comment(self, text): 490 events.append("comment-" + text) 491 def close(self): 492 return "DONE" 493 494 parser = self.etree.XMLParser(target=Target()) 495 496 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')) 497 done = parser.close() 498 499 self.assertEquals("DONE", done) 500 self.assertEquals(["comment-a", "start-root", "data-A", "comment-b", 501 "start-sub", "end-sub", "comment-c", "data-B", 502 "end-root", "comment-d"], 503 events) 504
505 - def test_parser_target_pi(self):
506 events = [] 507 class Target(object): 508 def start(self, tag, attrib): 509 events.append("start-" + tag)
510 def end(self, tag): 511 events.append("end-" + tag) 512 def data(self, data): 513 events.append("data-" + data) 514 def pi(self, target, data): 515 events.append("pi-" + target + "-" + data) 516 def close(self): 517 return "DONE" 518 519 parser = self.etree.XMLParser(target=Target()) 520 521 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>')) 522 done = parser.close() 523 524 self.assertEquals("DONE", done) 525 self.assertEquals(["pi-test-a", "start-root", "data-A", "pi-test-b", 526 "data-B", "end-root", "pi-test-c"], 527 events) 528
529 - def test_parser_target_cdata(self):
530 events = [] 531 class Target(object): 532 def start(self, tag, attrib): 533 events.append("start-" + tag)
534 def end(self, tag): 535 events.append("end-" + tag) 536 def data(self, data): 537 events.append("data-" + data) 538 def close(self): 539 return "DONE" 540 541 parser = self.etree.XMLParser(target=Target(), 542 strip_cdata=False) 543 544 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>')) 545 done = parser.close() 546 547 self.assertEquals("DONE", done) 548 self.assertEquals(["start-root", "data-A", "start-a", 549 "data-ca", "end-a", "data-B", "end-root"], 550 events) 551
552 - def test_parser_target_recover(self):
553 events = [] 554 class Target(object): 555 def start(self, tag, attrib): 556 events.append("start-" + tag)
557 def end(self, tag): 558 events.append("end-" + tag) 559 def data(self, data): 560 events.append("data-" + data) 561 def close(self): 562 events.append("close") 563 return "DONE" 564 565 parser = self.etree.XMLParser(target=Target(), 566 recover=True) 567 568 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>')) 569 done = parser.close() 570 571 self.assertEquals("DONE", done) 572 self.assertEquals(["start-root", "data-A", "start-a", 573 "data-ca", "end-a", "data-B", 574 "end-root", "close"], 575 events) 576
577 - def test_iterwalk_tag(self):
578 iterwalk = self.etree.iterwalk 579 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 580 581 iterator = iterwalk(root, tag="b", events=('start', 'end')) 582 events = list(iterator) 583 self.assertEquals( 584 [('start', root[0]), ('end', root[0])], 585 events)
586
587 - def test_iterwalk_tag_all(self):
588 iterwalk = self.etree.iterwalk 589 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 590 591 iterator = iterwalk(root, tag="*", events=('start', 'end')) 592 events = list(iterator) 593 self.assertEquals( 594 8, 595 len(events))
596
597 - def test_iterwalk(self):
598 iterwalk = self.etree.iterwalk 599 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 600 601 events = list(iterwalk(root)) 602 self.assertEquals( 603 [('end', root[0]), ('end', root[1]), ('end', root)], 604 events)
605
606 - def test_iterwalk_start(self):
607 iterwalk = self.etree.iterwalk 608 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 609 610 iterator = iterwalk(root, events=('start',)) 611 events = list(iterator) 612 self.assertEquals( 613 [('start', root), ('start', root[0]), ('start', root[1])], 614 events)
615
616 - def test_iterwalk_start_end(self):
617 iterwalk = self.etree.iterwalk 618 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 619 620 iterator = iterwalk(root, events=('start','end')) 621 events = list(iterator) 622 self.assertEquals( 623 [('start', root), ('start', root[0]), ('end', root[0]), 624 ('start', root[1]), ('end', root[1]), ('end', root)], 625 events)
626
627 - def test_iterwalk_clear(self):
628 iterwalk = self.etree.iterwalk 629 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 630 631 iterator = iterwalk(root) 632 for event, elem in iterator: 633 elem.clear() 634 635 self.assertEquals(0, 636 len(root))
637
638 - def test_iterwalk_attrib_ns(self):
639 iterwalk = self.etree.iterwalk 640 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')) 641 642 attr_name = '{testns}bla' 643 events = [] 644 iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 645 for event, elem in iterator: 646 events.append(event) 647 if event == 'start': 648 if elem.tag != '{ns1}a': 649 elem.set(attr_name, 'value') 650 651 self.assertEquals( 652 ['start-ns', 'start', 'start', 'start-ns', 'start', 653 'end', 'end-ns', 'end', 'end', 'end-ns'], 654 events) 655 656 self.assertEquals( 657 None, 658 root.get(attr_name)) 659 self.assertEquals( 660 'value', 661 root[0].get(attr_name))
662
663 - def test_iterwalk_getiterator(self):
664 iterwalk = self.etree.iterwalk 665 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 666 667 counts = [] 668 for event, elem in iterwalk(root): 669 counts.append(len(list(elem.getiterator()))) 670 self.assertEquals( 671 [1,2,1,4], 672 counts)
673
674 - def test_resolve_string_dtd(self):
675 parse = self.etree.parse 676 parser = self.etree.XMLParser(dtd_validation=True) 677 assertEqual = self.assertEqual 678 test_url = _str("__nosuch.dtd") 679 680 class MyResolver(self.etree.Resolver): 681 def resolve(self, url, id, context): 682 assertEqual(url, test_url) 683 return self.resolve_string( 684 _str('''<!ENTITY myentity "%s"> 685 <!ELEMENT doc ANY>''') % url, context)
686 687 parser.resolvers.add(MyResolver()) 688 689 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 690 tree = parse(StringIO(xml), parser) 691 root = tree.getroot() 692 self.assertEquals(root.text, test_url) 693
694 - def test_resolve_bytes_dtd(self):
695 parse = self.etree.parse 696 parser = self.etree.XMLParser(dtd_validation=True) 697 assertEqual = self.assertEqual 698 test_url = _str("__nosuch.dtd") 699 700 class MyResolver(self.etree.Resolver): 701 def resolve(self, url, id, context): 702 assertEqual(url, test_url) 703 return self.resolve_string( 704 (_str('''<!ENTITY myentity "%s"> 705 <!ELEMENT doc ANY>''') % url).encode('utf-8'), 706 context)
707 708 parser.resolvers.add(MyResolver()) 709 710 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 711 tree = parse(StringIO(xml), parser) 712 root = tree.getroot() 713 self.assertEquals(root.text, test_url) 714
715 - def test_resolve_filelike_dtd(self):
716 parse = self.etree.parse 717 parser = self.etree.XMLParser(dtd_validation=True) 718 assertEqual = self.assertEqual 719 test_url = _str("__nosuch.dtd") 720 721 class MyResolver(self.etree.Resolver): 722 def resolve(self, url, id, context): 723 assertEqual(url, test_url) 724 return self.resolve_file( 725 SillyFileLike( 726 _str('''<!ENTITY myentity "%s"> 727 <!ELEMENT doc ANY>''') % url), context)
728 729 parser.resolvers.add(MyResolver()) 730 731 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 732 tree = parse(StringIO(xml), parser) 733 root = tree.getroot() 734 self.assertEquals(root.text, test_url) 735
736 - def test_resolve_filename_dtd(self):
737 parse = self.etree.parse 738 parser = self.etree.XMLParser(attribute_defaults=True) 739 assertEqual = self.assertEqual 740 test_url = _str("__nosuch.dtd") 741 742 class MyResolver(self.etree.Resolver): 743 def resolve(self, url, id, context): 744 assertEqual(url, test_url) 745 return self.resolve_filename( 746 fileInTestDir('test.dtd'), context)
747 748 parser.resolvers.add(MyResolver()) 749 750 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 751 tree = parse(StringIO(xml), parser) 752 root = tree.getroot() 753 self.assertEquals( 754 root.attrib, {'default': 'valueA'}) 755 self.assertEquals( 756 root[0].attrib, {'default': 'valueB'}) 757
758 - def test_resolve_filename_dtd_relative(self):
759 parse = self.etree.parse 760 parser = self.etree.XMLParser(attribute_defaults=True) 761 assertEqual = self.assertEqual 762 test_url = _str("__nosuch.dtd") 763 764 class MyResolver(self.etree.Resolver): 765 def resolve(self, url, id, context): 766 assertEqual(url, fileInTestDir(test_url)) 767 return self.resolve_filename( 768 fileInTestDir('test.dtd'), context)
769 770 parser.resolvers.add(MyResolver()) 771 772 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 773 tree = parse(StringIO(xml), parser, 774 base_url=fileInTestDir('__test.xml')) 775 root = tree.getroot() 776 self.assertEquals( 777 root.attrib, {'default': 'valueA'}) 778 self.assertEquals( 779 root[0].attrib, {'default': 'valueB'}) 780
781 - def test_resolve_file_dtd(self):
782 parse = self.etree.parse 783 parser = self.etree.XMLParser(attribute_defaults=True) 784 assertEqual = self.assertEqual 785 test_url = _str("__nosuch.dtd") 786 787 class MyResolver(self.etree.Resolver): 788 def resolve(self, url, id, context): 789 assertEqual(url, test_url) 790 return self.resolve_file( 791 open(fileInTestDir('test.dtd'), 'rb'), context)
792 793 parser.resolvers.add(MyResolver()) 794 795 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 796 tree = parse(StringIO(xml), parser) 797 root = tree.getroot() 798 self.assertEquals( 799 root.attrib, {'default': 'valueA'}) 800 self.assertEquals( 801 root[0].attrib, {'default': 'valueB'}) 802
803 - def test_resolve_empty(self):
804 parse = self.etree.parse 805 parser = self.etree.XMLParser(load_dtd=True) 806 assertEqual = self.assertEqual 807 test_url = _str("__nosuch.dtd") 808 809 class check(object): 810 resolved = False
811 812 class MyResolver(self.etree.Resolver): 813 def resolve(self, url, id, context): 814 assertEqual(url, test_url) 815 check.resolved = True 816 return self.resolve_empty(context) 817 818 parser.resolvers.add(MyResolver()) 819 820 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 821 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 822 self.assert_(check.resolved) 823
824 - def test_resolve_error(self):
825 parse = self.etree.parse 826 parser = self.etree.XMLParser(dtd_validation=True) 827 828 class _LocalException(Exception): 829 pass
830 831 class MyResolver(self.etree.Resolver): 832 def resolve(self, url, id, context): 833 raise _LocalException 834 835 parser.resolvers.add(MyResolver()) 836 837 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 838 self.assertRaises(_LocalException, parse, BytesIO(xml), parser) 839 840 if etree.LIBXML_VERSION > (2,6,20):
841 - def test_entity_parse(self):
842 parse = self.etree.parse 843 tostring = self.etree.tostring 844 parser = self.etree.XMLParser(resolve_entities=False) 845 Entity = self.etree.Entity 846 847 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 848 tree = parse(BytesIO(xml), parser) 849 root = tree.getroot() 850 self.assertEquals(root[0].tag, Entity) 851 self.assertEquals(root[0].text, "&myentity;") 852 self.assertEquals(root[0].tail, None) 853 self.assertEquals(root[0].name, "myentity") 854 855 self.assertEquals(_bytes('<doc>&myentity;</doc>'), 856 tostring(root))
857
858 - def test_entity_append(self):
859 Entity = self.etree.Entity 860 Element = self.etree.Element 861 tostring = self.etree.tostring 862 863 root = Element("root") 864 root.append( Entity("test") ) 865 866 self.assertEquals(root[0].tag, Entity) 867 self.assertEquals(root[0].text, "&test;") 868 self.assertEquals(root[0].tail, None) 869 self.assertEquals(root[0].name, "test") 870 871 self.assertEquals(_bytes('<root>&test;</root>'), 872 tostring(root))
873
874 - def test_entity_values(self):
875 Entity = self.etree.Entity 876 self.assertEquals(Entity("test").text, '&test;') 877 self.assertEquals(Entity("#17683").text, '&#17683;') 878 self.assertEquals(Entity("#x1768").text, '&#x1768;') 879 self.assertEquals(Entity("#x98AF").text, '&#x98AF;')
880
881 - def test_entity_error(self):
882 Entity = self.etree.Entity 883 self.assertRaises(ValueError, Entity, 'a b c') 884 self.assertRaises(ValueError, Entity, 'a,b') 885 self.assertRaises(ValueError, Entity, 'a\0b') 886 self.assertRaises(ValueError, Entity, '#abc') 887 self.assertRaises(ValueError, Entity, '#xxyz')
888
889 - def test_cdata(self):
890 CDATA = self.etree.CDATA 891 Element = self.etree.Element 892 tostring = self.etree.tostring 893 894 root = Element("root") 895 root.text = CDATA('test') 896 897 self.assertEquals('test', 898 root.text) 899 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 900 tostring(root))
901
902 - def test_cdata_type(self):
903 CDATA = self.etree.CDATA 904 Element = self.etree.Element 905 root = Element("root") 906 907 root.text = CDATA("test") 908 self.assertEquals('test', root.text) 909 910 root.text = CDATA(_str("test")) 911 self.assertEquals('test', root.text) 912 913 self.assertRaises(TypeError, CDATA, 1)
914
915 - def test_cdata_errors(self):
916 CDATA = self.etree.CDATA 917 Element = self.etree.Element 918 919 root = Element("root") 920 cdata = CDATA('test') 921 922 self.assertRaises(TypeError, 923 setattr, root, 'tail', cdata) 924 self.assertRaises(TypeError, 925 root.set, 'attr', cdata) 926 self.assertRaises(TypeError, 927 operator.setitem, root.attrib, 'attr', cdata)
928
929 - def test_cdata_parser(self):
930 tostring = self.etree.tostring 931 parser = self.etree.XMLParser(strip_cdata=False) 932 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 933 934 self.assertEquals('test', root.text) 935 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 936 tostring(root))
937 938 # TypeError in etree, AssertionError in ElementTree;
939 - def test_setitem_assert(self):
940 Element = self.etree.Element 941 SubElement = self.etree.SubElement 942 943 a = Element('a') 944 b = SubElement(a, 'b') 945 946 self.assertRaises(TypeError, 947 a.__setitem__, 0, 'foo')
948
949 - def test_append_None(self):
950 # raises AssertionError in ElementTree 951 Element = self.etree.Element 952 self.assertRaises(TypeError, Element('a').append, None)
953
954 - def test_addnext(self):
955 Element = self.etree.Element 956 SubElement = self.etree.SubElement 957 root = Element('root') 958 SubElement(root, 'a') 959 SubElement(root, 'b') 960 961 self.assertEquals(['a', 'b'], 962 [c.tag for c in root]) 963 root[1].addnext(root[0]) 964 self.assertEquals(['b', 'a'], 965 [c.tag for c in root])
966
967 - def test_addprevious(self):
968 Element = self.etree.Element 969 SubElement = self.etree.SubElement 970 root = Element('root') 971 SubElement(root, 'a') 972 SubElement(root, 'b') 973 974 self.assertEquals(['a', 'b'], 975 [c.tag for c in root]) 976 root[0].addprevious(root[1]) 977 self.assertEquals(['b', 'a'], 978 [c.tag for c in root])
979
980 - def test_addnext_root(self):
981 Element = self.etree.Element 982 a = Element('a') 983 b = Element('b') 984 self.assertRaises(TypeError, a.addnext, b)
985
986 - def test_addnext_root(self):
987 Element = self.etree.Element 988 a = Element('a') 989 b = Element('b') 990 self.assertRaises(TypeError, a.addnext, b)
991
992 - def test_addprevious_pi(self):
993 Element = self.etree.Element 994 SubElement = self.etree.SubElement 995 PI = self.etree.PI 996 root = Element('root') 997 SubElement(root, 'a') 998 pi = PI('TARGET', 'TEXT') 999 pi.tail = "TAIL" 1000 1001 self.assertEquals(_bytes('<root><a></a></root>'), 1002 self._writeElement(root)) 1003 root[0].addprevious(pi) 1004 self.assertEquals(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 1005 self._writeElement(root))
1006
1007 - def test_addprevious_root_pi(self):
1008 Element = self.etree.Element 1009 PI = self.etree.PI 1010 root = Element('root') 1011 pi = PI('TARGET', 'TEXT') 1012 pi.tail = "TAIL" 1013 1014 self.assertEquals(_bytes('<root></root>'), 1015 self._writeElement(root)) 1016 root.addprevious(pi) 1017 self.assertEquals(_bytes('<?TARGET TEXT?>\n<root></root>'), 1018 self._writeElement(root))
1019
1020 - def test_addnext_pi(self):
1021 Element = self.etree.Element 1022 SubElement = self.etree.SubElement 1023 PI = self.etree.PI 1024 root = Element('root') 1025 SubElement(root, 'a') 1026 pi = PI('TARGET', 'TEXT') 1027 pi.tail = "TAIL" 1028 1029 self.assertEquals(_bytes('<root><a></a></root>'), 1030 self._writeElement(root)) 1031 root[0].addnext(pi) 1032 self.assertEquals(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 1033 self._writeElement(root))
1034
1035 - def test_addnext_root_pi(self):
1036 Element = self.etree.Element 1037 PI = self.etree.PI 1038 root = Element('root') 1039 pi = PI('TARGET', 'TEXT') 1040 pi.tail = "TAIL" 1041 1042 self.assertEquals(_bytes('<root></root>'), 1043 self._writeElement(root)) 1044 root.addnext(pi) 1045 self.assertEquals(_bytes('<root></root>\n<?TARGET TEXT?>'), 1046 self._writeElement(root))
1047
1048 - def test_addnext_comment(self):
1049 Element = self.etree.Element 1050 SubElement = self.etree.SubElement 1051 Comment = self.etree.Comment 1052 root = Element('root') 1053 SubElement(root, 'a') 1054 comment = Comment('TEXT ') 1055 comment.tail = "TAIL" 1056 1057 self.assertEquals(_bytes('<root><a></a></root>'), 1058 self._writeElement(root)) 1059 root[0].addnext(comment) 1060 self.assertEquals(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 1061 self._writeElement(root))
1062
1063 - def test_addnext_root_comment(self):
1064 Element = self.etree.Element 1065 Comment = self.etree.Comment 1066 root = Element('root') 1067 comment = Comment('TEXT ') 1068 comment.tail = "TAIL" 1069 1070 self.assertEquals(_bytes('<root></root>'), 1071 self._writeElement(root)) 1072 root.addnext(comment) 1073 self.assertEquals(_bytes('<root></root>\n<!--TEXT -->'), 1074 self._writeElement(root))
1075
1076 - def test_addprevious_comment(self):
1077 Element = self.etree.Element 1078 SubElement = self.etree.SubElement 1079 Comment = self.etree.Comment 1080 root = Element('root') 1081 SubElement(root, 'a') 1082 comment = Comment('TEXT ') 1083 comment.tail = "TAIL" 1084 1085 self.assertEquals(_bytes('<root><a></a></root>'), 1086 self._writeElement(root)) 1087 root[0].addprevious(comment) 1088 self.assertEquals(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 1089 self._writeElement(root))
1090
1091 - def test_addprevious_root_comment(self):
1092 Element = self.etree.Element 1093 Comment = self.etree.Comment 1094 root = Element('root') 1095 comment = Comment('TEXT ') 1096 comment.tail = "TAIL" 1097 1098 self.assertEquals(_bytes('<root></root>'), 1099 self._writeElement(root)) 1100 root.addprevious(comment) 1101 self.assertEquals(_bytes('<!--TEXT -->\n<root></root>'), 1102 self._writeElement(root))
1103 1104 # ET's Elements have items() and key(), but not values()
1105 - def test_attribute_values(self):
1106 XML = self.etree.XML 1107 1108 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 1109 values = root.values() 1110 values.sort() 1111 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
1112 1113 # gives error in ElementTree
1114 - def test_comment_empty(self):
1115 Element = self.etree.Element 1116 Comment = self.etree.Comment 1117 1118 a = Element('a') 1119 a.append(Comment()) 1120 self.assertEquals( 1121 _bytes('<a><!----></a>'), 1122 self._writeElement(a))
1123 1124 # ElementTree ignores comments
1125 - def test_comment_parse_empty(self):
1126 ElementTree = self.etree.ElementTree 1127 tostring = self.etree.tostring 1128 1129 xml = _bytes('<a><b/><!----><c/></a>') 1130 f = BytesIO(xml) 1131 doc = ElementTree(file=f) 1132 a = doc.getroot() 1133 self.assertEquals( 1134 '', 1135 a[1].text) 1136 self.assertEquals( 1137 xml, 1138 tostring(a))
1139 1140 # ElementTree ignores comments
1141 - def test_comment_no_proxy_yet(self):
1142 ElementTree = self.etree.ElementTree 1143 1144 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 1145 doc = ElementTree(file=f) 1146 a = doc.getroot() 1147 self.assertEquals( 1148 ' hoi ', 1149 a[1].text)
1150 1151 # does not raise an exception in ElementTree
1152 - def test_comment_immutable(self):
1153 Element = self.etree.Element 1154 Comment = self.etree.Comment 1155 1156 c = Comment() 1157 el = Element('myel') 1158 1159 self.assertRaises(TypeError, c.append, el) 1160 self.assertRaises(TypeError, c.insert, 0, el) 1161 self.assertRaises(TypeError, c.set, "myattr", "test")
1162 1163 # test passing 'None' to dump
1164 - def test_dump_none(self):
1165 self.assertRaises(TypeError, self.etree.dump, None)
1166
1167 - def test_prefix(self):
1168 ElementTree = self.etree.ElementTree 1169 1170 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 1171 doc = ElementTree(file=f) 1172 a = doc.getroot() 1173 self.assertEquals( 1174 None, 1175 a.prefix) 1176 self.assertEquals( 1177 'foo', 1178 a[0].prefix)
1179
1180 - def test_prefix_default_ns(self):
1181 ElementTree = self.etree.ElementTree 1182 1183 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 1184 doc = ElementTree(file=f) 1185 a = doc.getroot() 1186 self.assertEquals( 1187 None, 1188 a.prefix) 1189 self.assertEquals( 1190 None, 1191 a[0].prefix)
1192
1193 - def test_getparent(self):
1194 Element = self.etree.Element 1195 SubElement = self.etree.SubElement 1196 1197 a = Element('a') 1198 b = SubElement(a, 'b') 1199 c = SubElement(a, 'c') 1200 d = SubElement(b, 'd') 1201 self.assertEquals( 1202 None, 1203 a.getparent()) 1204 self.assertEquals( 1205 a, 1206 b.getparent()) 1207 self.assertEquals( 1208 b.getparent(), 1209 c.getparent()) 1210 self.assertEquals( 1211 b, 1212 d.getparent())
1213
1214 - def test_iterchildren(self):
1215 XML = self.etree.XML 1216 1217 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1218 result = [] 1219 for el in root.iterchildren(): 1220 result.append(el.tag) 1221 self.assertEquals(['one', 'two', 'three'], result)
1222
1223 - def test_iterchildren_reversed(self):
1224 XML = self.etree.XML 1225 1226 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1227 result = [] 1228 for el in root.iterchildren(reversed=True): 1229 result.append(el.tag) 1230 self.assertEquals(['three', 'two', 'one'], result)
1231
1232 - def test_iterchildren_tag(self):
1233 XML = self.etree.XML 1234 1235 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1236 result = [] 1237 for el in root.iterchildren(tag='two'): 1238 result.append(el.text) 1239 self.assertEquals(['Two', 'Bla'], result)
1240
1241 - def test_iterchildren_tag_reversed(self):
1242 XML = self.etree.XML 1243 1244 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1245 result = [] 1246 for el in root.iterchildren(reversed=True, tag='two'): 1247 result.append(el.text) 1248 self.assertEquals(['Bla', 'Two'], result)
1249
1250 - def test_iterancestors(self):
1251 Element = self.etree.Element 1252 SubElement = self.etree.SubElement 1253 1254 a = Element('a') 1255 b = SubElement(a, 'b') 1256 c = SubElement(a, 'c') 1257 d = SubElement(b, 'd') 1258 self.assertEquals( 1259 [], 1260 list(a.iterancestors())) 1261 self.assertEquals( 1262 [a], 1263 list(b.iterancestors())) 1264 self.assertEquals( 1265 [a], 1266 list(c.iterancestors())) 1267 self.assertEquals( 1268 [b, a], 1269 list(d.iterancestors()))
1270
1271 - def test_iterancestors_tag(self):
1272 Element = self.etree.Element 1273 SubElement = self.etree.SubElement 1274 1275 a = Element('a') 1276 b = SubElement(a, 'b') 1277 c = SubElement(a, 'c') 1278 d = SubElement(b, 'd') 1279 self.assertEquals( 1280 [a], 1281 list(d.iterancestors(tag='a')))
1282
1283 - def test_iterdescendants(self):
1284 Element = self.etree.Element 1285 SubElement = self.etree.SubElement 1286 1287 a = Element('a') 1288 b = SubElement(a, 'b') 1289 c = SubElement(a, 'c') 1290 d = SubElement(b, 'd') 1291 e = SubElement(c, 'e') 1292 1293 self.assertEquals( 1294 [b, d, c, e], 1295 list(a.iterdescendants())) 1296 self.assertEquals( 1297 [], 1298 list(d.iterdescendants()))
1299
1300 - def test_iterdescendants_tag(self):
1301 Element = self.etree.Element 1302 SubElement = self.etree.SubElement 1303 1304 a = Element('a') 1305 b = SubElement(a, 'b') 1306 c = SubElement(a, 'c') 1307 d = SubElement(b, 'd') 1308 e = SubElement(c, 'e') 1309 1310 self.assertEquals( 1311 [], 1312 list(a.iterdescendants('a'))) 1313 a2 = SubElement(e, 'a') 1314 self.assertEquals( 1315 [a2], 1316 list(a.iterdescendants('a'))) 1317 self.assertEquals( 1318 [a2], 1319 list(c.iterdescendants('a')))
1320
1321 - def test_getroottree(self):
1322 Element = self.etree.Element 1323 SubElement = self.etree.SubElement 1324 1325 a = Element('a') 1326 b = SubElement(a, 'b') 1327 c = SubElement(a, 'c') 1328 d = SubElement(b, 'd') 1329 self.assertEquals( 1330 a, 1331 a.getroottree().getroot()) 1332 self.assertEquals( 1333 a, 1334 b.getroottree().getroot()) 1335 self.assertEquals( 1336 a, 1337 d.getroottree().getroot())
1338
1339 - def test_getnext(self):
1340 Element = self.etree.Element 1341 SubElement = self.etree.SubElement 1342 1343 a = Element('a') 1344 b = SubElement(a, 'b') 1345 c = SubElement(a, 'c') 1346 self.assertEquals( 1347 None, 1348 a.getnext()) 1349 self.assertEquals( 1350 c, 1351 b.getnext()) 1352 self.assertEquals( 1353 None, 1354 c.getnext())
1355
1356 - def test_getprevious(self):
1357 Element = self.etree.Element 1358 SubElement = self.etree.SubElement 1359 1360 a = Element('a') 1361 b = SubElement(a, 'b') 1362 c = SubElement(a, 'c') 1363 d = SubElement(b, 'd') 1364 self.assertEquals( 1365 None, 1366 a.getprevious()) 1367 self.assertEquals( 1368 b, 1369 c.getprevious()) 1370 self.assertEquals( 1371 None, 1372 b.getprevious())
1373
1374 - def test_itersiblings(self):
1375 Element = self.etree.Element 1376 SubElement = self.etree.SubElement 1377 1378 a = Element('a') 1379 b = SubElement(a, 'b') 1380 c = SubElement(a, 'c') 1381 d = SubElement(b, 'd') 1382 self.assertEquals( 1383 [], 1384 list(a.itersiblings())) 1385 self.assertEquals( 1386 [c], 1387 list(b.itersiblings())) 1388 self.assertEquals( 1389 [], 1390 list(c.itersiblings())) 1391 self.assertEquals( 1392 [b], 1393 list(c.itersiblings(preceding=True))) 1394 self.assertEquals( 1395 [], 1396 list(b.itersiblings(preceding=True)))
1397
1398 - def test_itersiblings_tag(self):
1399 Element = self.etree.Element 1400 SubElement = self.etree.SubElement 1401 1402 a = Element('a') 1403 b = SubElement(a, 'b') 1404 c = SubElement(a, 'c') 1405 d = SubElement(b, 'd') 1406 self.assertEquals( 1407 [], 1408 list(a.itersiblings(tag='XXX'))) 1409 self.assertEquals( 1410 [c], 1411 list(b.itersiblings(tag='c'))) 1412 self.assertEquals( 1413 [b], 1414 list(c.itersiblings(preceding=True, tag='b'))) 1415 self.assertEquals( 1416 [], 1417 list(c.itersiblings(preceding=True, tag='c')))
1418
1419 - def test_parseid(self):
1420 parseid = self.etree.parseid 1421 XML = self.etree.XML 1422 xml_text = _bytes(''' 1423 <!DOCTYPE document [ 1424 <!ELEMENT document (h1,p)*> 1425 <!ELEMENT h1 (#PCDATA)> 1426 <!ATTLIST h1 myid ID #REQUIRED> 1427 <!ELEMENT p (#PCDATA)> 1428 <!ATTLIST p someid ID #REQUIRED> 1429 ]> 1430 <document> 1431 <h1 myid="chapter1">...</h1> 1432 <p id="note1" class="note">...</p> 1433 <p>Regular paragraph.</p> 1434 <p xml:id="xmlid">XML:ID paragraph.</p> 1435 <p someid="warn1" class="warning">...</p> 1436 </document> 1437 ''') 1438 1439 tree, dic = parseid(BytesIO(xml_text)) 1440 root = tree.getroot() 1441 root2 = XML(xml_text) 1442 self.assertEquals(self._writeElement(root), 1443 self._writeElement(root2)) 1444 expected = { 1445 "chapter1" : root[0], 1446 "xmlid" : root[3], 1447 "warn1" : root[4] 1448 } 1449 self.assert_("chapter1" in dic) 1450 self.assert_("warn1" in dic) 1451 self.assert_("xmlid" in dic) 1452 self._checkIDDict(dic, expected)
1453
1454 - def test_XMLDTDID(self):
1455 XMLDTDID = self.etree.XMLDTDID 1456 XML = self.etree.XML 1457 xml_text = _bytes(''' 1458 <!DOCTYPE document [ 1459 <!ELEMENT document (h1,p)*> 1460 <!ELEMENT h1 (#PCDATA)> 1461 <!ATTLIST h1 myid ID #REQUIRED> 1462 <!ELEMENT p (#PCDATA)> 1463 <!ATTLIST p someid ID #REQUIRED> 1464 ]> 1465 <document> 1466 <h1 myid="chapter1">...</h1> 1467 <p id="note1" class="note">...</p> 1468 <p>Regular paragraph.</p> 1469 <p xml:id="xmlid">XML:ID paragraph.</p> 1470 <p someid="warn1" class="warning">...</p> 1471 </document> 1472 ''') 1473 1474 root, dic = XMLDTDID(xml_text) 1475 root2 = XML(xml_text) 1476 self.assertEquals(self._writeElement(root), 1477 self._writeElement(root2)) 1478 expected = { 1479 "chapter1" : root[0], 1480 "xmlid" : root[3], 1481 "warn1" : root[4] 1482 } 1483 self.assert_("chapter1" in dic) 1484 self.assert_("warn1" in dic) 1485 self.assert_("xmlid" in dic) 1486 self._checkIDDict(dic, expected)
1487
1488 - def test_XMLDTDID_empty(self):
1489 XMLDTDID = self.etree.XMLDTDID 1490 XML = self.etree.XML 1491 xml_text = _bytes(''' 1492 <document> 1493 <h1 myid="chapter1">...</h1> 1494 <p id="note1" class="note">...</p> 1495 <p>Regular paragraph.</p> 1496 <p someid="warn1" class="warning">...</p> 1497 </document> 1498 ''') 1499 1500 root, dic = XMLDTDID(xml_text) 1501 root2 = XML(xml_text) 1502 self.assertEquals(self._writeElement(root), 1503 self._writeElement(root2)) 1504 expected = {} 1505 self._checkIDDict(dic, expected)
1506
1507 - def _checkIDDict(self, dic, expected):
1508 self.assertEquals(len(dic), 1509 len(expected)) 1510 self.assertEquals(sorted(dic.items()), 1511 sorted(expected.items())) 1512 if sys.version_info < (3,): 1513 self.assertEquals(sorted(dic.iteritems()), 1514 sorted(expected.iteritems())) 1515 self.assertEquals(sorted(dic.keys()), 1516 sorted(expected.keys())) 1517 if sys.version_info < (3,): 1518 self.assertEquals(sorted(dic.iterkeys()), 1519 sorted(expected.iterkeys())) 1520 if sys.version_info < (3,): 1521 self.assertEquals(sorted(dic.values()), 1522 sorted(expected.values())) 1523 self.assertEquals(sorted(dic.itervalues()), 1524 sorted(expected.itervalues()))
1525
1526 - def test_namespaces(self):
1527 etree = self.etree 1528 1529 r = {'foo': 'http://ns.infrae.com/foo'} 1530 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1531 self.assertEquals( 1532 'foo', 1533 e.prefix) 1534 self.assertEquals( 1535 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 1536 self._writeElement(e))
1537
1538 - def test_namespaces_default(self):
1539 etree = self.etree 1540 1541 r = {None: 'http://ns.infrae.com/foo'} 1542 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1543 self.assertEquals( 1544 None, 1545 e.prefix) 1546 self.assertEquals( 1547 '{http://ns.infrae.com/foo}bar', 1548 e.tag) 1549 self.assertEquals( 1550 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 1551 self._writeElement(e))
1552
1553 - def test_namespaces_default_and_attr(self):
1554 etree = self.etree 1555 1556 r = {None: 'http://ns.infrae.com/foo', 1557 'hoi': 'http://ns.infrae.com/hoi'} 1558 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1559 e.set('{http://ns.infrae.com/hoi}test', 'value') 1560 self.assertEquals( 1561 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 1562 self._writeElement(e))
1563
1564 - def test_namespaces_elementtree(self):
1565 etree = self.etree 1566 r = {None: 'http://ns.infrae.com/foo', 1567 'hoi': 'http://ns.infrae.com/hoi'} 1568 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 1569 tree = etree.ElementTree(element=e) 1570 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 1571 self.assertEquals( 1572 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 1573 self._writeElement(e))
1574
1575 - def test_namespaces_default_copy_element(self):
1576 etree = self.etree 1577 1578 r = {None: 'http://ns.infrae.com/foo'} 1579 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1580 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1581 1582 e1.append(e2) 1583 1584 self.assertEquals( 1585 None, 1586 e1.prefix) 1587 self.assertEquals( 1588 None, 1589 e1[0].prefix) 1590 self.assertEquals( 1591 '{http://ns.infrae.com/foo}bar', 1592 e1.tag) 1593 self.assertEquals( 1594 '{http://ns.infrae.com/foo}bar', 1595 e1[0].tag)
1596
1597 - def test_namespaces_copy_element(self):
1598 etree = self.etree 1599 1600 r = {None: 'http://ns.infrae.com/BAR'} 1601 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 1602 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1603 1604 e1.append(e2) 1605 1606 self.assertEquals( 1607 None, 1608 e1.prefix) 1609 self.assertNotEquals( 1610 None, 1611 e2.prefix) 1612 self.assertEquals( 1613 '{http://ns.infrae.com/BAR}bar', 1614 e1.tag) 1615 self.assertEquals( 1616 '{http://ns.infrae.com/foo}bar', 1617 e2.tag)
1618
1619 - def test_namespaces_reuse_after_move(self):
1620 ns_href = "http://a.b.c" 1621 one = self.etree.fromstring( 1622 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 1623 baz = one[0][0] 1624 1625 two = self.etree.fromstring( 1626 _bytes('<root xmlns:ns="%s"/>' % ns_href)) 1627 two.append(baz) 1628 del one # make sure the source document is deallocated 1629 1630 self.assertEquals('{%s}baz' % ns_href, baz.tag) 1631 self.assertEquals( 1632 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 1633 self.etree.tostring(two))
1634
1635 - def test_namespace_cleanup(self):
1636 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>') 1637 root = self.etree.fromstring(xml) 1638 self.assertEquals(xml, 1639 self.etree.tostring(root)) 1640 self.etree.cleanup_namespaces(root) 1641 self.assertEquals( 1642 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 1643 self.etree.tostring(root))
1644
1645 - def test_element_nsmap(self):
1646 etree = self.etree 1647 1648 r = {None: 'http://ns.infrae.com/foo', 1649 'hoi': 'http://ns.infrae.com/hoi'} 1650 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1651 self.assertEquals( 1652 r, 1653 e.nsmap)
1654
1655 - def test_subelement_nsmap(self):
1656 etree = self.etree 1657 1658 re = {None: 'http://ns.infrae.com/foo', 1659 'hoi': 'http://ns.infrae.com/hoi'} 1660 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 1661 1662 rs = {None: 'http://ns.infrae.com/honk', 1663 'top': 'http://ns.infrae.com/top'} 1664 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 1665 1666 r = re.copy() 1667 r.update(rs) 1668 self.assertEquals( 1669 re, 1670 e.nsmap) 1671 self.assertEquals( 1672 r, 1673 s.nsmap)
1674
1675 - def test_getiterator_filter_namespace(self):
1676 Element = self.etree.Element 1677 SubElement = self.etree.SubElement 1678 1679 a = Element('{a}a') 1680 b = SubElement(a, '{a}b') 1681 c = SubElement(a, '{a}c') 1682 d = SubElement(b, '{b}d') 1683 e = SubElement(c, '{a}e') 1684 f = SubElement(c, '{b}f') 1685 1686 self.assertEquals( 1687 [a], 1688 list(a.getiterator('{a}a'))) 1689 self.assertEquals( 1690 [], 1691 list(a.getiterator('{b}a'))) 1692 self.assertEquals( 1693 [], 1694 list(a.getiterator('a'))) 1695 self.assertEquals( 1696 [f], 1697 list(c.getiterator('{b}*'))) 1698 self.assertEquals( 1699 [d, f], 1700 list(a.getiterator('{b}*')))
1701
1702 - def test_getiterator_filter_entities(self):
1703 Element = self.etree.Element 1704 Entity = self.etree.Entity 1705 SubElement = self.etree.SubElement 1706 1707 a = Element('a') 1708 b = SubElement(a, 'b') 1709 entity_b = Entity("TEST-b") 1710 b.append(entity_b) 1711 1712 self.assertEquals( 1713 [entity_b], 1714 list(a.getiterator(Entity))) 1715 1716 entity_a = Entity("TEST-a") 1717 a.append(entity_a) 1718 1719 self.assertEquals( 1720 [entity_b, entity_a], 1721 list(a.getiterator(Entity))) 1722 1723 self.assertEquals( 1724 [entity_b], 1725 list(b.getiterator(Entity)))
1726
1727 - def test_getiterator_filter_element(self):
1728 Element = self.etree.Element 1729 Comment = self.etree.Comment 1730 PI = self.etree.PI 1731 SubElement = self.etree.SubElement 1732 1733 a = Element('a') 1734 b = SubElement(a, 'b') 1735 a.append(Comment("test")) 1736 a.append(PI("pi", "content")) 1737 c = SubElement(a, 'c') 1738 1739 self.assertEquals( 1740 [a, b, c], 1741 list(a.getiterator(Element)))
1742
1743 - def test_getiterator_filter_all_comment_pi(self):
1744 # ElementTree iterates over everything here 1745 Element = self.etree.Element 1746 Comment = self.etree.Comment 1747 PI = self.etree.PI 1748 SubElement = self.etree.SubElement 1749 1750 a = Element('a') 1751 b = SubElement(a, 'b') 1752 a.append(Comment("test")) 1753 a.append(PI("pi", "content")) 1754 c = SubElement(a, 'c') 1755 1756 self.assertEquals( 1757 [a, b, c], 1758 list(a.getiterator('*')))
1759
1760 - def test_elementtree_find_qname(self):
1761 XML = self.etree.XML 1762 ElementTree = self.etree.ElementTree 1763 QName = self.etree.QName 1764 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 1765 self.assertEquals(tree.find(QName("c")), tree.getroot()[2])
1766
1767 - def test_elementtree_findall_qname(self):
1768 XML = self.etree.XML 1769 ElementTree = self.etree.ElementTree 1770 QName = self.etree.QName 1771 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 1772 self.assertEquals(len(list(tree.findall(QName("c")))), 1)
1773
1774 - def test_elementtree_findall_ns_qname(self):
1775 XML = self.etree.XML 1776 ElementTree = self.etree.ElementTree 1777 QName = self.etree.QName 1778 tree = ElementTree(XML( 1779 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))) 1780 self.assertEquals(len(list(tree.findall(QName("b")))), 2) 1781 self.assertEquals(len(list(tree.findall(QName("X", "b")))), 1)
1782
1783 - def test_findall_ns(self):
1784 XML = self.etree.XML 1785 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')) 1786 self.assertEquals(len(root.findall(".//{X}b")), 2) 1787 self.assertEquals(len(root.findall(".//{X}*")), 2) 1788 self.assertEquals(len(root.findall(".//b")), 3)
1789
1790 - def test_index(self):
1791 etree = self.etree 1792 e = etree.Element('foo') 1793 for i in range(10): 1794 etree.SubElement(e, 'a%s' % i) 1795 for i in range(10): 1796 self.assertEquals( 1797 i, 1798 e.index(e[i])) 1799 self.assertEquals( 1800 3, e.index(e[3], 3)) 1801 self.assertRaises( 1802 ValueError, e.index, e[3], 4) 1803 self.assertRaises( 1804 ValueError, e.index, e[3], 0, 2) 1805 self.assertRaises( 1806 ValueError, e.index, e[8], 0, -3) 1807 self.assertRaises( 1808 ValueError, e.index, e[8], -5, -3) 1809 self.assertEquals( 1810 8, e.index(e[8], 0, -1)) 1811 self.assertEquals( 1812 8, e.index(e[8], -12, -1)) 1813 self.assertEquals( 1814 0, e.index(e[0], -12, -1))
1815
1816 - def test_replace(self):
1817 etree = self.etree 1818 e = etree.Element('foo') 1819 for i in range(10): 1820 el = etree.SubElement(e, 'a%s' % i) 1821 el.text = "text%d" % i 1822 el.tail = "tail%d" % i 1823 1824 child0 = e[0] 1825 child1 = e[1] 1826 child2 = e[2] 1827 1828 e.replace(e[0], e[1]) 1829 self.assertEquals( 1830 9, len(e)) 1831 self.assertEquals( 1832 child1, e[0]) 1833 self.assertEquals( 1834 child1.text, "text1") 1835 self.assertEquals( 1836 child1.tail, "tail1") 1837 self.assertEquals( 1838 child0.tail, "tail0") 1839 self.assertEquals( 1840 child2, e[1]) 1841 1842 e.replace(e[-1], e[0]) 1843 self.assertEquals( 1844 child1, e[-1]) 1845 self.assertEquals( 1846 child1.text, "text1") 1847 self.assertEquals( 1848 child1.tail, "tail1") 1849 self.assertEquals( 1850 child2, e[0])
1851
1852 - def test_replace_new(self):
1853 etree = self.etree 1854 e = etree.Element('foo') 1855 for i in range(10): 1856 etree.SubElement(e, 'a%s' % i) 1857 1858 new_element = etree.Element("test") 1859 new_element.text = "TESTTEXT" 1860 new_element.tail = "TESTTAIL" 1861 child1 = e[1] 1862 e.replace(e[0], new_element) 1863 self.assertEquals( 1864 new_element, e[0]) 1865 self.assertEquals( 1866 "TESTTEXT", 1867 e[0].text) 1868 self.assertEquals( 1869 "TESTTAIL", 1870 e[0].tail) 1871 self.assertEquals( 1872 child1, e[1])
1873
1874 - def test_setslice_all_empty_reversed(self):
1875 Element = self.etree.Element 1876 SubElement = self.etree.SubElement 1877 1878 a = Element('a') 1879 1880 e = Element('e') 1881 f = Element('f') 1882 g = Element('g') 1883 1884 s = [e, f, g] 1885 a[::-1] = s 1886 self.assertEquals( 1887 [g, f, e], 1888 list(a))
1889
1890 - def test_setslice_step(self):
1891 Element = self.etree.Element 1892 SubElement = self.etree.SubElement 1893 1894 a = Element('a') 1895 b = SubElement(a, 'b') 1896 c = SubElement(a, 'c') 1897 d = SubElement(a, 'd') 1898 e = SubElement(a, 'e') 1899 1900 x = Element('x') 1901 y = Element('y') 1902 1903 a[1::2] = [x, y] 1904 self.assertEquals( 1905 [b, x, d, y], 1906 list(a))
1907
1908 - def test_setslice_step_negative(self):
1909 Element = self.etree.Element 1910 SubElement = self.etree.SubElement 1911 1912 a = Element('a') 1913 b = SubElement(a, 'b') 1914 c = SubElement(a, 'c') 1915 d = SubElement(a, 'd') 1916 e = SubElement(a, 'e') 1917 1918 x = Element('x') 1919 y = Element('y') 1920 1921 a[1::-1] = [x, y] 1922 self.assertEquals( 1923 [y, x, d, e], 1924 list(a))
1925
1926 - def test_setslice_step_negative2(self):
1927 Element = self.etree.Element 1928 SubElement = self.etree.SubElement 1929 1930 a = Element('a') 1931 b = SubElement(a, 'b') 1932 c = SubElement(a, 'c') 1933 d = SubElement(a, 'd') 1934 e = SubElement(a, 'e') 1935 1936 x = Element('x') 1937 y = Element('y') 1938 1939 a[::-2] = [x, y] 1940 self.assertEquals( 1941 [b, y, d, x], 1942 list(a))
1943
1944 - def test_setslice_step_overrun(self):
1945 Element = self.etree.Element 1946 SubElement = self.etree.SubElement 1947 try: 1948 slice 1949 except NameError: 1950 print("slice() not found") 1951 return 1952 1953 a = Element('a') 1954 b = SubElement(a, 'b') 1955 c = SubElement(a, 'c') 1956 d = SubElement(a, 'd') 1957 e = SubElement(a, 'e') 1958 1959 x = Element('x') 1960 y = Element('y') 1961 z = Element('z') 1962 1963 self.assertRaises( 1964 ValueError, 1965 operator.setitem, a, slice(1,None,2), [x, y, z]) 1966 1967 self.assertEquals( 1968 [b, c, d, e], 1969 list(a))
1970
1971 - def test_sourceline_XML(self):
1972 XML = self.etree.XML 1973 root = XML(_bytes('''<?xml version="1.0"?> 1974 <root><test> 1975 1976 <bla/></test> 1977 </root> 1978 ''')) 1979 1980 self.assertEquals( 1981 [2, 2, 4], 1982 [ el.sourceline for el in root.getiterator() ])
1983
1984 - def test_sourceline_parse(self):
1985 parse = self.etree.parse 1986 tree = parse(fileInTestDir('include/test_xinclude.xml')) 1987 1988 self.assertEquals( 1989 [1, 2, 3], 1990 [ el.sourceline for el in tree.getiterator() ])
1991
1992 - def test_sourceline_iterparse_end(self):
1993 iterparse = self.etree.iterparse 1994 lines = [ el.sourceline for (event, el) in 1995 iterparse(fileInTestDir('include/test_xinclude.xml')) ] 1996 1997 self.assertEquals( 1998 [2, 3, 1], 1999 lines)
2000
2001 - def test_sourceline_iterparse_start(self):
2002 iterparse = self.etree.iterparse 2003 lines = [ el.sourceline for (event, el) in 2004 iterparse(fileInTestDir('include/test_xinclude.xml'), 2005 events=("start",)) ] 2006 2007 self.assertEquals( 2008 [1, 2, 3], 2009 lines)
2010
2011 - def test_sourceline_element(self):
2012 Element = self.etree.Element 2013 SubElement = self.etree.SubElement 2014 el = Element("test") 2015 self.assertEquals(None, el.sourceline) 2016 2017 child = SubElement(el, "test") 2018 self.assertEquals(None, el.sourceline) 2019 self.assertEquals(None, child.sourceline)
2020
2021 - def test_XML_base_url_docinfo(self):
2022 etree = self.etree 2023 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2024 docinfo = root.getroottree().docinfo 2025 self.assertEquals(docinfo.URL, "http://no/such/url")
2026
2027 - def test_XML_set_base_url_docinfo(self):
2028 etree = self.etree 2029 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2030 docinfo = root.getroottree().docinfo 2031 self.assertEquals(docinfo.URL, "http://no/such/url") 2032 docinfo.URL = "https://secret/url" 2033 self.assertEquals(docinfo.URL, "https://secret/url")
2034
2035 - def test_parse_stringio_base_url(self):
2036 etree = self.etree 2037 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url") 2038 docinfo = tree.docinfo 2039 self.assertEquals(docinfo.URL, "http://no/such/url")
2040
2041 - def test_parse_base_url_docinfo(self):
2042 etree = self.etree 2043 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 2044 base_url="http://no/such/url") 2045 docinfo = tree.docinfo 2046 self.assertEquals(docinfo.URL, "http://no/such/url")
2047
2048 - def test_HTML_base_url_docinfo(self):
2049 etree = self.etree 2050 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url") 2051 docinfo = root.getroottree().docinfo 2052 self.assertEquals(docinfo.URL, "http://no/such/url")
2053
2054 - def test_docinfo_public(self):
2055 etree = self.etree 2056 xml_header = '<?xml version="1.0" encoding="ascii"?>' 2057 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 2058 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 2059 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 2060 2061 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 2062 2063 tree = etree.parse(BytesIO(xml)) 2064 docinfo = tree.docinfo 2065 self.assertEquals(docinfo.encoding, "ascii") 2066 self.assertEquals(docinfo.xml_version, "1.0") 2067 self.assertEquals(docinfo.public_id, pub_id) 2068 self.assertEquals(docinfo.system_url, sys_id) 2069 self.assertEquals(docinfo.root_name, 'html') 2070 self.assertEquals(docinfo.doctype, doctype_string)
2071
2072 - def test_docinfo_system(self):
2073 etree = self.etree 2074 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 2075 sys_id = "some.dtd" 2076 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 2077 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 2078 2079 tree = etree.parse(BytesIO(xml)) 2080 docinfo = tree.docinfo 2081 self.assertEquals(docinfo.encoding, "UTF-8") 2082 self.assertEquals(docinfo.xml_version, "1.0") 2083 self.assertEquals(docinfo.public_id, None) 2084 self.assertEquals(docinfo.system_url, sys_id) 2085 self.assertEquals(docinfo.root_name, 'html') 2086 self.assertEquals(docinfo.doctype, doctype_string)
2087
2088 - def test_docinfo_empty(self):
2089 etree = self.etree 2090 xml = _bytes('<html><body></body></html>') 2091 tree = etree.parse(BytesIO(xml)) 2092 docinfo = tree.docinfo 2093 self.assertEquals(docinfo.encoding, "UTF-8") 2094 self.assertEquals(docinfo.xml_version, "1.0") 2095 self.assertEquals(docinfo.public_id, None) 2096 self.assertEquals(docinfo.system_url, None) 2097 self.assertEquals(docinfo.root_name, 'html') 2098 self.assertEquals(docinfo.doctype, '')
2099
2100 - def test_docinfo_name_only(self):
2101 etree = self.etree 2102 xml = _bytes('<!DOCTYPE root><root></root>') 2103 tree = etree.parse(BytesIO(xml)) 2104 docinfo = tree.docinfo 2105 self.assertEquals(docinfo.encoding, "UTF-8") 2106 self.assertEquals(docinfo.xml_version, "1.0") 2107 self.assertEquals(docinfo.public_id, None) 2108 self.assertEquals(docinfo.system_url, None) 2109 self.assertEquals(docinfo.root_name, 'root') 2110 self.assertEquals(docinfo.doctype, '<!DOCTYPE root>')
2111
2112 - def test_doctype_name_only_roundtrip(self):
2113 etree = self.etree 2114 xml = _bytes('<!DOCTYPE root>\n<root/>') 2115 tree = etree.parse(BytesIO(xml)) 2116 self.assertEquals(xml, etree.tostring(tree))
2117
2118 - def test_xml_base(self):
2119 etree = self.etree 2120 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2121 self.assertEquals(root.base, "http://no/such/url") 2122 self.assertEquals( 2123 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 2124 root.base = "https://secret/url" 2125 self.assertEquals(root.base, "https://secret/url") 2126 self.assertEquals( 2127 root.get('{http://www.w3.org/XML/1998/namespace}base'), 2128 "https://secret/url")
2129
2130 - def test_xml_base_attribute(self):
2131 etree = self.etree 2132 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2133 self.assertEquals(root.base, "http://no/such/url") 2134 self.assertEquals( 2135 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 2136 root.set('{http://www.w3.org/XML/1998/namespace}base', 2137 "https://secret/url") 2138 self.assertEquals(root.base, "https://secret/url") 2139 self.assertEquals( 2140 root.get('{http://www.w3.org/XML/1998/namespace}base'), 2141 "https://secret/url")
2142
2143 - def test_html_base(self):
2144 etree = self.etree 2145 root = etree.HTML(_bytes("<html><body></body></html>"), 2146 base_url="http://no/such/url") 2147 self.assertEquals(root.base, "http://no/such/url")
2148
2149 - def test_html_base_tag(self):
2150 etree = self.etree 2151 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 2152 self.assertEquals(root.base, "http://no/such/url")
2153
2154 - def test_parse_fileobject_unicode(self):
2155 # parse from a file object that returns unicode strings 2156 f = LargeFileLikeUnicode() 2157 tree = self.etree.parse(f) 2158 root = tree.getroot() 2159 self.assert_(root.tag.endswith('root'))
2160
2161 - def test_dtd_io(self):
2162 # check that DTDs that go in also go back out 2163 xml = _bytes('''\ 2164 <!DOCTYPE test SYSTEM "test.dtd" [ 2165 <!ENTITY entity "tasty"> 2166 <!ELEMENT test (a)> 2167 <!ELEMENT a (#PCDATA)> 2168 ]> 2169 <test><a>test-test</a></test>\ 2170 ''') 2171 tree = self.etree.parse(BytesIO(xml)) 2172 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 2173 xml.replace(_bytes(" "), _bytes("")))
2174
2175 - def test_byte_zero(self):
2176 Element = self.etree.Element 2177 2178 a = Element('a') 2179 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 2180 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 2181 2182 self.assertRaises(ValueError, Element, 'ha\0ho')
2183
2184 - def test_unicode_byte_zero(self):
2185 Element = self.etree.Element 2186 2187 a = Element('a') 2188 self.assertRaises(ValueError, setattr, a, "text", 2189 _str('ha\0ho')) 2190 self.assertRaises(ValueError, setattr, a, "tail", 2191 _str('ha\0ho')) 2192 2193 self.assertRaises(ValueError, Element, 2194 _str('ha\0ho'))
2195
2196 - def test_byte_invalid(self):
2197 Element = self.etree.Element 2198 2199 a = Element('a') 2200 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 2201 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 2202 2203 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 2204 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 2205 2206 self.assertRaises(ValueError, Element, 'ha\x07ho') 2207 self.assertRaises(ValueError, Element, 'ha\x02ho')
2208
2209 - def test_unicode_byte_invalid(self):
2210 Element = self.etree.Element 2211 2212 a = Element('a') 2213 self.assertRaises(ValueError, setattr, a, "text", 2214 _str('ha\x07ho')) 2215 self.assertRaises(ValueError, setattr, a, "text", 2216 _str('ha\x02ho')) 2217 2218 self.assertRaises(ValueError, setattr, a, "tail", 2219 _str('ha\x07ho')) 2220 self.assertRaises(ValueError, setattr, a, "tail", 2221 _str('ha\x02ho')) 2222 2223 self.assertRaises(ValueError, Element, 2224 _str('ha\x07ho')) 2225 self.assertRaises(ValueError, Element, 2226 _str('ha\x02ho'))
2227
2228 - def test_encoding_tostring_utf16(self):
2229 # ElementTree fails to serialize this 2230 tostring = self.etree.tostring 2231 Element = self.etree.Element 2232 SubElement = self.etree.SubElement 2233 2234 a = Element('a') 2235 b = SubElement(a, 'b') 2236 c = SubElement(a, 'c') 2237 2238 result = tostring(a, encoding='UTF-16') 2239 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2240 canonicalize(result))
2241
2242 - def test_tostring_none(self):
2243 # ElementTree raises an AssertionError here 2244 tostring = self.etree.tostring 2245 self.assertRaises(TypeError, self.etree.tostring, None)
2246
2247 - def test_tostring_pretty(self):
2248 tostring = self.etree.tostring 2249 Element = self.etree.Element 2250 SubElement = self.etree.SubElement 2251 2252 a = Element('a') 2253 b = SubElement(a, 'b') 2254 c = SubElement(a, 'c') 2255 2256 result = tostring(a) 2257 self.assertEquals(result, _bytes("<a><b/><c/></a>")) 2258 2259 result = tostring(a, pretty_print=False) 2260 self.assertEquals(result, _bytes("<a><b/><c/></a>")) 2261 2262 result = tostring(a, pretty_print=True) 2263 self.assertEquals(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
2264
2265 - def test_tostring_with_tail(self):
2266 tostring = self.etree.tostring 2267 Element = self.etree.Element 2268 SubElement = self.etree.SubElement 2269 2270 a = Element('a') 2271 a.tail = "aTAIL" 2272 b = SubElement(a, 'b') 2273 b.tail = "bTAIL" 2274 c = SubElement(a, 'c') 2275 2276 result = tostring(a) 2277 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 2278 2279 result = tostring(a, with_tail=False) 2280 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>")) 2281 2282 result = tostring(a, with_tail=True) 2283 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
2284
2285 - def test_tostring_method_text_encoding(self):
2286 tostring = self.etree.tostring 2287 Element = self.etree.Element 2288 SubElement = self.etree.SubElement 2289 2290 a = Element('a') 2291 a.text = "A" 2292 a.tail = "tail" 2293 b = SubElement(a, 'b') 2294 b.text = "B" 2295 b.tail = _str("Søk på nettet") 2296 c = SubElement(a, 'c') 2297 c.text = "C" 2298 2299 result = tostring(a, method="text", encoding="UTF-16") 2300 2301 self.assertEquals(_str('ABSøk på nettetCtail').encode("UTF-16"), 2302 result)
2303
2304 - def test_tostring_method_text_unicode(self):
2305 tostring = self.etree.tostring 2306 Element = self.etree.Element 2307 SubElement = self.etree.SubElement 2308 2309 a = Element('a') 2310 a.text = _str('Søk på nettetA') 2311 a.tail = "tail" 2312 b = SubElement(a, 'b') 2313 b.text = "B" 2314 b.tail = _str('Søk på nettetB') 2315 c = SubElement(a, 'c') 2316 c.text = "C" 2317 2318 self.assertRaises(UnicodeEncodeError, 2319 tostring, a, method="text") 2320 2321 self.assertEquals( 2322 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 2323 tostring(a, encoding="UTF-8", method="text"))
2324
2325 - def test_tounicode(self):
2326 tounicode = self.etree.tounicode 2327 Element = self.etree.Element 2328 SubElement = self.etree.SubElement 2329 2330 a = Element('a') 2331 b = SubElement(a, 'b') 2332 c = SubElement(a, 'c') 2333 2334 self.assert_(isinstance(tounicode(a), _unicode)) 2335 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2336 canonicalize(tounicode(a)))
2337
2338 - def test_tounicode_element(self):
2339 tounicode = self.etree.tounicode 2340 Element = self.etree.Element 2341 SubElement = self.etree.SubElement 2342 2343 a = Element('a') 2344 b = SubElement(a, 'b') 2345 c = SubElement(a, 'c') 2346 d = SubElement(c, 'd') 2347 self.assert_(isinstance(tounicode(b), _unicode)) 2348 self.assert_(isinstance(tounicode(c), _unicode)) 2349 self.assertEquals(_bytes('<b></b>'), 2350 canonicalize(tounicode(b))) 2351 self.assertEquals(_bytes('<c><d></d></c>'), 2352 canonicalize(tounicode(c)))
2353
2354 - def test_tounicode_none(self):
2355 tounicode = self.etree.tounicode 2356 self.assertRaises(TypeError, self.etree.tounicode, None)
2357
2358 - def test_tounicode_element_tail(self):
2359 tounicode = self.etree.tounicode 2360 Element = self.etree.Element 2361 SubElement = self.etree.SubElement 2362 2363 a = Element('a') 2364 b = SubElement(a, 'b') 2365 c = SubElement(a, 'c') 2366 d = SubElement(c, 'd') 2367 b.tail = 'Foo' 2368 2369 self.assert_(isinstance(tounicode(b), _unicode)) 2370 self.assert_(tounicode(b) == '<b/>Foo' or 2371 tounicode(b) == '<b />Foo')
2372
2373 - def test_tounicode_pretty(self):
2374 tounicode = self.etree.tounicode 2375 Element = self.etree.Element 2376 SubElement = self.etree.SubElement 2377 2378 a = Element('a') 2379 b = SubElement(a, 'b') 2380 c = SubElement(a, 'c') 2381 2382 result = tounicode(a) 2383 self.assertEquals(result, "<a><b/><c/></a>") 2384 2385 result = tounicode(a, pretty_print=False) 2386 self.assertEquals(result, "<a><b/><c/></a>") 2387 2388 result = tounicode(a, pretty_print=True) 2389 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2390
2391 - def test_tostring_unicode(self):
2392 tostring = self.etree.tostring 2393 Element = self.etree.Element 2394 SubElement = self.etree.SubElement 2395 2396 a = Element('a') 2397 b = SubElement(a, 'b') 2398 c = SubElement(a, 'c') 2399 2400 self.assert_(isinstance(tostring(a, encoding=_unicode), _unicode)) 2401 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2402 canonicalize(tostring(a, encoding=_unicode)))
2403
2404 - def test_tostring_unicode_element(self):
2405 tostring = self.etree.tostring 2406 Element = self.etree.Element 2407 SubElement = self.etree.SubElement 2408 2409 a = Element('a') 2410 b = SubElement(a, 'b') 2411 c = SubElement(a, 'c') 2412 d = SubElement(c, 'd') 2413 self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode)) 2414 self.assert_(isinstance(tostring(c, encoding=_unicode), _unicode)) 2415 self.assertEquals(_bytes('<b></b>'), 2416 canonicalize(tostring(b, encoding=_unicode))) 2417 self.assertEquals(_bytes('<c><d></d></c>'), 2418 canonicalize(tostring(c, encoding=_unicode)))
2419
2420 - def test_tostring_unicode_none(self):
2421 tostring = self.etree.tostring 2422 self.assertRaises(TypeError, self.etree.tostring, 2423 None, encoding=_unicode)
2424
2425 - def test_tostring_unicode_element_tail(self):
2426 tostring = self.etree.tostring 2427 Element = self.etree.Element 2428 SubElement = self.etree.SubElement 2429 2430 a = Element('a') 2431 b = SubElement(a, 'b') 2432 c = SubElement(a, 'c') 2433 d = SubElement(c, 'd') 2434 b.tail = 'Foo' 2435 2436 self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode)) 2437 self.assert_(tostring(b, encoding=_unicode) == '<b/>Foo' or 2438 tostring(b, encoding=_unicode) == '<b />Foo')
2439
2440 - def test_tostring_unicode_pretty(self):
2441 tostring = self.etree.tostring 2442 Element = self.etree.Element 2443 SubElement = self.etree.SubElement 2444 2445 a = Element('a') 2446 b = SubElement(a, 'b') 2447 c = SubElement(a, 'c') 2448 2449 result = tostring(a, encoding=_unicode) 2450 self.assertEquals(result, "<a><b/><c/></a>") 2451 2452 result = tostring(a, encoding=_unicode, pretty_print=False) 2453 self.assertEquals(result, "<a><b/><c/></a>") 2454 2455 result = tostring(a, encoding=_unicode, pretty_print=True) 2456 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2457 2458 # helper methods 2459
2460 - def _writeElement(self, element, encoding='us-ascii'):
2461 """Write out element for comparison. 2462 """ 2463 ElementTree = self.etree.ElementTree 2464 f = BytesIO() 2465 tree = ElementTree(element=element) 2466 tree.write(f, encoding=encoding) 2467 data = f.getvalue() 2468 return canonicalize(data)
2469 2470
2471 -class XIncludeTestCase(HelperTestCase):
2472 - def test_xinclude_text(self):
2473 filename = fileInTestDir('test_broken.xml') 2474 root = etree.XML(_bytes('''\ 2475 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 2476 <xi:include href="%s" parse="text"/> 2477 </doc> 2478 ''' % filename)) 2479 old_text = root.text 2480 content = open(filename).read() 2481 old_tail = root[0].tail 2482 2483 self.include( etree.ElementTree(root) ) 2484 self.assertEquals(old_text + content + old_tail, 2485 root.text)
2486
2487 - def test_xinclude(self):
2488 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 2489 self.assertNotEquals( 2490 'a', 2491 tree.getroot()[1].tag) 2492 # process xincludes 2493 self.include( tree ) 2494 # check whether we find it replaced with included data 2495 self.assertEquals( 2496 'a', 2497 tree.getroot()[1].tag)
2498
2499 - def test_xinclude_resolver(self):
2500 class res(etree.Resolver): 2501 include_text = open(fileInTestDir('test.xml')).read() 2502 called = {} 2503 def resolve(self, url, id, context): 2504 if url.endswith(".dtd"): 2505 self.called["dtd"] = True 2506 return self.resolve_filename( 2507 fileInTestDir('test.dtd'), context) 2508 elif url.endswith("test_xinclude.xml"): 2509 self.called["input"] = True 2510 return None # delegate to default resolver 2511 else: 2512 self.called["include"] = True 2513 return self.resolve_string(self.include_text, context)
2514 2515 res_instance = res() 2516 parser = etree.XMLParser(load_dtd = True) 2517 parser.resolvers.add(res_instance) 2518 2519 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 2520 parser = parser) 2521 2522 self.include(tree) 2523 2524 called = list(res_instance.called.items()) 2525 called.sort() 2526 self.assertEquals( 2527 [("dtd", True), ("include", True), ("input", True)], 2528 called) 2529
2530 -class ETreeXIncludeTestCase(XIncludeTestCase):
2531 - def include(self, tree):
2532 tree.xinclude()
2533 2534
2535 -class ElementIncludeTestCase(XIncludeTestCase):
2536 from lxml import ElementInclude
2537 - def include(self, tree):
2538 self.ElementInclude.include(tree.getroot())
2539 2540
2541 -class ETreeC14NTestCase(HelperTestCase):
2542 - def test_c14n(self):
2543 tree = self.parse(_bytes('<a><b/></a>')) 2544 f = BytesIO() 2545 tree.write_c14n(f) 2546 s = f.getvalue() 2547 self.assertEquals(_bytes('<a><b></b></a>'), 2548 s)
2549
2550 - def test_c14n_file(self):
2551 tree = self.parse(_bytes('<a><b/></a>')) 2552 handle, filename = tempfile.mkstemp() 2553 try: 2554 tree.write_c14n(filename) 2555 f = open(filename, 'rb') 2556 data = f.read() 2557 f.close() 2558 finally: 2559 os.close(handle) 2560 os.remove(filename) 2561 self.assertEquals(_bytes('<a><b></b></a>'), 2562 data)
2563
2564 - def test_c14n_with_comments(self):
2565 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 2566 f = BytesIO() 2567 tree.write_c14n(f) 2568 s = f.getvalue() 2569 self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 2570 s) 2571 f = BytesIO() 2572 tree.write_c14n(f, with_comments=True) 2573 s = f.getvalue() 2574 self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 2575 s) 2576 f = BytesIO() 2577 tree.write_c14n(f, with_comments=False) 2578 s = f.getvalue() 2579 self.assertEquals(_bytes('<a><b></b></a>'), 2580 s)
2581
2582 - def test_c14n_exclusive(self):
2583 tree = self.parse(_bytes( 2584 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 2585 f = BytesIO() 2586 tree.write_c14n(f) 2587 s = f.getvalue() 2588 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 2589 s) 2590 f = BytesIO() 2591 tree.write_c14n(f, exclusive=False) 2592 s = f.getvalue() 2593 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 2594 s) 2595 f = BytesIO() 2596 tree.write_c14n(f, exclusive=True) 2597 s = f.getvalue() 2598 self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 2599 s)
2600
2601 -def test_suite():
2602 suite = unittest.TestSuite() 2603 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 2604 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 2605 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 2606 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 2607 suite.addTests( 2608 [make_doctest('../../../doc/tutorial.txt')]) 2609 suite.addTests( 2610 [make_doctest('../../../doc/api.txt')]) 2611 suite.addTests( 2612 [make_doctest('../../../doc/FAQ.txt')]) 2613 suite.addTests( 2614 [make_doctest('../../../doc/parsing.txt')]) 2615 suite.addTests( 2616 [make_doctest('../../../doc/resolvers.txt')]) 2617 return suite
2618 2619 if __name__ == '__main__': 2620 print('to test use test.py %s' % __file__) 2621