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 
  11  import unittest 
  12  import copy 
  13  import sys 
  14  import re 
  15  import operator 
  16  import tempfile 
  17  import gzip 
  18   
  19  this_dir = os.path.dirname(__file__) 
  20  if this_dir not in sys.path: 
  21      sys.path.insert(0, this_dir) # needed for Py3 
  22   
  23  from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir 
  24  from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest 
  25  from common_imports import canonicalize, sorted, _str, _bytes 
  26   
  27  print("") 
  28  print("TESTED VERSION: %s" % etree.__version__) 
  29  print("    Python:           " + repr(sys.version_info)) 
  30  print("    lxml.etree:       " + repr(etree.LXML_VERSION)) 
  31  print("    libxml used:      " + repr(etree.LIBXML_VERSION)) 
  32  print("    libxml compiled:  " + repr(etree.LIBXML_COMPILED_VERSION)) 
  33  print("    libxslt used:     " + repr(etree.LIBXSLT_VERSION)) 
  34  print("    libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION)) 
  35  print("") 
  36   
  37  try: 
  38      _unicode = unicode 
  39  except NameError: 
  40      # Python 3 
  41      _unicode = str 
  42   
43 -class ETreeOnlyTestCase(HelperTestCase):
44 """Tests only for etree, not ElementTree""" 45 etree = etree 46
47 - def test_version(self):
48 self.assert_(isinstance(etree.__version__, _unicode)) 49 self.assert_(isinstance(etree.LXML_VERSION, tuple)) 50 self.assertEqual(len(etree.LXML_VERSION), 4) 51 self.assert_(isinstance(etree.LXML_VERSION[0], int)) 52 self.assert_(isinstance(etree.LXML_VERSION[1], int)) 53 self.assert_(isinstance(etree.LXML_VERSION[2], int)) 54 self.assert_(isinstance(etree.LXML_VERSION[3], int)) 55 self.assert_(etree.__version__.startswith( 56 str(etree.LXML_VERSION[0])))
57
58 - def test_c_api(self):
59 if hasattr(self.etree, '__pyx_capi__'): 60 # newer Pyrex compatible C-API 61 self.assert_(isinstance(self.etree.__pyx_capi__, dict)) 62 self.assert_(len(self.etree.__pyx_capi__) > 0) 63 else: 64 # older C-API mechanism 65 self.assert_(hasattr(self.etree, '_import_c_api'))
66
67 - def test_element_names(self):
68 Element = self.etree.Element 69 el = Element('name') 70 self.assertEquals(el.tag, 'name') 71 el = Element('{}name') 72 self.assertEquals(el.tag, 'name')
73
74 - def test_element_name_empty(self):
75 Element = self.etree.Element 76 el = Element('name') 77 self.assertRaises(ValueError, Element, '{}') 78 self.assertRaises(ValueError, setattr, el, 'tag', '{}') 79 80 self.assertRaises(ValueError, Element, '{test}') 81 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
82
83 - def test_element_name_colon(self):
84 Element = self.etree.Element 85 self.assertRaises(ValueError, Element, 'p:name') 86 self.assertRaises(ValueError, Element, '{test}p:name') 87 88 el = Element('name') 89 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
90
91 - def test_element_name_quote(self):
92 Element = self.etree.Element 93 self.assertRaises(ValueError, Element, "p'name") 94 self.assertRaises(ValueError, Element, 'p"name') 95 96 self.assertRaises(ValueError, Element, "{test}p'name") 97 self.assertRaises(ValueError, Element, '{test}p"name') 98 99 el = Element('name') 100 self.assertRaises(ValueError, setattr, el, 'tag', "p'name") 101 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
102
103 - def test_element_name_space(self):
104 Element = self.etree.Element 105 self.assertRaises(ValueError, Element, ' name ') 106 self.assertRaises(ValueError, Element, 'na me') 107 self.assertRaises(ValueError, Element, '{test} name') 108 109 el = Element('name') 110 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
111
112 - def test_subelement_name_empty(self):
113 Element = self.etree.Element 114 SubElement = self.etree.SubElement 115 116 el = Element('name') 117 self.assertRaises(ValueError, SubElement, el, '{}') 118 self.assertRaises(ValueError, SubElement, el, '{test}')
119
120 - def test_subelement_name_colon(self):
121 Element = self.etree.Element 122 SubElement = self.etree.SubElement 123 124 el = Element('name') 125 self.assertRaises(ValueError, SubElement, el, 'p:name') 126 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
127
128 - def test_subelement_name_quote(self):
129 Element = self.etree.Element 130 SubElement = self.etree.SubElement 131 132 el = Element('name') 133 self.assertRaises(ValueError, SubElement, el, "p'name") 134 self.assertRaises(ValueError, SubElement, el, "{test}p'name") 135 136 self.assertRaises(ValueError, SubElement, el, 'p"name') 137 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
138
139 - def test_subelement_name_space(self):
140 Element = self.etree.Element 141 SubElement = self.etree.SubElement 142 143 el = Element('name') 144 self.assertRaises(ValueError, SubElement, el, ' name ') 145 self.assertRaises(ValueError, SubElement, el, 'na me') 146 self.assertRaises(ValueError, SubElement, el, '{test} name')
147
149 Element = self.etree.Element 150 SubElement = self.etree.SubElement 151 152 el = Element('name') 153 self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'}) 154 self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'}) 155 self.assertEquals(0, len(el))
156
157 - def test_qname_empty(self):
158 QName = self.etree.QName 159 self.assertRaises(ValueError, QName, '') 160 self.assertRaises(ValueError, QName, 'test', '')
161
162 - def test_qname_colon(self):
163 QName = self.etree.QName 164 self.assertRaises(ValueError, QName, 'p:name') 165 self.assertRaises(ValueError, QName, 'test', 'p:name')
166
167 - def test_qname_space(self):
168 QName = self.etree.QName 169 self.assertRaises(ValueError, QName, ' name ') 170 self.assertRaises(ValueError, QName, 'na me') 171 self.assertRaises(ValueError, QName, 'test', ' name')
172
174 # ET doesn't have namespace/localname properties on QNames 175 QName = self.etree.QName 176 namespace, localname = 'http://myns', 'a' 177 qname = QName(namespace, localname) 178 self.assertEquals(namespace, qname.namespace) 179 self.assertEquals(localname, qname.localname)
180
181 - def test_qname_element(self):
182 # ET doesn't have namespace/localname properties on QNames 183 QName = self.etree.QName 184 qname1 = QName('http://myns', 'a') 185 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'}) 186 187 qname2 = QName(a) 188 self.assertEquals(a.tag, qname1.text) 189 self.assertEquals(qname1.text, qname2.text) 190 self.assertEquals(qname1, qname2)
191
192 - def test_qname_text_resolve(self):
193 # ET doesn't resove QNames as text values 194 etree = self.etree 195 qname = etree.QName('http://myns', 'a') 196 a = etree.Element(qname, nsmap={'p' : 'http://myns'}) 197 a.text = qname 198 199 self.assertEquals("p:a", a.text)
200
201 - def test_nsmap_prefix_invalid(self):
202 etree = self.etree 203 self.assertRaises(ValueError, 204 etree.Element, "root", nsmap={'"' : 'testns'}) 205 self.assertRaises(ValueError, 206 etree.Element, "root", nsmap={'&' : 'testns'}) 207 self.assertRaises(ValueError, 208 etree.Element, "root", nsmap={'a:b' : 'testns'})
209
210 - def test_attribute_set(self):
211 Element = self.etree.Element 212 root = Element("root") 213 root.set("attr", "TEST") 214 self.assertEquals("TEST", root.get("attr"))
215
216 - def test_attribute_set_invalid(self):
217 # ElementTree accepts arbitrary attribute values 218 # lxml.etree allows only strings 219 Element = self.etree.Element 220 root = Element("root") 221 self.assertRaises(TypeError, root.set, "newattr", 5) 222 self.assertRaises(TypeError, root.set, "newattr", None)
223
224 - def test_strip_attributes(self):
225 XML = self.etree.XML 226 xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>') 227 228 root = XML(xml) 229 self.etree.strip_attributes(root, 'a') 230 self.assertEquals(_bytes('<test b="10" c="20"><x b="2"></x></test>'), 231 self._writeElement(root)) 232 233 root = XML(xml) 234 self.etree.strip_attributes(root, 'b', 'c') 235 self.assertEquals(_bytes('<test a="5"><x a="4"></x></test>'), 236 self._writeElement(root))
237
238 - def test_strip_attributes_ns(self):
239 XML = self.etree.XML 240 xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>') 241 242 root = XML(xml) 243 self.etree.strip_attributes(root, 'a') 244 self.assertEquals( 245 _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'), 246 self._writeElement(root)) 247 248 root = XML(xml) 249 self.etree.strip_attributes(root, '{http://test/ns}a', 'c') 250 self.assertEquals( 251 _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'), 252 self._writeElement(root)) 253 254 root = XML(xml) 255 self.etree.strip_attributes(root, '{http://test/ns}*') 256 self.assertEquals( 257 _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'), 258 self._writeElement(root))
259
260 - def test_strip_elements(self):
261 XML = self.etree.XML 262 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>') 263 264 root = XML(xml) 265 self.etree.strip_elements(root, 'a') 266 self.assertEquals(_bytes('<test><x></x></test>'), 267 self._writeElement(root)) 268 269 root = XML(xml) 270 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z') 271 self.assertEquals(_bytes('<test><a></a><x><a></a></x></test>'), 272 self._writeElement(root)) 273 274 root = XML(xml) 275 self.etree.strip_elements(root, 'c') 276 self.assertEquals(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'), 277 self._writeElement(root))
278
279 - def test_strip_elements_ns(self):
280 XML = self.etree.XML 281 xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>C</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>') 282 283 root = XML(xml) 284 self.etree.strip_elements(root, 'a') 285 self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X</x>XT</test>'), 286 self._writeElement(root)) 287 288 root = XML(xml) 289 self.etree.strip_elements(root, '{urn:a}b', 'c') 290 self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 291 self._writeElement(root)) 292 293 root = XML(xml) 294 self.etree.strip_elements(root, '{urn:a}*', 'c') 295 self.assertEquals(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 296 self._writeElement(root)) 297 298 root = XML(xml) 299 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False) 300 self.assertEquals(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 301 self._writeElement(root))
302
303 - def test_strip_tags(self):
304 XML = self.etree.XML 305 xml = _bytes('<test>TEST<a>A<b>B<c/>CT</b>BT</a>AT<x>X<a>A<b/>BT<c/>CT</a>AT</x>XT</test>') 306 307 root = XML(xml) 308 self.etree.strip_tags(root, 'a') 309 self.assertEquals(_bytes('<test>TESTA<b>B<c></c>CT</b>BTAT<x>XA<b></b>BT<c></c>CTAT</x>XT</test>'), 310 self._writeElement(root)) 311 312 root = XML(xml) 313 self.etree.strip_tags(root, 'b', 'c', 'X', 'Y', 'Z') 314 self.assertEquals(_bytes('<test>TEST<a>ABCTBT</a>AT<x>X<a>ABTCT</a>AT</x>XT</test>'), 315 self._writeElement(root)) 316 317 root = XML(xml) 318 self.etree.strip_tags(root, 'c') 319 self.assertEquals(_bytes('<test>TEST<a>A<b>BCT</b>BT</a>AT<x>X<a>A<b></b>BTCT</a>AT</x>XT</test>'), 320 self._writeElement(root))
321
322 - def test_strip_tags_pi_comment(self):
323 XML = self.etree.XML 324 PI = self.etree.ProcessingInstruction 325 Comment = self.etree.Comment 326 xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>') 327 328 root = XML(xml) 329 self.etree.strip_tags(root, PI) 330 self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->\n<?PI1?>'), 331 self._writeElement(root)) 332 333 root = XML(xml) 334 self.etree.strip_tags(root, Comment) 335 self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT<?PI2?></test>\n<!--comment3-->\n<?PI1?>'), 336 self._writeElement(root)) 337 338 root = XML(xml) 339 self.etree.strip_tags(root, PI, Comment) 340 self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'), 341 self._writeElement(root)) 342 343 root = XML(xml) 344 self.etree.strip_tags(root, Comment, PI) 345 self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'), 346 self._writeElement(root))
347
349 XML = self.etree.XML 350 ElementTree = self.etree.ElementTree 351 PI = self.etree.ProcessingInstruction 352 Comment = self.etree.Comment 353 xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>') 354 355 root = XML(xml) 356 self.etree.strip_tags(ElementTree(root), PI) 357 self.assertEquals(_bytes('<!--comment1-->\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->'), 358 self._writeElement(root)) 359 360 root = XML(xml) 361 self.etree.strip_tags(ElementTree(root), Comment) 362 self.assertEquals(_bytes('<?PI1?>\n<test>TESTXT<?PI2?></test>\n<?PI1?>'), 363 self._writeElement(root)) 364 365 root = XML(xml) 366 self.etree.strip_tags(ElementTree(root), PI, Comment) 367 self.assertEquals(_bytes('<test>TESTXT</test>'), 368 self._writeElement(root)) 369 370 root = XML(xml) 371 self.etree.strip_tags(ElementTree(root), Comment, PI) 372 self.assertEquals(_bytes('<test>TESTXT</test>'), 373 self._writeElement(root))
374
375 - def test_strip_tags_doc_style(self):
376 XML = self.etree.XML 377 xml = _bytes(''' 378 <div> 379 <div> 380 I like <strong>sheep</strong>. 381 <br/> 382 I like lots of <strong>sheep</strong>. 383 <br/> 384 Click <a href="http://www.sheep.com">here</a> for <a href="http://www.sheep.com">those</a> sheep. 385 <br/> 386 </div> 387 </div> 388 '''.strip()) 389 390 root = XML(xml) 391 self.etree.strip_tags(root, 'a') 392 self.assertEquals(re.sub(_bytes('</?a[^>]*>'), '', xml).replace('<br/>', '<br></br>'), 393 self._writeElement(root)) 394 395 root = XML(xml) 396 self.etree.strip_tags(root, 'a', 'br') 397 self.assertEquals(re.sub(_bytes('</?a[^>]*>'), '', 398 re.sub(_bytes('<br[^>]*>'), '', xml)), 399 self._writeElement(root))
400
401 - def test_strip_tags_ns(self):
402 XML = self.etree.XML 403 xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>CT</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>') 404 405 root = XML(xml) 406 self.etree.strip_tags(root, 'a') 407 self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>XA<b xmlns="urn:a"></b>BT<c xmlns="urn:x"></c>CTAT</x>XT</test>'), 408 self._writeElement(root)) 409 410 root = XML(xml) 411 self.etree.strip_tags(root, '{urn:a}b', 'c') 412 self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 413 self._writeElement(root)) 414 415 root = XML(xml) 416 self.etree.strip_tags(root, '{urn:a}*', 'c') 417 self.assertEquals(_bytes('<test>TESTA<b>B<c xmlns="urn:c"></c>CT</b>BTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 418 self._writeElement(root))
419
420 - def test_pi(self):
421 # lxml.etree separates target and text 422 Element = self.etree.Element 423 SubElement = self.etree.SubElement 424 ProcessingInstruction = self.etree.ProcessingInstruction 425 426 a = Element('a') 427 a.append(ProcessingInstruction('foo', 'some more text')) 428 self.assertEquals(a[0].target, 'foo') 429 self.assertEquals(a[0].text, 'some more text')
430
431 - def test_pi_parse(self):
432 XML = self.etree.XML 433 root = XML(_bytes("<test><?mypi my test ?></test>")) 434 self.assertEquals(root[0].target, "mypi") 435 self.assertEquals(root[0].text, "my test ")
436
437 - def test_deepcopy_pi(self):
438 # previously caused a crash 439 ProcessingInstruction = self.etree.ProcessingInstruction 440 441 a = ProcessingInstruction("PI", "ONE") 442 b = copy.deepcopy(a) 443 b.text = "ANOTHER" 444 445 self.assertEquals('ONE', a.text) 446 self.assertEquals('ANOTHER', b.text)
447
449 XML = self.etree.XML 450 tostring = self.etree.tostring 451 root = XML(_bytes("<?mypi my test ?><test/><!--comment -->")) 452 tree1 = self.etree.ElementTree(root) 453 self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"), 454 tostring(tree1)) 455 456 tree2 = copy.deepcopy(tree1) 457 self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"), 458 tostring(tree2)) 459 460 root2 = copy.deepcopy(tree1.getroot()) 461 self.assertEquals(_bytes("<test/>"), 462 tostring(root2))
463
465 XML = self.etree.XML 466 tostring = self.etree.tostring 467 xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') 468 root = XML(xml) 469 tree1 = self.etree.ElementTree(root) 470 self.assertEquals(xml, tostring(tree1)) 471 472 tree2 = copy.deepcopy(tree1) 473 self.assertEquals(xml, tostring(tree2)) 474 475 root2 = copy.deepcopy(tree1.getroot()) 476 self.assertEquals(_bytes("<test/>"), 477 tostring(root2))
478
479 - def test_attribute_set(self):
480 # ElementTree accepts arbitrary attribute values 481 # lxml.etree allows only strings 482 Element = self.etree.Element 483 484 root = Element("root") 485 root.set("attr", "TEST") 486 self.assertEquals("TEST", root.get("attr")) 487 self.assertRaises(TypeError, root.set, "newattr", 5)
488
489 - def test_parse_remove_comments(self):
490 fromstring = self.etree.fromstring 491 tostring = self.etree.tostring 492 XMLParser = self.etree.XMLParser 493 494 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 495 parser = XMLParser(remove_comments=True) 496 root = fromstring(xml, parser) 497 self.assertEquals( 498 _bytes('<a><b><c/></b></a>'), 499 tostring(root))
500
501 - def test_parse_remove_pis(self):
502 parse = self.etree.parse 503 tostring = self.etree.tostring 504 XMLParser = self.etree.XMLParser 505 506 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>') 507 508 f = BytesIO(xml) 509 tree = parse(f) 510 self.assertEquals( 511 xml, 512 tostring(tree)) 513 514 parser = XMLParser(remove_pis=True) 515 tree = parse(f, parser) 516 self.assertEquals( 517 _bytes('<a><b><c/></b></a>'), 518 tostring(tree))
519
521 # ET raises IOError only 522 parse = self.etree.parse 523 self.assertRaises(TypeError, parse, 'notthere.xml', object())
524
526 # ET removes comments 527 iterparse = self.etree.iterparse 528 tostring = self.etree.tostring 529 530 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 531 events = list(iterparse(f)) 532 root = events[-1][1] 533 self.assertEquals(3, len(events)) 534 self.assertEquals( 535 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 536 tostring(root))
537
538 - def test_iterparse_comments(self):
539 # ET removes comments 540 iterparse = self.etree.iterparse 541 tostring = self.etree.tostring 542 543 def name(event, el): 544 if event == 'comment': 545 return el.text 546 else: 547 return el.tag
548 549 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 550 events = list(iterparse(f, events=('end', 'comment'))) 551 root = events[-1][1] 552 self.assertEquals(6, len(events)) 553 self.assertEquals(['A', ' B ', 'c', 'b', 'C', 'a'], 554 [ name(*item) for item in events ]) 555 self.assertEquals( 556 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 557 tostring(root))
558
559 - def test_iterparse_pis(self):
560 # ET removes pis 561 iterparse = self.etree.iterparse 562 tostring = self.etree.tostring 563 ElementTree = self.etree.ElementTree 564 565 def name(event, el): 566 if event == 'pi': 567 return (el.target, el.text) 568 else: 569 return el.tag
570 571 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>') 572 events = list(iterparse(f, events=('end', 'pi'))) 573 root = events[-2][1] 574 self.assertEquals(8, len(events)) 575 self.assertEquals([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b', 576 ('pid','d'), 'a', ('pie','e')], 577 [ name(*item) for item in events ]) 578 self.assertEquals( 579 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'), 580 tostring(ElementTree(root))) 581
582 - def test_iterparse_remove_comments(self):
583 iterparse = self.etree.iterparse 584 tostring = self.etree.tostring 585 586 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 587 events = list(iterparse(f, remove_comments=True, 588 events=('end', 'comment'))) 589 root = events[-1][1] 590 self.assertEquals(3, len(events)) 591 self.assertEquals(['c', 'b', 'a'], 592 [ el.tag for (event, el) in events ]) 593 self.assertEquals( 594 _bytes('<a><b><c/></b></a>'), 595 tostring(root))
596
597 - def test_iterparse_broken(self):
598 iterparse = self.etree.iterparse 599 f = BytesIO('<a><b><c/></a>') 600 # ET raises ExpatError, lxml raises XMLSyntaxError 601 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
602
603 - def test_iterparse_strip(self):
604 iterparse = self.etree.iterparse 605 f = BytesIO(""" 606 <a> \n \n <b> b test </b> \n 607 608 \n\t <c> \n </c> </a> \n """) 609 iterator = iterparse(f, remove_blank_text=True) 610 text = [ (element.text, element.tail) 611 for event, element in iterator ] 612 self.assertEquals( 613 [(" b test ", None), (" \n ", None), (None, None)], 614 text)
615
616 - def test_iterparse_tag(self):
617 iterparse = self.etree.iterparse 618 f = BytesIO('<a><b><d/></b><c/></a>') 619 620 iterator = iterparse(f, tag="b", events=('start', 'end')) 621 events = list(iterator) 622 root = iterator.root 623 self.assertEquals( 624 [('start', root[0]), ('end', root[0])], 625 events)
626
627 - def test_iterparse_tag_all(self):
628 iterparse = self.etree.iterparse 629 f = BytesIO('<a><b><d/></b><c/></a>') 630 631 iterator = iterparse(f, tag="*", events=('start', 'end')) 632 events = list(iterator) 633 self.assertEquals( 634 8, 635 len(events))
636
637 - def test_iterparse_encoding_error(self):
638 text = _str('Søk på nettet') 639 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 640 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 641 ).encode('iso-8859-1') 642 643 self.assertRaises(self.etree.ParseError, 644 list, self.etree.iterparse(BytesIO(xml_latin1)))
645
646 - def test_iterparse_encoding_8bit_override(self):
647 text = _str('Søk på nettet', encoding="UTF-8") 648 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 649 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 650 ).encode('iso-8859-1') 651 652 iterator = self.etree.iterparse(BytesIO(xml_latin1), 653 encoding="iso-8859-1") 654 self.assertEquals(1, len(list(iterator))) 655 656 a = iterator.root 657 self.assertEquals(a.text, text)
658
659 - def test_iterparse_keep_cdata(self):
660 tostring = self.etree.tostring 661 f = BytesIO('<root><![CDATA[test]]></root>') 662 context = self.etree.iterparse(f, strip_cdata=False) 663 content = [ el.text for event,el in context ] 664 665 self.assertEquals(['test'], content) 666 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 667 tostring(context.root))
668
669 - def test_parser_encoding_unknown(self):
670 self.assertRaises( 671 LookupError, self.etree.XMLParser, encoding="hopefully unknown")
672
673 - def test_parser_encoding(self):
674 self.etree.XMLParser(encoding="ascii") 675 self.etree.XMLParser(encoding="utf-8") 676 self.etree.XMLParser(encoding="iso-8859-1")
677
678 - def test_feed_parser_recover(self):
679 parser = self.etree.XMLParser(recover=True) 680 681 parser.feed('<?xml version=') 682 parser.feed('"1.0"?><ro') 683 parser.feed('ot><') 684 parser.feed('a test="works"') 685 parser.feed('><othertag/></root') # <a> not closed! 686 parser.feed('>') 687 688 root = parser.close() 689 690 self.assertEquals(root.tag, "root") 691 self.assertEquals(len(root), 1) 692 self.assertEquals(root[0].tag, "a") 693 self.assertEquals(root[0].get("test"), "works") 694 self.assertEquals(len(root[0]), 1) 695 self.assertEquals(root[0][0].tag, "othertag")
696 # FIXME: would be nice to get some errors logged ... 697 #self.assert_(len(parser.error_log) > 0, "error log is empty") 698
699 - def test_elementtree_parser_target_type_error(self):
700 assertEquals = self.assertEquals 701 assertFalse = self.assertFalse 702 703 events = [] 704 class Target(object): 705 def start(self, tag, attrib): 706 events.append("start") 707 assertFalse(attrib) 708 assertEquals("TAG", tag)
709 def end(self, tag): 710 events.append("end") 711 assertEquals("TAG", tag) 712 def close(self): 713 return "DONE" # no Element! 714 715 parser = self.etree.XMLParser(target=Target()) 716 tree = self.etree.ElementTree() 717 718 self.assertRaises(TypeError, 719 tree.parse, BytesIO("<TAG/>"), parser=parser) 720 self.assertEquals(["start", "end"], events) 721
722 - def test_parser_target_comment(self):
723 events = [] 724 class Target(object): 725 def start(self, tag, attrib): 726 events.append("start-" + tag)
727 def end(self, tag): 728 events.append("end-" + tag) 729 def data(self, data): 730 events.append("data-" + data) 731 def comment(self, text): 732 events.append("comment-" + text) 733 def close(self): 734 return "DONE" 735 736 parser = self.etree.XMLParser(target=Target()) 737 738 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')) 739 done = parser.close() 740 741 self.assertEquals("DONE", done) 742 self.assertEquals(["comment-a", "start-root", "data-A", "comment-b", 743 "start-sub", "end-sub", "comment-c", "data-B", 744 "end-root", "comment-d"], 745 events) 746
747 - def test_parser_target_pi(self):
748 events = [] 749 class Target(object): 750 def start(self, tag, attrib): 751 events.append("start-" + tag)
752 def end(self, tag): 753 events.append("end-" + tag) 754 def data(self, data): 755 events.append("data-" + data) 756 def pi(self, target, data): 757 events.append("pi-" + target + "-" + data) 758 def close(self): 759 return "DONE" 760 761 parser = self.etree.XMLParser(target=Target()) 762 763 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>')) 764 done = parser.close() 765 766 self.assertEquals("DONE", done) 767 self.assertEquals(["pi-test-a", "start-root", "data-A", "pi-test-b", 768 "data-B", "end-root", "pi-test-c"], 769 events) 770
771 - def test_parser_target_cdata(self):
772 events = [] 773 class Target(object): 774 def start(self, tag, attrib): 775 events.append("start-" + tag)
776 def end(self, tag): 777 events.append("end-" + tag) 778 def data(self, data): 779 events.append("data-" + data) 780 def close(self): 781 return "DONE" 782 783 parser = self.etree.XMLParser(target=Target(), 784 strip_cdata=False) 785 786 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>')) 787 done = parser.close() 788 789 self.assertEquals("DONE", done) 790 self.assertEquals(["start-root", "data-A", "start-a", 791 "data-ca", "end-a", "data-B", "end-root"], 792 events) 793
794 - def test_parser_target_recover(self):
795 events = [] 796 class Target(object): 797 def start(self, tag, attrib): 798 events.append("start-" + tag)
799 def end(self, tag): 800 events.append("end-" + tag) 801 def data(self, data): 802 events.append("data-" + data) 803 def close(self): 804 events.append("close") 805 return "DONE" 806 807 parser = self.etree.XMLParser(target=Target(), 808 recover=True) 809 810 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>')) 811 done = parser.close() 812 813 self.assertEquals("DONE", done) 814 self.assertEquals(["start-root", "data-A", "start-a", 815 "data-ca", "end-a", "data-B", 816 "end-root", "close"], 817 events) 818
819 - def test_iterwalk_tag(self):
820 iterwalk = self.etree.iterwalk 821 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 822 823 iterator = iterwalk(root, tag="b", events=('start', 'end')) 824 events = list(iterator) 825 self.assertEquals( 826 [('start', root[0]), ('end', root[0])], 827 events)
828
829 - def test_iterwalk_tag_all(self):
830 iterwalk = self.etree.iterwalk 831 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 832 833 iterator = iterwalk(root, tag="*", events=('start', 'end')) 834 events = list(iterator) 835 self.assertEquals( 836 8, 837 len(events))
838
839 - def test_iterwalk(self):
840 iterwalk = self.etree.iterwalk 841 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 842 843 events = list(iterwalk(root)) 844 self.assertEquals( 845 [('end', root[0]), ('end', root[1]), ('end', root)], 846 events)
847
848 - def test_iterwalk_start(self):
849 iterwalk = self.etree.iterwalk 850 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 851 852 iterator = iterwalk(root, events=('start',)) 853 events = list(iterator) 854 self.assertEquals( 855 [('start', root), ('start', root[0]), ('start', root[1])], 856 events)
857
858 - def test_iterwalk_start_end(self):
859 iterwalk = self.etree.iterwalk 860 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 861 862 iterator = iterwalk(root, events=('start','end')) 863 events = list(iterator) 864 self.assertEquals( 865 [('start', root), ('start', root[0]), ('end', root[0]), 866 ('start', root[1]), ('end', root[1]), ('end', root)], 867 events)
868
869 - def test_iterwalk_clear(self):
870 iterwalk = self.etree.iterwalk 871 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 872 873 iterator = iterwalk(root) 874 for event, elem in iterator: 875 elem.clear() 876 877 self.assertEquals(0, 878 len(root))
879
880 - def test_iterwalk_attrib_ns(self):
881 iterwalk = self.etree.iterwalk 882 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')) 883 884 attr_name = '{testns}bla' 885 events = [] 886 iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 887 for event, elem in iterator: 888 events.append(event) 889 if event == 'start': 890 if elem.tag != '{ns1}a': 891 elem.set(attr_name, 'value') 892 893 self.assertEquals( 894 ['start-ns', 'start', 'start', 'start-ns', 'start', 895 'end', 'end-ns', 'end', 'end', 'end-ns'], 896 events) 897 898 self.assertEquals( 899 None, 900 root.get(attr_name)) 901 self.assertEquals( 902 'value', 903 root[0].get(attr_name))
904
905 - def test_iterwalk_getiterator(self):
906 iterwalk = self.etree.iterwalk 907 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 908 909 counts = [] 910 for event, elem in iterwalk(root): 911 counts.append(len(list(elem.getiterator()))) 912 self.assertEquals( 913 [1,2,1,4], 914 counts)
915
916 - def test_resolve_string_dtd(self):
917 parse = self.etree.parse 918 parser = self.etree.XMLParser(dtd_validation=True) 919 assertEqual = self.assertEqual 920 test_url = _str("__nosuch.dtd") 921 922 class MyResolver(self.etree.Resolver): 923 def resolve(self, url, id, context): 924 assertEqual(url, test_url) 925 return self.resolve_string( 926 _str('''<!ENTITY myentity "%s"> 927 <!ELEMENT doc ANY>''') % url, context)
928 929 parser.resolvers.add(MyResolver()) 930 931 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 932 tree = parse(StringIO(xml), parser) 933 root = tree.getroot() 934 self.assertEquals(root.text, test_url) 935
936 - def test_resolve_bytes_dtd(self):
937 parse = self.etree.parse 938 parser = self.etree.XMLParser(dtd_validation=True) 939 assertEqual = self.assertEqual 940 test_url = _str("__nosuch.dtd") 941 942 class MyResolver(self.etree.Resolver): 943 def resolve(self, url, id, context): 944 assertEqual(url, test_url) 945 return self.resolve_string( 946 (_str('''<!ENTITY myentity "%s"> 947 <!ELEMENT doc ANY>''') % url).encode('utf-8'), 948 context)
949 950 parser.resolvers.add(MyResolver()) 951 952 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 953 tree = parse(StringIO(xml), parser) 954 root = tree.getroot() 955 self.assertEquals(root.text, test_url) 956
957 - def test_resolve_filelike_dtd(self):
958 parse = self.etree.parse 959 parser = self.etree.XMLParser(dtd_validation=True) 960 assertEqual = self.assertEqual 961 test_url = _str("__nosuch.dtd") 962 963 class MyResolver(self.etree.Resolver): 964 def resolve(self, url, id, context): 965 assertEqual(url, test_url) 966 return self.resolve_file( 967 SillyFileLike( 968 _str('''<!ENTITY myentity "%s"> 969 <!ELEMENT doc ANY>''') % url), context)
970 971 parser.resolvers.add(MyResolver()) 972 973 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 974 tree = parse(StringIO(xml), parser) 975 root = tree.getroot() 976 self.assertEquals(root.text, test_url) 977
978 - def test_resolve_filename_dtd(self):
979 parse = self.etree.parse 980 parser = self.etree.XMLParser(attribute_defaults=True) 981 assertEqual = self.assertEqual 982 test_url = _str("__nosuch.dtd") 983 984 class MyResolver(self.etree.Resolver): 985 def resolve(self, url, id, context): 986 assertEqual(url, test_url) 987 return self.resolve_filename( 988 fileInTestDir('test.dtd'), context)
989 990 parser.resolvers.add(MyResolver()) 991 992 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 993 tree = parse(StringIO(xml), parser) 994 root = tree.getroot() 995 self.assertEquals( 996 root.attrib, {'default': 'valueA'}) 997 self.assertEquals( 998 root[0].attrib, {'default': 'valueB'}) 999
1000 - def test_resolve_filename_dtd_relative(self):
1001 parse = self.etree.parse 1002 parser = self.etree.XMLParser(attribute_defaults=True) 1003 assertEqual = self.assertEqual 1004 test_url = _str("__nosuch.dtd") 1005 1006 class MyResolver(self.etree.Resolver): 1007 def resolve(self, url, id, context): 1008 assertEqual(url, fileInTestDir(test_url)) 1009 return self.resolve_filename( 1010 fileInTestDir('test.dtd'), context)
1011 1012 parser.resolvers.add(MyResolver()) 1013 1014 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1015 tree = parse(StringIO(xml), parser, 1016 base_url=fileInTestDir('__test.xml')) 1017 root = tree.getroot() 1018 self.assertEquals( 1019 root.attrib, {'default': 'valueA'}) 1020 self.assertEquals( 1021 root[0].attrib, {'default': 'valueB'}) 1022
1023 - def test_resolve_file_dtd(self):
1024 parse = self.etree.parse 1025 parser = self.etree.XMLParser(attribute_defaults=True) 1026 assertEqual = self.assertEqual 1027 test_url = _str("__nosuch.dtd") 1028 1029 class MyResolver(self.etree.Resolver): 1030 def resolve(self, url, id, context): 1031 assertEqual(url, test_url) 1032 return self.resolve_file( 1033 open(fileInTestDir('test.dtd'), 'rb'), context)
1034 1035 parser.resolvers.add(MyResolver()) 1036 1037 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1038 tree = parse(StringIO(xml), parser) 1039 root = tree.getroot() 1040 self.assertEquals( 1041 root.attrib, {'default': 'valueA'}) 1042 self.assertEquals( 1043 root[0].attrib, {'default': 'valueB'}) 1044
1045 - def test_resolve_empty(self):
1046 parse = self.etree.parse 1047 parser = self.etree.XMLParser(load_dtd=True) 1048 assertEqual = self.assertEqual 1049 test_url = _str("__nosuch.dtd") 1050 1051 class check(object): 1052 resolved = False
1053 1054 class MyResolver(self.etree.Resolver): 1055 def resolve(self, url, id, context): 1056 assertEqual(url, test_url) 1057 check.resolved = True 1058 return self.resolve_empty(context) 1059 1060 parser.resolvers.add(MyResolver()) 1061 1062 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1063 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 1064 self.assert_(check.resolved) 1065
1066 - def test_resolve_error(self):
1067 parse = self.etree.parse 1068 parser = self.etree.XMLParser(dtd_validation=True) 1069 1070 class _LocalException(Exception): 1071 pass
1072 1073 class MyResolver(self.etree.Resolver): 1074 def resolve(self, url, id, context): 1075 raise _LocalException 1076 1077 parser.resolvers.add(MyResolver()) 1078 1079 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 1080 self.assertRaises(_LocalException, parse, BytesIO(xml), parser) 1081 1082 if etree.LIBXML_VERSION > (2,6,20):
1083 - def test_entity_parse(self):
1084 parse = self.etree.parse 1085 tostring = self.etree.tostring 1086 parser = self.etree.XMLParser(resolve_entities=False) 1087 Entity = self.etree.Entity 1088 1089 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>') 1090 tree = parse(BytesIO(xml), parser) 1091 root = tree.getroot() 1092 self.assertEquals(root[0].tag, Entity) 1093 self.assertEquals(root[0].text, "&myentity;") 1094 self.assertEquals(root[0].tail, None) 1095 self.assertEquals(root[0].name, "myentity") 1096 1097 self.assertEquals(_bytes('<doc>&myentity;</doc>'), 1098 tostring(root))
1099
1100 - def test_entity_restructure(self):
1101 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp "&#160;"> ]> 1102 <root> 1103 <child1/> 1104 <child2/> 1105 <child3>&nbsp;</child3> 1106 </root>''') 1107 1108 parser = self.etree.XMLParser(resolve_entities=False) 1109 root = etree.fromstring(xml, parser) 1110 self.assertEquals([ el.tag for el in root ], 1111 ['child1', 'child2', 'child3']) 1112 1113 root[0] = root[-1] 1114 self.assertEquals([ el.tag for el in root ], 1115 ['child3', 'child2']) 1116 self.assertEquals(root[0][0].text, '&nbsp;') 1117 self.assertEquals(root[0][0].name, 'nbsp')
1118
1119 - def test_entity_append(self):
1120 Entity = self.etree.Entity 1121 Element = self.etree.Element 1122 tostring = self.etree.tostring 1123 1124 root = Element("root") 1125 root.append( Entity("test") ) 1126 1127 self.assertEquals(root[0].tag, Entity) 1128 self.assertEquals(root[0].text, "&test;") 1129 self.assertEquals(root[0].tail, None) 1130 self.assertEquals(root[0].name, "test") 1131 1132 self.assertEquals(_bytes('<root>&test;</root>'), 1133 tostring(root))
1134
1135 - def test_entity_values(self):
1136 Entity = self.etree.Entity 1137 self.assertEquals(Entity("test").text, '&test;') 1138 self.assertEquals(Entity("#17683").text, '&#17683;') 1139 self.assertEquals(Entity("#x1768").text, '&#x1768;') 1140 self.assertEquals(Entity("#x98AF").text, '&#x98AF;')
1141
1142 - def test_entity_error(self):
1143 Entity = self.etree.Entity 1144 self.assertRaises(ValueError, Entity, 'a b c') 1145 self.assertRaises(ValueError, Entity, 'a,b') 1146 self.assertRaises(ValueError, Entity, 'a\0b') 1147 self.assertRaises(ValueError, Entity, '#abc') 1148 self.assertRaises(ValueError, Entity, '#xxyz')
1149
1150 - def test_cdata(self):
1151 CDATA = self.etree.CDATA 1152 Element = self.etree.Element 1153 tostring = self.etree.tostring 1154 1155 root = Element("root") 1156 root.text = CDATA('test') 1157 1158 self.assertEquals('test', 1159 root.text) 1160 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 1161 tostring(root))
1162
1163 - def test_cdata_type(self):
1164 CDATA = self.etree.CDATA 1165 Element = self.etree.Element 1166 root = Element("root") 1167 1168 root.text = CDATA("test") 1169 self.assertEquals('test', root.text) 1170 1171 root.text = CDATA(_str("test")) 1172 self.assertEquals('test', root.text) 1173 1174 self.assertRaises(TypeError, CDATA, 1)
1175
1176 - def test_cdata_errors(self):
1177 CDATA = self.etree.CDATA 1178 Element = self.etree.Element 1179 1180 root = Element("root") 1181 cdata = CDATA('test') 1182 1183 self.assertRaises(TypeError, 1184 setattr, root, 'tail', cdata) 1185 self.assertRaises(TypeError, 1186 root.set, 'attr', cdata) 1187 self.assertRaises(TypeError, 1188 operator.setitem, root.attrib, 'attr', cdata)
1189
1190 - def test_cdata_parser(self):
1191 tostring = self.etree.tostring 1192 parser = self.etree.XMLParser(strip_cdata=False) 1193 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1194 1195 self.assertEquals('test', root.text) 1196 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 1197 tostring(root))
1198
1199 - def test_cdata_xpath(self):
1200 tostring = self.etree.tostring 1201 parser = self.etree.XMLParser(strip_cdata=False) 1202 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1203 self.assertEquals(_bytes('<root><![CDATA[test]]></root>'), 1204 tostring(root)) 1205 1206 self.assertEquals(['test'], root.xpath('//text()'))
1207 1208 # TypeError in etree, AssertionError in ElementTree;
1209 - def test_setitem_assert(self):
1210 Element = self.etree.Element 1211 SubElement = self.etree.SubElement 1212 1213 a = Element('a') 1214 b = SubElement(a, 'b') 1215 1216 self.assertRaises(TypeError, 1217 a.__setitem__, 0, 'foo')
1218
1219 - def test_append_None(self):
1220 # raises AssertionError in ElementTree 1221 Element = self.etree.Element 1222 self.assertRaises(TypeError, Element('a').append, None)
1223
1224 - def test_addnext(self):
1225 Element = self.etree.Element 1226 SubElement = self.etree.SubElement 1227 root = Element('root') 1228 SubElement(root, 'a') 1229 SubElement(root, 'b') 1230 1231 self.assertEquals(['a', 'b'], 1232 [c.tag for c in root]) 1233 root[1].addnext(root[0]) 1234 self.assertEquals(['b', 'a'], 1235 [c.tag for c in root])
1236
1237 - def test_addprevious(self):
1238 Element = self.etree.Element 1239 SubElement = self.etree.SubElement 1240 root = Element('root') 1241 SubElement(root, 'a') 1242 SubElement(root, 'b') 1243 1244 self.assertEquals(['a', 'b'], 1245 [c.tag for c in root]) 1246 root[0].addprevious(root[1]) 1247 self.assertEquals(['b', 'a'], 1248 [c.tag for c in root])
1249
1250 - def test_addnext_root(self):
1251 Element = self.etree.Element 1252 a = Element('a') 1253 b = Element('b') 1254 self.assertRaises(TypeError, a.addnext, b)
1255
1256 - def test_addnext_root(self):
1257 Element = self.etree.Element 1258 a = Element('a') 1259 b = Element('b') 1260 self.assertRaises(TypeError, a.addnext, b)
1261
1262 - def test_addprevious_pi(self):
1263 Element = self.etree.Element 1264 SubElement = self.etree.SubElement 1265 PI = self.etree.PI 1266 root = Element('root') 1267 SubElement(root, 'a') 1268 pi = PI('TARGET', 'TEXT') 1269 pi.tail = "TAIL" 1270 1271 self.assertEquals(_bytes('<root><a></a></root>'), 1272 self._writeElement(root)) 1273 root[0].addprevious(pi) 1274 self.assertEquals(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 1275 self._writeElement(root))
1276
1277 - def test_addprevious_root_pi(self):
1278 Element = self.etree.Element 1279 PI = self.etree.PI 1280 root = Element('root') 1281 pi = PI('TARGET', 'TEXT') 1282 pi.tail = "TAIL" 1283 1284 self.assertEquals(_bytes('<root></root>'), 1285 self._writeElement(root)) 1286 root.addprevious(pi) 1287 self.assertEquals(_bytes('<?TARGET TEXT?>\n<root></root>'), 1288 self._writeElement(root))
1289
1290 - def test_addnext_pi(self):
1291 Element = self.etree.Element 1292 SubElement = self.etree.SubElement 1293 PI = self.etree.PI 1294 root = Element('root') 1295 SubElement(root, 'a') 1296 pi = PI('TARGET', 'TEXT') 1297 pi.tail = "TAIL" 1298 1299 self.assertEquals(_bytes('<root><a></a></root>'), 1300 self._writeElement(root)) 1301 root[0].addnext(pi) 1302 self.assertEquals(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 1303 self._writeElement(root))
1304
1305 - def test_addnext_root_pi(self):
1306 Element = self.etree.Element 1307 PI = self.etree.PI 1308 root = Element('root') 1309 pi = PI('TARGET', 'TEXT') 1310 pi.tail = "TAIL" 1311 1312 self.assertEquals(_bytes('<root></root>'), 1313 self._writeElement(root)) 1314 root.addnext(pi) 1315 self.assertEquals(_bytes('<root></root>\n<?TARGET TEXT?>'), 1316 self._writeElement(root))
1317
1318 - def test_addnext_comment(self):
1319 Element = self.etree.Element 1320 SubElement = self.etree.SubElement 1321 Comment = self.etree.Comment 1322 root = Element('root') 1323 SubElement(root, 'a') 1324 comment = Comment('TEXT ') 1325 comment.tail = "TAIL" 1326 1327 self.assertEquals(_bytes('<root><a></a></root>'), 1328 self._writeElement(root)) 1329 root[0].addnext(comment) 1330 self.assertEquals(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 1331 self._writeElement(root))
1332
1333 - def test_addnext_root_comment(self):
1334 Element = self.etree.Element 1335 Comment = self.etree.Comment 1336 root = Element('root') 1337 comment = Comment('TEXT ') 1338 comment.tail = "TAIL" 1339 1340 self.assertEquals(_bytes('<root></root>'), 1341 self._writeElement(root)) 1342 root.addnext(comment) 1343 self.assertEquals(_bytes('<root></root>\n<!--TEXT -->'), 1344 self._writeElement(root))
1345
1346 - def test_addprevious_comment(self):
1347 Element = self.etree.Element 1348 SubElement = self.etree.SubElement 1349 Comment = self.etree.Comment 1350 root = Element('root') 1351 SubElement(root, 'a') 1352 comment = Comment('TEXT ') 1353 comment.tail = "TAIL" 1354 1355 self.assertEquals(_bytes('<root><a></a></root>'), 1356 self._writeElement(root)) 1357 root[0].addprevious(comment) 1358 self.assertEquals(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 1359 self._writeElement(root))
1360
1361 - def test_addprevious_root_comment(self):
1362 Element = self.etree.Element 1363 Comment = self.etree.Comment 1364 root = Element('root') 1365 comment = Comment('TEXT ') 1366 comment.tail = "TAIL" 1367 1368 self.assertEquals(_bytes('<root></root>'), 1369 self._writeElement(root)) 1370 root.addprevious(comment) 1371 self.assertEquals(_bytes('<!--TEXT -->\n<root></root>'), 1372 self._writeElement(root))
1373 1374 # ET's Elements have items() and key(), but not values()
1375 - def test_attribute_values(self):
1376 XML = self.etree.XML 1377 1378 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 1379 values = root.values() 1380 values.sort() 1381 self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
1382 1383 # gives error in ElementTree
1384 - def test_comment_empty(self):
1385 Element = self.etree.Element 1386 Comment = self.etree.Comment 1387 1388 a = Element('a') 1389 a.append(Comment()) 1390 self.assertEquals( 1391 _bytes('<a><!----></a>'), 1392 self._writeElement(a))
1393 1394 # ElementTree ignores comments
1395 - def test_comment_parse_empty(self):
1396 ElementTree = self.etree.ElementTree 1397 tostring = self.etree.tostring 1398 1399 xml = _bytes('<a><b/><!----><c/></a>') 1400 f = BytesIO(xml) 1401 doc = ElementTree(file=f) 1402 a = doc.getroot() 1403 self.assertEquals( 1404 '', 1405 a[1].text) 1406 self.assertEquals( 1407 xml, 1408 tostring(a))
1409 1410 # ElementTree ignores comments
1411 - def test_comment_no_proxy_yet(self):
1412 ElementTree = self.etree.ElementTree 1413 1414 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 1415 doc = ElementTree(file=f) 1416 a = doc.getroot() 1417 self.assertEquals( 1418 ' hoi ', 1419 a[1].text)
1420 1421 # does not raise an exception in ElementTree
1422 - def test_comment_immutable(self):
1423 Element = self.etree.Element 1424 Comment = self.etree.Comment 1425 1426 c = Comment() 1427 el = Element('myel') 1428 1429 self.assertRaises(TypeError, c.append, el) 1430 self.assertRaises(TypeError, c.insert, 0, el) 1431 self.assertRaises(TypeError, c.set, "myattr", "test")
1432 1433 # test passing 'None' to dump
1434 - def test_dump_none(self):
1435 self.assertRaises(TypeError, self.etree.dump, None)
1436
1437 - def test_prefix(self):
1438 ElementTree = self.etree.ElementTree 1439 1440 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 1441 doc = ElementTree(file=f) 1442 a = doc.getroot() 1443 self.assertEquals( 1444 None, 1445 a.prefix) 1446 self.assertEquals( 1447 'foo', 1448 a[0].prefix)
1449
1450 - def test_prefix_default_ns(self):
1451 ElementTree = self.etree.ElementTree 1452 1453 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 1454 doc = ElementTree(file=f) 1455 a = doc.getroot() 1456 self.assertEquals( 1457 None, 1458 a.prefix) 1459 self.assertEquals( 1460 None, 1461 a[0].prefix)
1462
1463 - def test_getparent(self):
1464 Element = self.etree.Element 1465 SubElement = self.etree.SubElement 1466 1467 a = Element('a') 1468 b = SubElement(a, 'b') 1469 c = SubElement(a, 'c') 1470 d = SubElement(b, 'd') 1471 self.assertEquals( 1472 None, 1473 a.getparent()) 1474 self.assertEquals( 1475 a, 1476 b.getparent()) 1477 self.assertEquals( 1478 b.getparent(), 1479 c.getparent()) 1480 self.assertEquals( 1481 b, 1482 d.getparent())
1483
1484 - def test_iterchildren(self):
1485 XML = self.etree.XML 1486 1487 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1488 result = [] 1489 for el in root.iterchildren(): 1490 result.append(el.tag) 1491 self.assertEquals(['one', 'two', 'three'], result)
1492
1493 - def test_iterchildren_reversed(self):
1494 XML = self.etree.XML 1495 1496 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1497 result = [] 1498 for el in root.iterchildren(reversed=True): 1499 result.append(el.tag) 1500 self.assertEquals(['three', 'two', 'one'], result)
1501
1502 - def test_iterchildren_tag(self):
1503 XML = self.etree.XML 1504 1505 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1506 result = [] 1507 for el in root.iterchildren(tag='two'): 1508 result.append(el.text) 1509 self.assertEquals(['Two', 'Bla'], result)
1510
1511 - def test_iterchildren_tag_reversed(self):
1512 XML = self.etree.XML 1513 1514 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1515 result = [] 1516 for el in root.iterchildren(reversed=True, tag='two'): 1517 result.append(el.text) 1518 self.assertEquals(['Bla', 'Two'], result)
1519
1520 - def test_iterancestors(self):
1521 Element = self.etree.Element 1522 SubElement = self.etree.SubElement 1523 1524 a = Element('a') 1525 b = SubElement(a, 'b') 1526 c = SubElement(a, 'c') 1527 d = SubElement(b, 'd') 1528 self.assertEquals( 1529 [], 1530 list(a.iterancestors())) 1531 self.assertEquals( 1532 [a], 1533 list(b.iterancestors())) 1534 self.assertEquals( 1535 [a], 1536 list(c.iterancestors())) 1537 self.assertEquals( 1538 [b, a], 1539 list(d.iterancestors()))
1540
1541 - def test_iterancestors_tag(self):
1542 Element = self.etree.Element 1543 SubElement = self.etree.SubElement 1544 1545 a = Element('a') 1546 b = SubElement(a, 'b') 1547 c = SubElement(a, 'c') 1548 d = SubElement(b, 'd') 1549 self.assertEquals( 1550 [a], 1551 list(d.iterancestors(tag='a')))
1552
1553 - def test_iterdescendants(self):
1554 Element = self.etree.Element 1555 SubElement = self.etree.SubElement 1556 1557 a = Element('a') 1558 b = SubElement(a, 'b') 1559 c = SubElement(a, 'c') 1560 d = SubElement(b, 'd') 1561 e = SubElement(c, 'e') 1562 1563 self.assertEquals( 1564 [b, d, c, e], 1565 list(a.iterdescendants())) 1566 self.assertEquals( 1567 [], 1568 list(d.iterdescendants()))
1569
1570 - def test_iterdescendants_tag(self):
1571 Element = self.etree.Element 1572 SubElement = self.etree.SubElement 1573 1574 a = Element('a') 1575 b = SubElement(a, 'b') 1576 c = SubElement(a, 'c') 1577 d = SubElement(b, 'd') 1578 e = SubElement(c, 'e') 1579 1580 self.assertEquals( 1581 [], 1582 list(a.iterdescendants('a'))) 1583 a2 = SubElement(e, 'a') 1584 self.assertEquals( 1585 [a2], 1586 list(a.iterdescendants('a'))) 1587 self.assertEquals( 1588 [a2], 1589 list(c.iterdescendants('a')))
1590
1591 - def test_getroottree(self):
1592 Element = self.etree.Element 1593 SubElement = self.etree.SubElement 1594 1595 a = Element('a') 1596 b = SubElement(a, 'b') 1597 c = SubElement(a, 'c') 1598 d = SubElement(b, 'd') 1599 self.assertEquals( 1600 a, 1601 a.getroottree().getroot()) 1602 self.assertEquals( 1603 a, 1604 b.getroottree().getroot()) 1605 self.assertEquals( 1606 a, 1607 d.getroottree().getroot())
1608
1609 - def test_getnext(self):
1610 Element = self.etree.Element 1611 SubElement = self.etree.SubElement 1612 1613 a = Element('a') 1614 b = SubElement(a, 'b') 1615 c = SubElement(a, 'c') 1616 self.assertEquals( 1617 None, 1618 a.getnext()) 1619 self.assertEquals( 1620 c, 1621 b.getnext()) 1622 self.assertEquals( 1623 None, 1624 c.getnext())
1625
1626 - def test_getprevious(self):
1627 Element = self.etree.Element 1628 SubElement = self.etree.SubElement 1629 1630 a = Element('a') 1631 b = SubElement(a, 'b') 1632 c = SubElement(a, 'c') 1633 d = SubElement(b, 'd') 1634 self.assertEquals( 1635 None, 1636 a.getprevious()) 1637 self.assertEquals( 1638 b, 1639 c.getprevious()) 1640 self.assertEquals( 1641 None, 1642 b.getprevious())
1643
1644 - def test_itersiblings(self):
1645 Element = self.etree.Element 1646 SubElement = self.etree.SubElement 1647 1648 a = Element('a') 1649 b = SubElement(a, 'b') 1650 c = SubElement(a, 'c') 1651 d = SubElement(b, 'd') 1652 self.assertEquals( 1653 [], 1654 list(a.itersiblings())) 1655 self.assertEquals( 1656 [c], 1657 list(b.itersiblings())) 1658 self.assertEquals( 1659 [], 1660 list(c.itersiblings())) 1661 self.assertEquals( 1662 [b], 1663 list(c.itersiblings(preceding=True))) 1664 self.assertEquals( 1665 [], 1666 list(b.itersiblings(preceding=True)))
1667
1668 - def test_itersiblings_tag(self):
1669 Element = self.etree.Element 1670 SubElement = self.etree.SubElement 1671 1672 a = Element('a') 1673 b = SubElement(a, 'b') 1674 c = SubElement(a, 'c') 1675 d = SubElement(b, 'd') 1676 self.assertEquals( 1677 [], 1678 list(a.itersiblings(tag='XXX'))) 1679 self.assertEquals( 1680 [c], 1681 list(b.itersiblings(tag='c'))) 1682 self.assertEquals( 1683 [b], 1684 list(c.itersiblings(preceding=True, tag='b'))) 1685 self.assertEquals( 1686 [], 1687 list(c.itersiblings(preceding=True, tag='c')))
1688
1689 - def test_parseid(self):
1690 parseid = self.etree.parseid 1691 XML = self.etree.XML 1692 xml_text = _bytes(''' 1693 <!DOCTYPE document [ 1694 <!ELEMENT document (h1,p)*> 1695 <!ELEMENT h1 (#PCDATA)> 1696 <!ATTLIST h1 myid ID #REQUIRED> 1697 <!ELEMENT p (#PCDATA)> 1698 <!ATTLIST p someid ID #REQUIRED> 1699 ]> 1700 <document> 1701 <h1 myid="chapter1">...</h1> 1702 <p id="note1" class="note">...</p> 1703 <p>Regular paragraph.</p> 1704 <p xml:id="xmlid">XML:ID paragraph.</p> 1705 <p someid="warn1" class="warning">...</p> 1706 </document> 1707 ''') 1708 1709 tree, dic = parseid(BytesIO(xml_text)) 1710 root = tree.getroot() 1711 root2 = XML(xml_text) 1712 self.assertEquals(self._writeElement(root), 1713 self._writeElement(root2)) 1714 expected = { 1715 "chapter1" : root[0], 1716 "xmlid" : root[3], 1717 "warn1" : root[4] 1718 } 1719 self.assert_("chapter1" in dic) 1720 self.assert_("warn1" in dic) 1721 self.assert_("xmlid" in dic) 1722 self._checkIDDict(dic, expected)
1723
1724 - def test_XMLDTDID(self):
1725 XMLDTDID = self.etree.XMLDTDID 1726 XML = self.etree.XML 1727 xml_text = _bytes(''' 1728 <!DOCTYPE document [ 1729 <!ELEMENT document (h1,p)*> 1730 <!ELEMENT h1 (#PCDATA)> 1731 <!ATTLIST h1 myid ID #REQUIRED> 1732 <!ELEMENT p (#PCDATA)> 1733 <!ATTLIST p someid ID #REQUIRED> 1734 ]> 1735 <document> 1736 <h1 myid="chapter1">...</h1> 1737 <p id="note1" class="note">...</p> 1738 <p>Regular paragraph.</p> 1739 <p xml:id="xmlid">XML:ID paragraph.</p> 1740 <p someid="warn1" class="warning">...</p> 1741 </document> 1742 ''') 1743 1744 root, dic = XMLDTDID(xml_text) 1745 root2 = XML(xml_text) 1746 self.assertEquals(self._writeElement(root), 1747 self._writeElement(root2)) 1748 expected = { 1749 "chapter1" : root[0], 1750 "xmlid" : root[3], 1751 "warn1" : root[4] 1752 } 1753 self.assert_("chapter1" in dic) 1754 self.assert_("warn1" in dic) 1755 self.assert_("xmlid" in dic) 1756 self._checkIDDict(dic, expected)
1757
1758 - def test_XMLDTDID_empty(self):
1759 XMLDTDID = self.etree.XMLDTDID 1760 XML = self.etree.XML 1761 xml_text = _bytes(''' 1762 <document> 1763 <h1 myid="chapter1">...</h1> 1764 <p id="note1" class="note">...</p> 1765 <p>Regular paragraph.</p> 1766 <p someid="warn1" class="warning">...</p> 1767 </document> 1768 ''') 1769 1770 root, dic = XMLDTDID(xml_text) 1771 root2 = XML(xml_text) 1772 self.assertEquals(self._writeElement(root), 1773 self._writeElement(root2)) 1774 expected = {} 1775 self._checkIDDict(dic, expected)
1776
1777 - def _checkIDDict(self, dic, expected):
1778 self.assertEquals(len(dic), 1779 len(expected)) 1780 self.assertEquals(sorted(dic.items()), 1781 sorted(expected.items())) 1782 if sys.version_info < (3,): 1783 self.assertEquals(sorted(dic.iteritems()), 1784 sorted(expected.iteritems())) 1785 self.assertEquals(sorted(dic.keys()), 1786 sorted(expected.keys())) 1787 if sys.version_info < (3,): 1788 self.assertEquals(sorted(dic.iterkeys()), 1789 sorted(expected.iterkeys())) 1790 if sys.version_info < (3,): 1791 self.assertEquals(sorted(dic.values()), 1792 sorted(expected.values())) 1793 self.assertEquals(sorted(dic.itervalues()), 1794 sorted(expected.itervalues()))
1795
1796 - def test_namespaces(self):
1797 etree = self.etree 1798 1799 r = {'foo': 'http://ns.infrae.com/foo'} 1800 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1801 self.assertEquals( 1802 'foo', 1803 e.prefix) 1804 self.assertEquals( 1805 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 1806 self._writeElement(e))
1807
1808 - def test_namespaces_default(self):
1809 etree = self.etree 1810 1811 r = {None: 'http://ns.infrae.com/foo'} 1812 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1813 self.assertEquals( 1814 None, 1815 e.prefix) 1816 self.assertEquals( 1817 '{http://ns.infrae.com/foo}bar', 1818 e.tag) 1819 self.assertEquals( 1820 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 1821 self._writeElement(e))
1822
1823 - def test_namespaces_default_and_attr(self):
1824 etree = self.etree 1825 1826 r = {None: 'http://ns.infrae.com/foo', 1827 'hoi': 'http://ns.infrae.com/hoi'} 1828 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1829 e.set('{http://ns.infrae.com/hoi}test', 'value') 1830 self.assertEquals( 1831 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 1832 self._writeElement(e))
1833
1834 - def test_namespaces_elementtree(self):
1835 etree = self.etree 1836 r = {None: 'http://ns.infrae.com/foo', 1837 'hoi': 'http://ns.infrae.com/hoi'} 1838 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 1839 tree = etree.ElementTree(element=e) 1840 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 1841 self.assertEquals( 1842 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 1843 self._writeElement(e))
1844
1845 - def test_namespaces_default_copy_element(self):
1846 etree = self.etree 1847 1848 r = {None: 'http://ns.infrae.com/foo'} 1849 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1850 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1851 1852 e1.append(e2) 1853 1854 self.assertEquals( 1855 None, 1856 e1.prefix) 1857 self.assertEquals( 1858 None, 1859 e1[0].prefix) 1860 self.assertEquals( 1861 '{http://ns.infrae.com/foo}bar', 1862 e1.tag) 1863 self.assertEquals( 1864 '{http://ns.infrae.com/foo}bar', 1865 e1[0].tag)
1866
1867 - def test_namespaces_copy_element(self):
1868 etree = self.etree 1869 1870 r = {None: 'http://ns.infrae.com/BAR'} 1871 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 1872 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1873 1874 e1.append(e2) 1875 1876 self.assertEquals( 1877 None, 1878 e1.prefix) 1879 self.assertNotEquals( 1880 None, 1881 e2.prefix) 1882 self.assertEquals( 1883 '{http://ns.infrae.com/BAR}bar', 1884 e1.tag) 1885 self.assertEquals( 1886 '{http://ns.infrae.com/foo}bar', 1887 e2.tag)
1888
1889 - def test_namespaces_reuse_after_move(self):
1890 ns_href = "http://a.b.c" 1891 one = self.etree.fromstring( 1892 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 1893 baz = one[0][0] 1894 1895 two = self.etree.fromstring( 1896 _bytes('<root xmlns:ns="%s"/>' % ns_href)) 1897 two.append(baz) 1898 del one # make sure the source document is deallocated 1899 1900 self.assertEquals('{%s}baz' % ns_href, baz.tag) 1901 self.assertEquals( 1902 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 1903 self.etree.tostring(two))
1904
1905 - def test_namespace_cleanup(self):
1906 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>') 1907 root = self.etree.fromstring(xml) 1908 self.assertEquals(xml, 1909 self.etree.tostring(root)) 1910 self.etree.cleanup_namespaces(root) 1911 self.assertEquals( 1912 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 1913 self.etree.tostring(root))
1914
1915 - def test_element_nsmap(self):
1916 etree = self.etree 1917 1918 r = {None: 'http://ns.infrae.com/foo', 1919 'hoi': 'http://ns.infrae.com/hoi'} 1920 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 1921 self.assertEquals( 1922 r, 1923 e.nsmap)
1924
1925 - def test_subelement_nsmap(self):
1926 etree = self.etree 1927 1928 re = {None: 'http://ns.infrae.com/foo', 1929 'hoi': 'http://ns.infrae.com/hoi'} 1930 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 1931 1932 rs = {None: 'http://ns.infrae.com/honk', 1933 'top': 'http://ns.infrae.com/top'} 1934 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 1935 1936 r = re.copy() 1937 r.update(rs) 1938 self.assertEquals( 1939 re, 1940 e.nsmap) 1941 self.assertEquals( 1942 r, 1943 s.nsmap)
1944
1945 - def test_getiterator_filter_namespace(self):
1946 Element = self.etree.Element 1947 SubElement = self.etree.SubElement 1948 1949 a = Element('{a}a') 1950 b = SubElement(a, '{a}b') 1951 c = SubElement(a, '{a}c') 1952 d = SubElement(b, '{b}d') 1953 e = SubElement(c, '{a}e') 1954 f = SubElement(c, '{b}f') 1955 1956 self.assertEquals( 1957 [a], 1958 list(a.getiterator('{a}a'))) 1959 self.assertEquals( 1960 [], 1961 list(a.getiterator('{b}a'))) 1962 self.assertEquals( 1963 [], 1964 list(a.getiterator('a'))) 1965 self.assertEquals( 1966 [f], 1967 list(c.getiterator('{b}*'))) 1968 self.assertEquals( 1969 [d, f], 1970 list(a.getiterator('{b}*')))
1971
1972 - def test_getiterator_filter_entities(self):
1973 Element = self.etree.Element 1974 Entity = self.etree.Entity 1975 SubElement = self.etree.SubElement 1976 1977 a = Element('a') 1978 b = SubElement(a, 'b') 1979 entity_b = Entity("TEST-b") 1980 b.append(entity_b) 1981 1982 self.assertEquals( 1983 [entity_b], 1984 list(a.getiterator(Entity))) 1985 1986 entity_a = Entity("TEST-a") 1987 a.append(entity_a) 1988 1989 self.assertEquals( 1990 [entity_b, entity_a], 1991 list(a.getiterator(Entity))) 1992 1993 self.assertEquals( 1994 [entity_b], 1995 list(b.getiterator(Entity)))
1996
1997 - def test_getiterator_filter_element(self):
1998 Element = self.etree.Element 1999 Comment = self.etree.Comment 2000 PI = self.etree.PI 2001 SubElement = self.etree.SubElement 2002 2003 a = Element('a') 2004 b = SubElement(a, 'b') 2005 a.append(Comment("test")) 2006 a.append(PI("pi", "content")) 2007 c = SubElement(a, 'c') 2008 2009 self.assertEquals( 2010 [a, b, c], 2011 list(a.getiterator(Element)))
2012
2013 - def test_getiterator_filter_all_comment_pi(self):
2014 # ElementTree iterates over everything here 2015 Element = self.etree.Element 2016 Comment = self.etree.Comment 2017 PI = self.etree.PI 2018 SubElement = self.etree.SubElement 2019 2020 a = Element('a') 2021 b = SubElement(a, 'b') 2022 a.append(Comment("test")) 2023 a.append(PI("pi", "content")) 2024 c = SubElement(a, 'c') 2025 2026 self.assertEquals( 2027 [a, b, c], 2028 list(a.getiterator('*')))
2029
2030 - def test_elementtree_find_qname(self):
2031 XML = self.etree.XML 2032 ElementTree = self.etree.ElementTree 2033 QName = self.etree.QName 2034 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 2035 self.assertEquals(tree.find(QName("c")), tree.getroot()[2])
2036
2037 - def test_elementtree_findall_qname(self):
2038 XML = self.etree.XML 2039 ElementTree = self.etree.ElementTree 2040 QName = self.etree.QName 2041 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 2042 self.assertEquals(len(list(tree.findall(QName("c")))), 1)
2043
2044 - def test_elementtree_findall_ns_qname(self):
2045 XML = self.etree.XML 2046 ElementTree = self.etree.ElementTree 2047 QName = self.etree.QName 2048 tree = ElementTree(XML( 2049 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))) 2050 self.assertEquals(len(list(tree.findall(QName("b")))), 2) 2051 self.assertEquals(len(list(tree.findall(QName("X", "b")))), 1)
2052
2053 - def test_findall_ns(self):
2054 XML = self.etree.XML 2055 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')) 2056 self.assertEquals(len(root.findall(".//{X}b")), 2) 2057 self.assertEquals(len(root.findall(".//{X}*")), 2) 2058 self.assertEquals(len(root.findall(".//b")), 3)
2059
2060 - def test_index(self):
2061 etree = self.etree 2062 e = etree.Element('foo') 2063 for i in range(10): 2064 etree.SubElement(e, 'a%s' % i) 2065 for i in range(10): 2066 self.assertEquals( 2067 i, 2068 e.index(e[i])) 2069 self.assertEquals( 2070 3, e.index(e[3], 3)) 2071 self.assertRaises( 2072 ValueError, e.index, e[3], 4) 2073 self.assertRaises( 2074 ValueError, e.index, e[3], 0, 2) 2075 self.assertRaises( 2076 ValueError, e.index, e[8], 0, -3) 2077 self.assertRaises( 2078 ValueError, e.index, e[8], -5, -3) 2079 self.assertEquals( 2080 8, e.index(e[8], 0, -1)) 2081 self.assertEquals( 2082 8, e.index(e[8], -12, -1)) 2083 self.assertEquals( 2084 0, e.index(e[0], -12, -1))
2085
2086 - def test_replace(self):
2087 etree = self.etree 2088 e = etree.Element('foo') 2089 for i in range(10): 2090 el = etree.SubElement(e, 'a%s' % i) 2091 el.text = "text%d" % i 2092 el.tail = "tail%d" % i 2093 2094 child0 = e[0] 2095 child1 = e[1] 2096 child2 = e[2] 2097 2098 e.replace(e[0], e[1]) 2099 self.assertEquals( 2100 9, len(e)) 2101 self.assertEquals( 2102 child1, e[0]) 2103 self.assertEquals( 2104 child1.text, "text1") 2105 self.assertEquals( 2106 child1.tail, "tail1") 2107 self.assertEquals( 2108 child0.tail, "tail0") 2109 self.assertEquals( 2110 child2, e[1]) 2111 2112 e.replace(e[-1], e[0]) 2113 self.assertEquals( 2114 child1, e[-1]) 2115 self.assertEquals( 2116 child1.text, "text1") 2117 self.assertEquals( 2118 child1.tail, "tail1") 2119 self.assertEquals( 2120 child2, e[0])
2121
2122 - def test_replace_new(self):
2123 etree = self.etree 2124 e = etree.Element('foo') 2125 for i in range(10): 2126 etree.SubElement(e, 'a%s' % i) 2127 2128 new_element = etree.Element("test") 2129 new_element.text = "TESTTEXT" 2130 new_element.tail = "TESTTAIL" 2131 child1 = e[1] 2132 e.replace(e[0], new_element) 2133 self.assertEquals( 2134 new_element, e[0]) 2135 self.assertEquals( 2136 "TESTTEXT", 2137 e[0].text) 2138 self.assertEquals( 2139 "TESTTAIL", 2140 e[0].tail) 2141 self.assertEquals( 2142 child1, e[1])
2143
2144 - def test_setslice_all_empty_reversed(self):
2145 Element = self.etree.Element 2146 SubElement = self.etree.SubElement 2147 2148 a = Element('a') 2149 2150 e = Element('e') 2151 f = Element('f') 2152 g = Element('g') 2153 2154 s = [e, f, g] 2155 a[::-1] = s 2156 self.assertEquals( 2157 [g, f, e], 2158 list(a))
2159
2160 - def test_setslice_step(self):
2161 Element = self.etree.Element 2162 SubElement = self.etree.SubElement 2163 2164 a = Element('a') 2165 b = SubElement(a, 'b') 2166 c = SubElement(a, 'c') 2167 d = SubElement(a, 'd') 2168 e = SubElement(a, 'e') 2169 2170 x = Element('x') 2171 y = Element('y') 2172 2173 a[1::2] = [x, y] 2174 self.assertEquals( 2175 [b, x, d, y], 2176 list(a))
2177
2178 - def test_setslice_step_negative(self):
2179 Element = self.etree.Element 2180 SubElement = self.etree.SubElement 2181 2182 a = Element('a') 2183 b = SubElement(a, 'b') 2184 c = SubElement(a, 'c') 2185 d = SubElement(a, 'd') 2186 e = SubElement(a, 'e') 2187 2188 x = Element('x') 2189 y = Element('y') 2190 2191 a[1::-1] = [x, y] 2192 self.assertEquals( 2193 [y, x, d, e], 2194 list(a))
2195
2196 - def test_setslice_step_negative2(self):
2197 Element = self.etree.Element 2198 SubElement = self.etree.SubElement 2199 2200 a = Element('a') 2201 b = SubElement(a, 'b') 2202 c = SubElement(a, 'c') 2203 d = SubElement(a, 'd') 2204 e = SubElement(a, 'e') 2205 2206 x = Element('x') 2207 y = Element('y') 2208 2209 a[::-2] = [x, y] 2210 self.assertEquals( 2211 [b, y, d, x], 2212 list(a))
2213
2214 - def test_setslice_step_overrun(self):
2215 Element = self.etree.Element 2216 SubElement = self.etree.SubElement 2217 try: 2218 slice 2219 except NameError: 2220 print("slice() not found") 2221 return 2222 2223 a = Element('a') 2224 b = SubElement(a, 'b') 2225 c = SubElement(a, 'c') 2226 d = SubElement(a, 'd') 2227 e = SubElement(a, 'e') 2228 2229 x = Element('x') 2230 y = Element('y') 2231 z = Element('z') 2232 2233 self.assertRaises( 2234 ValueError, 2235 operator.setitem, a, slice(1,None,2), [x, y, z]) 2236 2237 self.assertEquals( 2238 [b, c, d, e], 2239 list(a))
2240
2241 - def test_sourceline_XML(self):
2242 XML = self.etree.XML 2243 root = XML(_bytes('''<?xml version="1.0"?> 2244 <root><test> 2245 2246 <bla/></test> 2247 </root> 2248 ''')) 2249 2250 self.assertEquals( 2251 [2, 2, 4], 2252 [ el.sourceline for el in root.getiterator() ])
2253
2254 - def test_sourceline_parse(self):
2255 parse = self.etree.parse 2256 tree = parse(fileInTestDir('include/test_xinclude.xml')) 2257 2258 self.assertEquals( 2259 [1, 2, 3], 2260 [ el.sourceline for el in tree.getiterator() ])
2261
2262 - def test_sourceline_iterparse_end(self):
2263 iterparse = self.etree.iterparse 2264 lines = [ el.sourceline for (event, el) in 2265 iterparse(fileInTestDir('include/test_xinclude.xml')) ] 2266 2267 self.assertEquals( 2268 [2, 3, 1], 2269 lines)
2270
2271 - def test_sourceline_iterparse_start(self):
2272 iterparse = self.etree.iterparse 2273 lines = [ el.sourceline for (event, el) in 2274 iterparse(fileInTestDir('include/test_xinclude.xml'), 2275 events=("start",)) ] 2276 2277 self.assertEquals( 2278 [1, 2, 3], 2279 lines)
2280
2281 - def test_sourceline_element(self):
2282 Element = self.etree.Element 2283 SubElement = self.etree.SubElement 2284 el = Element("test") 2285 self.assertEquals(None, el.sourceline) 2286 2287 child = SubElement(el, "test") 2288 self.assertEquals(None, el.sourceline) 2289 self.assertEquals(None, child.sourceline)
2290
2291 - def test_XML_base_url_docinfo(self):
2292 etree = self.etree 2293 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2294 docinfo = root.getroottree().docinfo 2295 self.assertEquals(docinfo.URL, "http://no/such/url")
2296
2297 - def test_XML_set_base_url_docinfo(self):
2298 etree = self.etree 2299 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2300 docinfo = root.getroottree().docinfo 2301 self.assertEquals(docinfo.URL, "http://no/such/url") 2302 docinfo.URL = "https://secret/url" 2303 self.assertEquals(docinfo.URL, "https://secret/url")
2304
2305 - def test_parse_stringio_base_url(self):
2306 etree = self.etree 2307 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url") 2308 docinfo = tree.docinfo 2309 self.assertEquals(docinfo.URL, "http://no/such/url")
2310
2311 - def test_parse_base_url_docinfo(self):
2312 etree = self.etree 2313 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 2314 base_url="http://no/such/url") 2315 docinfo = tree.docinfo 2316 self.assertEquals(docinfo.URL, "http://no/such/url")
2317
2318 - def test_HTML_base_url_docinfo(self):
2319 etree = self.etree 2320 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url") 2321 docinfo = root.getroottree().docinfo 2322 self.assertEquals(docinfo.URL, "http://no/such/url")
2323
2324 - def test_docinfo_public(self):
2325 etree = self.etree 2326 xml_header = '<?xml version="1.0" encoding="ascii"?>' 2327 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 2328 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 2329 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 2330 2331 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 2332 2333 tree = etree.parse(BytesIO(xml)) 2334 docinfo = tree.docinfo 2335 self.assertEquals(docinfo.encoding, "ascii") 2336 self.assertEquals(docinfo.xml_version, "1.0") 2337 self.assertEquals(docinfo.public_id, pub_id) 2338 self.assertEquals(docinfo.system_url, sys_id) 2339 self.assertEquals(docinfo.root_name, 'html') 2340 self.assertEquals(docinfo.doctype, doctype_string)
2341
2342 - def test_docinfo_system(self):
2343 etree = self.etree 2344 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 2345 sys_id = "some.dtd" 2346 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 2347 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 2348 2349 tree = etree.parse(BytesIO(xml)) 2350 docinfo = tree.docinfo 2351 self.assertEquals(docinfo.encoding, "UTF-8") 2352 self.assertEquals(docinfo.xml_version, "1.0") 2353 self.assertEquals(docinfo.public_id, None) 2354 self.assertEquals(docinfo.system_url, sys_id) 2355 self.assertEquals(docinfo.root_name, 'html') 2356 self.assertEquals(docinfo.doctype, doctype_string)
2357
2358 - def test_docinfo_empty(self):
2359 etree = self.etree 2360 xml = _bytes('<html><body></body></html>') 2361 tree = etree.parse(BytesIO(xml)) 2362 docinfo = tree.docinfo 2363 self.assertEquals(docinfo.encoding, "UTF-8") 2364 self.assertEquals(docinfo.xml_version, "1.0") 2365 self.assertEquals(docinfo.public_id, None) 2366 self.assertEquals(docinfo.system_url, None) 2367 self.assertEquals(docinfo.root_name, 'html') 2368 self.assertEquals(docinfo.doctype, '')
2369
2370 - def test_docinfo_name_only(self):
2371 etree = self.etree 2372 xml = _bytes('<!DOCTYPE root><root></root>') 2373 tree = etree.parse(BytesIO(xml)) 2374 docinfo = tree.docinfo 2375 self.assertEquals(docinfo.encoding, "UTF-8") 2376 self.assertEquals(docinfo.xml_version, "1.0") 2377 self.assertEquals(docinfo.public_id, None) 2378 self.assertEquals(docinfo.system_url, None) 2379 self.assertEquals(docinfo.root_name, 'root') 2380 self.assertEquals(docinfo.doctype, '<!DOCTYPE root>')
2381
2382 - def test_doctype_name_only_roundtrip(self):
2383 etree = self.etree 2384 xml = _bytes('<!DOCTYPE root>\n<root/>') 2385 tree = etree.parse(BytesIO(xml)) 2386 self.assertEquals(xml, etree.tostring(tree))
2387
2388 - def test_xml_base(self):
2389 etree = self.etree 2390 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2391 self.assertEquals(root.base, "http://no/such/url") 2392 self.assertEquals( 2393 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 2394 root.base = "https://secret/url" 2395 self.assertEquals(root.base, "https://secret/url") 2396 self.assertEquals( 2397 root.get('{http://www.w3.org/XML/1998/namespace}base'), 2398 "https://secret/url")
2399
2400 - def test_xml_base_attribute(self):
2401 etree = self.etree 2402 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2403 self.assertEquals(root.base, "http://no/such/url") 2404 self.assertEquals( 2405 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 2406 root.set('{http://www.w3.org/XML/1998/namespace}base', 2407 "https://secret/url") 2408 self.assertEquals(root.base, "https://secret/url") 2409 self.assertEquals( 2410 root.get('{http://www.w3.org/XML/1998/namespace}base'), 2411 "https://secret/url")
2412
2413 - def test_html_base(self):
2414 etree = self.etree 2415 root = etree.HTML(_bytes("<html><body></body></html>"), 2416 base_url="http://no/such/url") 2417 self.assertEquals(root.base, "http://no/such/url")
2418
2419 - def test_html_base_tag(self):
2420 etree = self.etree 2421 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 2422 self.assertEquals(root.base, "http://no/such/url")
2423
2424 - def test_parse_fileobject_unicode(self):
2425 # parse from a file object that returns unicode strings 2426 f = LargeFileLikeUnicode() 2427 tree = self.etree.parse(f) 2428 root = tree.getroot() 2429 self.assert_(root.tag.endswith('root'))
2430
2431 - def test_dtd_io(self):
2432 # check that DTDs that go in also go back out 2433 xml = _bytes('''\ 2434 <!DOCTYPE test SYSTEM "test.dtd" [ 2435 <!ENTITY entity "tasty"> 2436 <!ELEMENT test (a)> 2437 <!ELEMENT a (#PCDATA)> 2438 ]> 2439 <test><a>test-test</a></test>\ 2440 ''') 2441 tree = self.etree.parse(BytesIO(xml)) 2442 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 2443 xml.replace(_bytes(" "), _bytes("")))
2444
2445 - def test_byte_zero(self):
2446 Element = self.etree.Element 2447 2448 a = Element('a') 2449 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 2450 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 2451 2452 self.assertRaises(ValueError, Element, 'ha\0ho')
2453
2454 - def test_unicode_byte_zero(self):
2455 Element = self.etree.Element 2456 2457 a = Element('a') 2458 self.assertRaises(ValueError, setattr, a, "text", 2459 _str('ha\0ho')) 2460 self.assertRaises(ValueError, setattr, a, "tail", 2461 _str('ha\0ho')) 2462 2463 self.assertRaises(ValueError, Element, 2464 _str('ha\0ho'))
2465
2466 - def test_byte_invalid(self):
2467 Element = self.etree.Element 2468 2469 a = Element('a') 2470 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 2471 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 2472 2473 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 2474 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 2475 2476 self.assertRaises(ValueError, Element, 'ha\x07ho') 2477 self.assertRaises(ValueError, Element, 'ha\x02ho')
2478
2479 - def test_unicode_byte_invalid(self):
2480 Element = self.etree.Element 2481 2482 a = Element('a') 2483 self.assertRaises(ValueError, setattr, a, "text", 2484 _str('ha\x07ho')) 2485 self.assertRaises(ValueError, setattr, a, "text", 2486 _str('ha\x02ho')) 2487 2488 self.assertRaises(ValueError, setattr, a, "tail", 2489 _str('ha\x07ho')) 2490 self.assertRaises(ValueError, setattr, a, "tail", 2491 _str('ha\x02ho')) 2492 2493 self.assertRaises(ValueError, Element, 2494 _str('ha\x07ho')) 2495 self.assertRaises(ValueError, Element, 2496 _str('ha\x02ho'))
2497
2498 - def test_unicode_byte_invalid_sequence(self):
2499 Element = self.etree.Element 2500 2501 a = Element('a') 2502 self.assertRaises(ValueError, setattr, a, "text", 2503 _str('ha\u1234\x07ho')) 2504 self.assertRaises(ValueError, setattr, a, "text", 2505 _str('ha\u1234\x02ho')) 2506 2507 self.assertRaises(ValueError, setattr, a, "tail", 2508 _str('ha\u1234\x07ho')) 2509 self.assertRaises(ValueError, setattr, a, "tail", 2510 _str('ha\u1234\x02ho')) 2511 2512 self.assertRaises(ValueError, Element, 2513 _str('ha\u1234\x07ho')) 2514 self.assertRaises(ValueError, Element, 2515 _str('ha\u1234\x02ho'))
2516
2517 - def test_encoding_tostring_utf16(self):
2518 # ElementTree fails to serialize this 2519 tostring = self.etree.tostring 2520 Element = self.etree.Element 2521 SubElement = self.etree.SubElement 2522 2523 a = Element('a') 2524 b = SubElement(a, 'b') 2525 c = SubElement(a, 'c') 2526 2527 result = tostring(a, encoding='UTF-16') 2528 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2529 canonicalize(result))
2530
2531 - def test_tostring_none(self):
2532 # ElementTree raises an AssertionError here 2533 tostring = self.etree.tostring 2534 self.assertRaises(TypeError, self.etree.tostring, None)
2535
2536 - def test_tostring_pretty(self):
2537 tostring = self.etree.tostring 2538 Element = self.etree.Element 2539 SubElement = self.etree.SubElement 2540 2541 a = Element('a') 2542 b = SubElement(a, 'b') 2543 c = SubElement(a, 'c') 2544 2545 result = tostring(a) 2546 self.assertEquals(result, _bytes("<a><b/><c/></a>")) 2547 2548 result = tostring(a, pretty_print=False) 2549 self.assertEquals(result, _bytes("<a><b/><c/></a>")) 2550 2551 result = tostring(a, pretty_print=True) 2552 self.assertEquals(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
2553
2554 - def test_tostring_with_tail(self):
2555 tostring = self.etree.tostring 2556 Element = self.etree.Element 2557 SubElement = self.etree.SubElement 2558 2559 a = Element('a') 2560 a.tail = "aTAIL" 2561 b = SubElement(a, 'b') 2562 b.tail = "bTAIL" 2563 c = SubElement(a, 'c') 2564 2565 result = tostring(a) 2566 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 2567 2568 result = tostring(a, with_tail=False) 2569 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>")) 2570 2571 result = tostring(a, with_tail=True) 2572 self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
2573
2574 - def test_standalone(self):
2575 tostring = self.etree.tostring 2576 XML = self.etree.XML 2577 ElementTree = self.etree.ElementTree 2578 Element = self.etree.Element 2579 2580 tree = Element("root").getroottree() 2581 self.assertEquals(None, tree.docinfo.standalone) 2582 2583 tree = XML(_bytes("<root/>")).getroottree() 2584 self.assertEquals(None, tree.docinfo.standalone) 2585 2586 tree = XML(_bytes( 2587 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>" 2588 )).getroottree() 2589 self.assertEquals(True, tree.docinfo.standalone) 2590 2591 tree = XML(_bytes( 2592 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>" 2593 )).getroottree() 2594 self.assertEquals(False, tree.docinfo.standalone)
2595
2596 - def test_tostring_standalone(self):
2597 tostring = self.etree.tostring 2598 XML = self.etree.XML 2599 ElementTree = self.etree.ElementTree 2600 2601 root = XML(_bytes("<root/>")) 2602 2603 tree = ElementTree(root) 2604 self.assertEquals(None, tree.docinfo.standalone) 2605 2606 result = tostring(root, xml_declaration=True, encoding="ASCII") 2607 self.assertEquals(result, _bytes( 2608 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 2609 2610 result = tostring(root, xml_declaration=True, encoding="ASCII", 2611 standalone=True) 2612 self.assertEquals(result, _bytes( 2613 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 2614 2615 tree = ElementTree(XML(result)) 2616 self.assertEquals(True, tree.docinfo.standalone) 2617 2618 result = tostring(root, xml_declaration=True, encoding="ASCII", 2619 standalone=False) 2620 self.assertEquals(result, _bytes( 2621 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>")) 2622 2623 tree = ElementTree(XML(result)) 2624 self.assertEquals(False, tree.docinfo.standalone)
2625
2626 - def test_tostring_standalone_in_out(self):
2627 tostring = self.etree.tostring 2628 XML = self.etree.XML 2629 ElementTree = self.etree.ElementTree 2630 2631 root = XML(_bytes( 2632 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>")) 2633 2634 tree = ElementTree(root) 2635 self.assertEquals(True, tree.docinfo.standalone) 2636 2637 result = tostring(root, xml_declaration=True, encoding="ASCII") 2638 self.assertEquals(result, _bytes( 2639 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 2640 2641 result = tostring(root, xml_declaration=True, encoding="ASCII", 2642 standalone=True) 2643 self.assertEquals(result, _bytes( 2644 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
2645
2646 - def test_tostring_method_text_encoding(self):
2647 tostring = self.etree.tostring 2648 Element = self.etree.Element 2649 SubElement = self.etree.SubElement 2650 2651 a = Element('a') 2652 a.text = "A" 2653 a.tail = "tail" 2654 b = SubElement(a, 'b') 2655 b.text = "B" 2656 b.tail = _str("Søk på nettet") 2657 c = SubElement(a, 'c') 2658 c.text = "C" 2659 2660 result = tostring(a, method="text", encoding="UTF-16") 2661 2662 self.assertEquals(_str('ABSøk på nettetCtail').encode("UTF-16"), 2663 result)
2664
2665 - def test_tostring_method_text_unicode(self):
2666 tostring = self.etree.tostring 2667 Element = self.etree.Element 2668 SubElement = self.etree.SubElement 2669 2670 a = Element('a') 2671 a.text = _str('Søk på nettetA') 2672 a.tail = "tail" 2673 b = SubElement(a, 'b') 2674 b.text = "B" 2675 b.tail = _str('Søk på nettetB') 2676 c = SubElement(a, 'c') 2677 c.text = "C" 2678 2679 self.assertRaises(UnicodeEncodeError, 2680 tostring, a, method="text") 2681 2682 self.assertEquals( 2683 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 2684 tostring(a, encoding="UTF-8", method="text"))
2685
2686 - def test_tounicode(self):
2687 tounicode = self.etree.tounicode 2688 Element = self.etree.Element 2689 SubElement = self.etree.SubElement 2690 2691 a = Element('a') 2692 b = SubElement(a, 'b') 2693 c = SubElement(a, 'c') 2694 2695 self.assert_(isinstance(tounicode(a), _unicode)) 2696 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2697 canonicalize(tounicode(a)))
2698
2699 - def test_tounicode_element(self):
2700 tounicode = self.etree.tounicode 2701 Element = self.etree.Element 2702 SubElement = self.etree.SubElement 2703 2704 a = Element('a') 2705 b = SubElement(a, 'b') 2706 c = SubElement(a, 'c') 2707 d = SubElement(c, 'd') 2708 self.assert_(isinstance(tounicode(b), _unicode)) 2709 self.assert_(isinstance(tounicode(c), _unicode)) 2710 self.assertEquals(_bytes('<b></b>'), 2711 canonicalize(tounicode(b))) 2712 self.assertEquals(_bytes('<c><d></d></c>'), 2713 canonicalize(tounicode(c)))
2714
2715 - def test_tounicode_none(self):
2716 tounicode = self.etree.tounicode 2717 self.assertRaises(TypeError, self.etree.tounicode, None)
2718
2719 - def test_tounicode_element_tail(self):
2720 tounicode = self.etree.tounicode 2721 Element = self.etree.Element 2722 SubElement = self.etree.SubElement 2723 2724 a = Element('a') 2725 b = SubElement(a, 'b') 2726 c = SubElement(a, 'c') 2727 d = SubElement(c, 'd') 2728 b.tail = 'Foo' 2729 2730 self.assert_(isinstance(tounicode(b), _unicode)) 2731 self.assert_(tounicode(b) == '<b/>Foo' or 2732 tounicode(b) == '<b />Foo')
2733
2734 - def test_tounicode_pretty(self):
2735 tounicode = self.etree.tounicode 2736 Element = self.etree.Element 2737 SubElement = self.etree.SubElement 2738 2739 a = Element('a') 2740 b = SubElement(a, 'b') 2741 c = SubElement(a, 'c') 2742 2743 result = tounicode(a) 2744 self.assertEquals(result, "<a><b/><c/></a>") 2745 2746 result = tounicode(a, pretty_print=False) 2747 self.assertEquals(result, "<a><b/><c/></a>") 2748 2749 result = tounicode(a, pretty_print=True) 2750 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2751
2752 - def test_tostring_unicode(self):
2753 tostring = self.etree.tostring 2754 Element = self.etree.Element 2755 SubElement = self.etree.SubElement 2756 2757 a = Element('a') 2758 b = SubElement(a, 'b') 2759 c = SubElement(a, 'c') 2760 2761 self.assert_(isinstance(tostring(a, encoding=_unicode), _unicode)) 2762 self.assertEquals(_bytes('<a><b></b><c></c></a>'), 2763 canonicalize(tostring(a, encoding=_unicode)))
2764
2765 - def test_tostring_unicode_element(self):
2766 tostring = self.etree.tostring 2767 Element = self.etree.Element 2768 SubElement = self.etree.SubElement 2769 2770 a = Element('a') 2771 b = SubElement(a, 'b') 2772 c = SubElement(a, 'c') 2773 d = SubElement(c, 'd') 2774 self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode)) 2775 self.assert_(isinstance(tostring(c, encoding=_unicode), _unicode)) 2776 self.assertEquals(_bytes('<b></b>'), 2777 canonicalize(tostring(b, encoding=_unicode))) 2778 self.assertEquals(_bytes('<c><d></d></c>'), 2779 canonicalize(tostring(c, encoding=_unicode)))
2780
2781 - def test_tostring_unicode_none(self):
2782 tostring = self.etree.tostring 2783 self.assertRaises(TypeError, self.etree.tostring, 2784 None, encoding=_unicode)
2785
2786 - def test_tostring_unicode_element_tail(self):
2787 tostring = self.etree.tostring 2788 Element = self.etree.Element 2789 SubElement = self.etree.SubElement 2790 2791 a = Element('a') 2792 b = SubElement(a, 'b') 2793 c = SubElement(a, 'c') 2794 d = SubElement(c, 'd') 2795 b.tail = 'Foo' 2796 2797 self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode)) 2798 self.assert_(tostring(b, encoding=_unicode) == '<b/>Foo' or 2799 tostring(b, encoding=_unicode) == '<b />Foo')
2800
2801 - def test_tostring_unicode_pretty(self):
2802 tostring = self.etree.tostring 2803 Element = self.etree.Element 2804 SubElement = self.etree.SubElement 2805 2806 a = Element('a') 2807 b = SubElement(a, 'b') 2808 c = SubElement(a, 'c') 2809 2810 result = tostring(a, encoding=_unicode) 2811 self.assertEquals(result, "<a><b/><c/></a>") 2812 2813 result = tostring(a, encoding=_unicode, pretty_print=False) 2814 self.assertEquals(result, "<a><b/><c/></a>") 2815 2816 result = tostring(a, encoding=_unicode, pretty_print=True) 2817 self.assertEquals(result, "<a>\n <b/>\n <c/>\n</a>\n")
2818 2819 # helper methods 2820
2821 - def _writeElement(self, element, encoding='us-ascii', compression=0):
2822 """Write out element for comparison. 2823 """ 2824 ElementTree = self.etree.ElementTree 2825 f = BytesIO() 2826 tree = ElementTree(element=element) 2827 tree.write(f, encoding=encoding, compression=compression) 2828 data = f.getvalue() 2829 if compression: 2830 data = zlib.decompress(data) 2831 return canonicalize(data)
2832 2833
2834 -class XIncludeTestCase(HelperTestCase):
2835 - def test_xinclude_text(self):
2836 filename = fileInTestDir('test_broken.xml') 2837 root = etree.XML(_bytes('''\ 2838 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 2839 <xi:include href="%s" parse="text"/> 2840 </doc> 2841 ''' % filename)) 2842 old_text = root.text 2843 content = open(filename).read() 2844 old_tail = root[0].tail 2845 2846 self.include( etree.ElementTree(root) ) 2847 self.assertEquals(old_text + content + old_tail, 2848 root.text)
2849
2850 - def test_xinclude(self):
2851 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 2852 self.assertNotEquals( 2853 'a', 2854 tree.getroot()[1].tag) 2855 # process xincludes 2856 self.include( tree ) 2857 # check whether we find it replaced with included data 2858 self.assertEquals( 2859 'a', 2860 tree.getroot()[1].tag)
2861
2862 - def test_xinclude_resolver(self):
2863 class res(etree.Resolver): 2864 include_text = open(fileInTestDir('test.xml')).read() 2865 called = {} 2866 def resolve(self, url, id, context): 2867 if url.endswith(".dtd"): 2868 self.called["dtd"] = True 2869 return self.resolve_filename( 2870 fileInTestDir('test.dtd'), context) 2871 elif url.endswith("test_xinclude.xml"): 2872 self.called["input"] = True 2873 return None # delegate to default resolver 2874 else: 2875 self.called["include"] = True 2876 return self.resolve_string(self.include_text, context)
2877 2878 res_instance = res() 2879 parser = etree.XMLParser(load_dtd = True) 2880 parser.resolvers.add(res_instance) 2881 2882 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 2883 parser = parser) 2884 2885 self.include(tree) 2886 2887 called = list(res_instance.called.items()) 2888 called.sort() 2889 self.assertEquals( 2890 [("dtd", True), ("include", True), ("input", True)], 2891 called) 2892
2893 -class ETreeXIncludeTestCase(XIncludeTestCase):
2894 - def include(self, tree):
2895 tree.xinclude()
2896 2897
2898 -class ElementIncludeTestCase(XIncludeTestCase):
2899 from lxml import ElementInclude
2900 - def include(self, tree):
2901 self.ElementInclude.include(tree.getroot())
2902 2903
2904 -class ETreeC14NTestCase(HelperTestCase):
2905 - def test_c14n(self):
2906 tree = self.parse(_bytes('<a><b/></a>')) 2907 f = BytesIO() 2908 tree.write_c14n(f) 2909 s = f.getvalue() 2910 self.assertEquals(_bytes('<a><b></b></a>'), 2911 s)
2912
2913 - def test_c14n_gzip(self):
2914 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 2915 f = BytesIO() 2916 tree.write_c14n(f, compression=9) 2917 s = gzip.GzipFile(fileobj=BytesIO(f.getvalue())).read() 2918 self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'), 2919 s)
2920
2921 - def test_c14n_file(self):
2922 tree = self.parse(_bytes('<a><b/></a>')) 2923 handle, filename = tempfile.mkstemp() 2924 try: 2925 tree.write_c14n(filename) 2926 f = open(filename, 'rb') 2927 data = f.read() 2928 f.close() 2929 finally: 2930 os.close(handle) 2931 os.remove(filename) 2932 self.assertEquals(_bytes('<a><b></b></a>'), 2933 data)
2934
2935 - def test_c14n_file_gzip(self):
2936 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 2937 handle, filename = tempfile.mkstemp() 2938 try: 2939 tree.write_c14n(filename, compression=9) 2940 f = gzip.open(filename, 'rb') 2941 data = f.read() 2942 f.close() 2943 finally: 2944 os.close(handle) 2945 os.remove(filename) 2946 self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'), 2947 data)
2948
2949 - def test_c14n_with_comments(self):
2950 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 2951 f = BytesIO() 2952 tree.write_c14n(f) 2953 s = f.getvalue() 2954 self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 2955 s) 2956 f = BytesIO() 2957 tree.write_c14n(f, with_comments=True) 2958 s = f.getvalue() 2959 self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 2960 s) 2961 f = BytesIO() 2962 tree.write_c14n(f, with_comments=False) 2963 s = f.getvalue() 2964 self.assertEquals(_bytes('<a><b></b></a>'), 2965 s)
2966
2967 - def test_c14n_exclusive(self):
2968 tree = self.parse(_bytes( 2969 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 2970 f = BytesIO() 2971 tree.write_c14n(f) 2972 s = f.getvalue() 2973 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 2974 s) 2975 f = BytesIO() 2976 tree.write_c14n(f, exclusive=False) 2977 s = f.getvalue() 2978 self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 2979 s) 2980 f = BytesIO() 2981 tree.write_c14n(f, exclusive=True) 2982 s = f.getvalue() 2983 self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 2984 s)
2985 2986
2987 -class ETreeWriteTestCase(HelperTestCase):
2988 - def test_write(self):
2989 tree = self.parse(_bytes('<a><b/></a>')) 2990 f = BytesIO() 2991 tree.write(f) 2992 s = f.getvalue() 2993 self.assertEquals(_bytes('<a><b/></a>'), 2994 s)
2995
2996 - def test_write_gzip(self):
2997 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 2998 f = BytesIO() 2999 tree.write(f, compression=9) 3000 s = gzip.GzipFile(fileobj=BytesIO(f.getvalue())).read() 3001 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'), 3002 s)
3003
3004 - def test_write_gzip_level(self):
3005 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3006 f = BytesIO() 3007 tree.write(f, compression=0) 3008 s0 = f.getvalue() 3009 3010 f = BytesIO() 3011 tree.write(f) 3012 self.assertEquals(f.getvalue(), s0) 3013 3014 f = BytesIO() 3015 tree.write(f, compression=1) 3016 s = f.getvalue() 3017 self.assert_(len(s) <= len(s0)) 3018 s1 = gzip.GzipFile(fileobj=BytesIO(s)).read() 3019 3020 f = BytesIO() 3021 tree.write(f, compression=9) 3022 s = f.getvalue() 3023 self.assert_(len(s) <= len(s0)) 3024 s9 = gzip.GzipFile(fileobj=BytesIO(s)).read() 3025 3026 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'), 3027 s0) 3028 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'), 3029 s1) 3030 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'), 3031 s9)
3032
3033 - def test_write_file(self):
3034 tree = self.parse(_bytes('<a><b/></a>')) 3035 handle, filename = tempfile.mkstemp() 3036 try: 3037 tree.write(filename) 3038 f = open(filename, 'rb') 3039 data = f.read() 3040 f.close() 3041 finally: 3042 os.close(handle) 3043 os.remove(filename) 3044 self.assertEquals(_bytes('<a><b/></a>'), 3045 data)
3046
3047 - def test_write_file_gzip(self):
3048 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3049 handle, filename = tempfile.mkstemp() 3050 try: 3051 tree.write(filename, compression=9) 3052 f = gzip.open(filename, 'rb') 3053 data = f.read() 3054 f.close() 3055 finally: 3056 os.close(handle) 3057 os.remove(filename) 3058 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'), 3059 data)
3060
3061 - def test_write_file_gzip_parse(self):
3062 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3063 handle, filename = tempfile.mkstemp() 3064 try: 3065 tree.write(filename, compression=9) 3066 data = etree.tostring(etree.parse(filename)) 3067 finally: 3068 os.close(handle) 3069 os.remove(filename) 3070 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'), 3071 data)
3072
3074 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3075 handle, filename = tempfile.mkstemp() 3076 try: 3077 tree.write(filename, compression=9) 3078 data = etree.tostring(etree.parse( 3079 gzip.GzipFile(filename))) 3080 finally: 3081 os.close(handle) 3082 os.remove(filename) 3083 self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'), 3084 data)
3085
3086 -class ETreeErrorLogTest(HelperTestCase):
3087 etree = etree 3088
3089 - def test_parse_error_logging(self):
3090 parse = self.etree.parse 3091 f = BytesIO('<a><b></c></b></a>') 3092 self.etree.clear_error_log() 3093 try: 3094 parse(f) 3095 logs = None 3096 except SyntaxError: 3097 e = sys.exc_info()[1] 3098 logs = e.error_log 3099 f.close() 3100 self.assert_([ log for log in logs 3101 if 'mismatch' in log.message ]) 3102 self.assert_([ log for log in logs 3103 if 'PARSER' in log.domain_name]) 3104 self.assert_([ log for log in logs 3105 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ]) 3106 self.assert_([ log for log in logs 3107 if 1 == log.line ]) 3108 self.assert_([ log for log in logs 3109 if 15 == log.column ])
3110
3111 - def _test_python_error_logging(self):
3112 """This can't really be tested as long as there isn't a way to 3113 reset the logging setup ... 3114 """ 3115 parse = self.etree.parse 3116 3117 messages = [] 3118 class Logger(self.etree.PyErrorLog): 3119 def log(self, entry, message, *args): 3120 messages.append(message)
3121 3122 self.etree.use_global_python_log(Logger()) 3123 f = BytesIO('<a><b></c></b></a>') 3124 try: 3125 parse(f) 3126 except SyntaxError: 3127 pass 3128 f.close() 3129 3130 self.assert_([ message for message in messages 3131 if 'mismatch' in message ]) 3132 self.assert_([ message for message in messages 3133 if ':PARSER:' in message]) 3134 self.assert_([ message for message in messages 3135 if ':ERR_TAG_NAME_MISMATCH:' in message ]) 3136 self.assert_([ message for message in messages 3137 if ':1:15:' in message ]) 3138
3139 -def test_suite():
3140 suite = unittest.TestSuite() 3141 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 3142 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 3143 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 3144 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 3145 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)]) 3146 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)]) 3147 suite.addTests( 3148 [make_doctest('../../../doc/tutorial.txt')]) 3149 suite.addTests( 3150 [make_doctest('../../../doc/api.txt')]) 3151 suite.addTests( 3152 [make_doctest('../../../doc/FAQ.txt')]) 3153 suite.addTests( 3154 [make_doctest('../../../doc/parsing.txt')]) 3155 suite.addTests( 3156 [make_doctest('../../../doc/resolvers.txt')]) 3157 return suite
3158 3159 if __name__ == '__main__': 3160 print('to test use test.py %s' % __file__) 3161