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 = _bytes(xml_header + doctype_string + '<html><body></body></html>') 2043 2044 tree = etree.parse(BytesIO(xml)) 2045 docinfo = tree.docinfo 2046 self.assertEquals(docinfo.encoding, "ascii") 2047 self.assertEquals(docinfo.xml_version, "1.0") 2048 self.assertEquals(docinfo.public_id, pub_id) 2049 self.assertEquals(docinfo.system_url, sys_id) 2050 self.assertEquals(docinfo.root_name, 'html') 2051 self.assertEquals(docinfo.doctype, doctype_string)
2052
2053 - def test_docinfo_system(self):
2054 etree = self.etree 2055 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 2056 sys_id = "some.dtd" 2057 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 2058 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 2059 2060 tree = etree.parse(BytesIO(xml)) 2061 docinfo = tree.docinfo 2062 self.assertEquals(docinfo.encoding, "UTF-8") 2063 self.assertEquals(docinfo.xml_version, "1.0") 2064 self.assertEquals(docinfo.public_id, None) 2065 self.assertEquals(docinfo.system_url, sys_id) 2066 self.assertEquals(docinfo.root_name, 'html') 2067 self.assertEquals(docinfo.doctype, doctype_string)
2068
2069 - def test_docinfo_empty(self):
2070 etree = self.etree 2071 xml = _bytes('<html><body></body></html>') 2072 tree = etree.parse(BytesIO(xml)) 2073 docinfo = tree.docinfo 2074 self.assertEquals(docinfo.encoding, "UTF-8") 2075 self.assertEquals(docinfo.xml_version, "1.0") 2076 self.assertEquals(docinfo.public_id, None) 2077 self.assertEquals(docinfo.system_url, None) 2078 self.assertEquals(docinfo.root_name, 'html') 2079 self.assertEquals(docinfo.doctype, '')
2080
2081 - def test_docinfo_name_only(self):
2082 etree = self.etree 2083 xml = _bytes('<!DOCTYPE root><root></root>') 2084 tree = etree.parse(BytesIO(xml)) 2085 docinfo = tree.docinfo 2086 self.assertEquals(docinfo.encoding, "UTF-8") 2087 self.assertEquals(docinfo.xml_version, "1.0") 2088 self.assertEquals(docinfo.public_id, None) 2089 self.assertEquals(docinfo.system_url, None) 2090 self.assertEquals(docinfo.root_name, 'root') 2091 self.assertEquals(docinfo.doctype, '<!DOCTYPE root>')
2092
2093 - def test_doctype_name_only_roundtrip(self):
2094 etree = self.etree 2095 xml = _bytes('<!DOCTYPE root>\n<root/>') 2096 tree = etree.parse(BytesIO(xml)) 2097 self.assertEquals(xml, etree.tostring(tree))
2098
2099 - def test_xml_base(self):
2100 etree = self.etree 2101 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2102 self.assertEquals(root.base, "http://no/such/url") 2103 self.assertEquals( 2104 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 2105 root.base = "https://secret/url" 2106 self.assertEquals(root.base, "https://secret/url") 2107 self.assertEquals( 2108 root.get('{http://www.w3.org/XML/1998/namespace}base'), 2109 "https://secret/url")
2110
2111 - def test_xml_base_attribute(self):
2112 etree = self.etree 2113 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2114 self.assertEquals(root.base, "http://no/such/url") 2115 self.assertEquals( 2116 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 2117 root.set('{http://www.w3.org/XML/1998/namespace}base', 2118 "https://secret/url") 2119 self.assertEquals(root.base, "https://secret/url") 2120 self.assertEquals( 2121 root.get('{http://www.w3.org/XML/1998/namespace}base'), 2122 "https://secret/url")
2123
2124 - def test_html_base(self):
2125 etree = self.etree 2126 root = etree.HTML(_bytes("<html><body></body></html>"), 2127 base_url="http://no/such/url") 2128 self.assertEquals(root.base, "http://no/such/url")
2129
2130 - def test_html_base_tag(self):
2131 etree = self.etree 2132 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 2133 self.assertEquals(root.base, "http://no/such/url")
2134
2135 - def test_parse_fileobject_unicode(self):
2136 # parse from a file object that returns unicode strings 2137 f = LargeFileLikeUnicode() 2138 tree = self.etree.parse(f) 2139 root = tree.getroot() 2140 self.assert_(root.tag.endswith('root'))
2141
2142 - def test_dtd_io(self):
2143 # check that DTDs that go in also go back out 2144 xml = _bytes('''\ 2145 <!DOCTYPE test SYSTEM "test.dtd" [ 2146 <!ENTITY entity "tasty"> 2147 <!ELEMENT test (a)> 2148 <!ELEMENT a (#PCDATA)> 2149 ]> 2150 <test><a>test-test</a></test>\ 2151 ''') 2152 tree = self.etree.parse(BytesIO(xml)) 2153 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 2154 xml.replace(_bytes(" "), _bytes("")))
2155
2156 - def test_byte_zero(self):
2157 Element = self.etree.Element 2158 2159 a = Element('a') 2160 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 2161 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 2162 2163 self.assertRaises(ValueError, Element, 'ha\0ho')
2164
2165 - def test_unicode_byte_zero(self):
2166 Element = self.etree.Element 2167 2168 a = Element('a') 2169 self.assertRaises(ValueError, setattr, a, "text", 2170 _str('ha\0ho')) 2171 self.assertRaises(ValueError, setattr, a, "tail", 2172 _str('ha\0ho')) 2173 2174 self.assertRaises(ValueError, Element, 2175 _str('ha\0ho'))
2176
2177 - def test_byte_invalid(self):
2178 Element = self.etree.Element 2179 2180 a = Element('a') 2181 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 2182 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 2183 2184 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 2185 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 2186 2187 self.assertRaises(ValueError, Element, 'ha\x07ho') 2188 self.assertRaises(ValueError, Element, 'ha\x02ho')
2189
2190 - def test_unicode_byte_invalid(self):
2191 Element = self.etree.Element 2192 2193 a = Element('a') 2194 self.assertRaises(ValueError, setattr, a, "text", 2195 _str('ha\x07ho')) 2196 self.assertRaises(ValueError, setattr, a, "text", 2197 _str('ha\x02ho')) 2198 2199 self.assertRaises(ValueError, setattr, a, "tail", 2200 _str('ha\x07ho')) 2201 self.assertRaises(ValueError, setattr, a, "tail", 2202 _str('ha\x02ho')) 2203 2204 self.assertRaises(ValueError, Element, 2205 _str('ha\x07ho')) 2206 self.assertRaises(ValueError, Element, 2207 _str('ha\x02ho'))
2208
2209 - def test_encoding_tostring_utf16(self):
2210 # ElementTree fails to serialize this 2211 tostring = self.etree.tostring 2212 Element = self.etree.Element 2213 SubElement = self.etree.SubElement 2214 2215 a = Element('a') 2216 b = SubElement(a, 'b') 2217 c = SubElement(a, 'c') 2218 2219 result = tostring(a, encoding='UTF-16') 2220 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2221 canonicalize(result))
2222
2223 - def test_tostring_none(self):
2224 # ElementTree raises an AssertionError here 2225 tostring = self.etree.tostring 2226 self.assertRaises(TypeError, self.etree.tostring, None)
2227
2228 - def test_tostring_pretty(self):
2229 tostring = self.etree.tostring 2230 Element = self.etree.Element 2231 SubElement = self.etree.SubElement 2232 2233 a = Element('a') 2234 b = SubElement(a, 'b') 2235 c = SubElement(a, 'c') 2236 2237 result = tostring(a) 2238 self.assertEquals(result, _bytes("<a><b/><c/></a>")) 2239 2240 result = tostring(a, pretty_print=False) 2241 self.assertEquals(result, _bytes("<a><b/><c/></a>")) 2242 2243 result = tostring(a, pretty_print=True) 2244 self.assertEquals(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
2245
2246 - def test_tostring_with_tail(self):
2247 tostring = self.etree.tostring 2248 Element = self.etree.Element 2249 SubElement = self.etree.SubElement 2250 2251 a = Element('a') 2252 a.tail = "aTAIL" 2253 b = SubElement(a, 'b') 2254 b.tail = "bTAIL" 2255 c = SubElement(a, 'c') 2256 2257 result = tostring(a) 2258 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 2259 2260 result = tostring(a, with_tail=False) 2261 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>")) 2262 2263 result = tostring(a, with_tail=True) 2264 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
2265
2266 - def test_tostring_method_text_encoding(self):
2267 tostring = self.etree.tostring 2268 Element = self.etree.Element 2269 SubElement = self.etree.SubElement 2270 2271 a = Element('a') 2272 a.text = "A" 2273 a.tail = "tail" 2274 b = SubElement(a, 'b') 2275 b.text = "B" 2276 b.tail = _str("Søk på nettet") 2277 c = SubElement(a, 'c') 2278 c.text = "C" 2279 2280 result = tostring(a, method="text", encoding="UTF-16") 2281 2282 self.assertEquals(_str('ABSøk på nettetCtail').encode("UTF-16"), 2283 result)
2284
2285 - def test_tostring_method_text_unicode(self):
2286 tostring = self.etree.tostring 2287 Element = self.etree.Element 2288 SubElement = self.etree.SubElement 2289 2290 a = Element('a') 2291 a.text = _str('Søk på nettetA') 2292 a.tail = "tail" 2293 b = SubElement(a, 'b') 2294 b.text = "B" 2295 b.tail = _str('Søk på nettetB') 2296 c = SubElement(a, 'c') 2297 c.text = "C" 2298 2299 self.assertRaises(UnicodeEncodeError, 2300 tostring, a, method="text") 2301 2302 self.assertEquals( 2303 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 2304 tostring(a, encoding="UTF-8", method="text"))
2305
2306 - def test_tounicode(self):
2307 tounicode = self.etree.tounicode 2308 Element = self.etree.Element 2309 SubElement = self.etree.SubElement 2310 2311 a = Element('a') 2312 b = SubElement(a, 'b') 2313 c = SubElement(a, 'c') 2314 2315 self.assert_(isinstance(tounicode(a), _unicode)) 2316 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2317 canonicalize(tounicode(a)))
2318
2319 - def test_tounicode_element(self):
2320 tounicode = self.etree.tounicode 2321 Element = self.etree.Element 2322 SubElement = self.etree.SubElement 2323 2324 a = Element('a') 2325 b = SubElement(a, 'b') 2326 c = SubElement(a, 'c') 2327 d = SubElement(c, 'd') 2328 self.assert_(isinstance(tounicode(b), _unicode)) 2329 self.assert_(isinstance(tounicode(c), _unicode)) 2330 self.assertEquals(_bytes('<b></b>'), 2331 canonicalize(tounicode(b))) 2332 self.assertEquals(_bytes('<c><d></d></c>'), 2333 canonicalize(tounicode(c)))
2334
2335 - def test_tounicode_none(self):
2336 tounicode = self.etree.tounicode 2337 self.assertRaises(TypeError, self.etree.tounicode, None)
2338
2339 - def test_tounicode_element_tail(self):
2340 tounicode = self.etree.tounicode 2341 Element = self.etree.Element 2342 SubElement = self.etree.SubElement 2343 2344 a = Element('a') 2345 b = SubElement(a, 'b') 2346 c = SubElement(a, 'c') 2347 d = SubElement(c, 'd') 2348 b.tail = 'Foo' 2349 2350 self.assert_(isinstance(tounicode(b), _unicode)) 2351 self.assert_(tounicode(b) == '<b/>Foo' or 2352 tounicode(b) == '<b />Foo')
2353
2354 - def test_tounicode_pretty(self):
2355 tounicode = self.etree.tounicode 2356 Element = self.etree.Element 2357 SubElement = self.etree.SubElement 2358 2359 a = Element('a') 2360 b = SubElement(a, 'b') 2361 c = SubElement(a, 'c') 2362 2363 result = tounicode(a) 2364 self.assertEquals(result, "<a><b/><c/></a>") 2365 2366 result = tounicode(a, pretty_print=False) 2367 self.assertEquals(result, "<a><b/><c/></a>") 2368 2369 result = tounicode(a, pretty_print=True) 2370 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2371
2372 - def test_tostring_unicode(self):
2373 tostring = self.etree.tostring 2374 Element = self.etree.Element 2375 SubElement = self.etree.SubElement 2376 2377 a = Element('a') 2378 b = SubElement(a, 'b') 2379 c = SubElement(a, 'c') 2380 2381 self.assert_(isinstance(tostring(a, encoding=_unicode), _unicode)) 2382 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2383 canonicalize(tostring(a, encoding=_unicode)))
2384
2385 - def test_tostring_unicode_element(self):
2386 tostring = self.etree.tostring 2387 Element = self.etree.Element 2388 SubElement = self.etree.SubElement 2389 2390 a = Element('a') 2391 b = SubElement(a, 'b') 2392 c = SubElement(a, 'c') 2393 d = SubElement(c, 'd') 2394 self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode)) 2395 self.assert_(isinstance(tostring(c, encoding=_unicode), _unicode)) 2396 self.assertEquals(_bytes('<b></b>'), 2397 canonicalize(tostring(b, encoding=_unicode))) 2398 self.assertEquals(_bytes('<c><d></d></c>'), 2399 canonicalize(tostring(c, encoding=_unicode)))
2400
2401 - def test_tostring_unicode_none(self):
2402 tostring = self.etree.tostring 2403 self.assertRaises(TypeError, self.etree.tostring, 2404 None, encoding=_unicode)
2405
2406 - def test_tostring_unicode_element_tail(self):
2407 tostring = self.etree.tostring 2408 Element = self.etree.Element 2409 SubElement = self.etree.SubElement 2410 2411 a = Element('a') 2412 b = SubElement(a, 'b') 2413 c = SubElement(a, 'c') 2414 d = SubElement(c, 'd') 2415 b.tail = 'Foo' 2416 2417 self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode)) 2418 self.assert_(tostring(b, encoding=_unicode) == '<b/>Foo' or 2419 tostring(b, encoding=_unicode) == '<b />Foo')
2420
2421 - def test_tostring_unicode_pretty(self):
2422 tostring = self.etree.tostring 2423 Element = self.etree.Element 2424 SubElement = self.etree.SubElement 2425 2426 a = Element('a') 2427 b = SubElement(a, 'b') 2428 c = SubElement(a, 'c') 2429 2430 result = tostring(a, encoding=_unicode) 2431 self.assertEquals(result, "<a><b/><c/></a>") 2432 2433 result = tostring(a, encoding=_unicode, pretty_print=False) 2434 self.assertEquals(result, "<a><b/><c/></a>") 2435 2436 result = tostring(a, encoding=_unicode, pretty_print=True) 2437 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2438 2439 # helper methods 2440
2441 - def _writeElement(self, element, encoding='us-ascii'):
2442 """Write out element for comparison. 2443 """ 2444 ElementTree = self.etree.ElementTree 2445 f = BytesIO() 2446 tree = ElementTree(element=element) 2447 tree.write(f, encoding=encoding) 2448 data = f.getvalue() 2449 return canonicalize(data)
2450 2451
2452 -class XIncludeTestCase(HelperTestCase):
2453 - def test_xinclude_text(self):
2454 filename = fileInTestDir('test_broken.xml') 2455 root = etree.XML(_bytes('''\ 2456 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 2457 <xi:include href="%s" parse="text"/> 2458 </doc> 2459 ''' % filename)) 2460 old_text = root.text 2461 content = open(filename).read() 2462 old_tail = root[0].tail 2463 2464 self.include( etree.ElementTree(root) ) 2465 self.assertEquals(old_text + content + old_tail, 2466 root.text)
2467
2468 - def test_xinclude(self):
2469 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 2470 self.assertNotEquals( 2471 'a', 2472 tree.getroot()[1].tag) 2473 # process xincludes 2474 self.include( tree ) 2475 # check whether we find it replaced with included data 2476 self.assertEquals( 2477 'a', 2478 tree.getroot()[1].tag)
2479
2480 - def test_xinclude_resolver(self):
2481 class res(etree.Resolver): 2482 include_text = open(fileInTestDir('test.xml')).read() 2483 called = {} 2484 def resolve(self, url, id, context): 2485 if url.endswith(".dtd"): 2486 self.called["dtd"] = True 2487 return self.resolve_filename( 2488 fileInTestDir('test.dtd'), context) 2489 elif url.endswith("test_xinclude.xml"): 2490 self.called["input"] = True 2491 return None # delegate to default resolver 2492 else: 2493 self.called["include"] = True 2494 return self.resolve_string(self.include_text, context)
2495 2496 res_instance = res() 2497 parser = etree.XMLParser(load_dtd = True) 2498 parser.resolvers.add(res_instance) 2499 2500 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 2501 parser = parser) 2502 2503 self.include(tree) 2504 2505 called = list(res_instance.called.items()) 2506 called.sort() 2507 self.assertEquals( 2508 [("dtd", True), ("include", True), ("input", True)], 2509 called) 2510
2511 -class ETreeXIncludeTestCase(XIncludeTestCase):
2512 - def include(self, tree):
2513 tree.xinclude()
2514 2515
2516 -class ElementIncludeTestCase(XIncludeTestCase):
2517 from lxml import ElementInclude
2518 - def include(self, tree):
2519 self.ElementInclude.include(tree.getroot())
2520 2521
2522 -class ETreeC14NTestCase(HelperTestCase):
2523 - def test_c14n(self):
2524 tree = self.parse(_bytes('<a><b/></a>')) 2525 f = BytesIO() 2526 tree.write_c14n(f) 2527 s = f.getvalue() 2528 self.assertEquals(_bytes('<a><b></b></a>'), 2529 s)
2530
2531 -def test_suite():
2532 suite = unittest.TestSuite() 2533 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 2534 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 2535 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 2536 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 2537 suite.addTests( 2538 [make_doctest('../../../doc/tutorial.txt')]) 2539 suite.addTests( 2540 [make_doctest('../../../doc/api.txt')]) 2541 suite.addTests( 2542 [make_doctest('../../../doc/FAQ.txt')]) 2543 suite.addTests( 2544 [make_doctest('../../../doc/parsing.txt')]) 2545 suite.addTests( 2546 [make_doctest('../../../doc/resolvers.txt')]) 2547 return suite
2548 2549 if __name__ == '__main__': 2550 print('to test use test.py %s' % __file__) 2551