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