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 gc 
  16  import operator 
  17  import tempfile 
  18  import zlib 
  19  import gzip 
  20   
  21  this_dir = os.path.dirname(__file__) 
  22  if this_dir not in sys.path: 
  23      sys.path.insert(0, this_dir) # needed for Py3 
  24   
  25  from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir, read_file 
  26  from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest 
  27  from common_imports import canonicalize, sorted, _str, _bytes 
  28   
  29  print("") 
  30  print("TESTED VERSION: %s" % etree.__version__) 
  31  print("    Python:           " + repr(sys.version_info)) 
  32  print("    lxml.etree:       " + repr(etree.LXML_VERSION)) 
  33  print("    libxml used:      " + repr(etree.LIBXML_VERSION)) 
  34  print("    libxml compiled:  " + repr(etree.LIBXML_COMPILED_VERSION)) 
  35  print("    libxslt used:     " + repr(etree.LIBXSLT_VERSION)) 
  36  print("    libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION)) 
  37  print("") 
  38   
  39  try: 
  40      _unicode = unicode 
  41  except NameError: 
  42      # Python 3 
  43      _unicode = str 
  44   
45 -class ETreeOnlyTestCase(HelperTestCase):
46 """Tests only for etree, not ElementTree""" 47 etree = etree 48
49 - def test_version(self):
50 self.assertTrue(isinstance(etree.__version__, _unicode)) 51 self.assertTrue(isinstance(etree.LXML_VERSION, tuple)) 52 self.assertEqual(len(etree.LXML_VERSION), 4) 53 self.assertTrue(isinstance(etree.LXML_VERSION[0], int)) 54 self.assertTrue(isinstance(etree.LXML_VERSION[1], int)) 55 self.assertTrue(isinstance(etree.LXML_VERSION[2], int)) 56 self.assertTrue(isinstance(etree.LXML_VERSION[3], int)) 57 self.assertTrue(etree.__version__.startswith( 58 str(etree.LXML_VERSION[0])))
59
60 - def test_c_api(self):
61 if hasattr(self.etree, '__pyx_capi__'): 62 # newer Pyrex compatible C-API 63 self.assertTrue(isinstance(self.etree.__pyx_capi__, dict)) 64 self.assertTrue(len(self.etree.__pyx_capi__) > 0) 65 else: 66 # older C-API mechanism 67 self.assertTrue(hasattr(self.etree, '_import_c_api'))
68
69 - def test_element_names(self):
70 Element = self.etree.Element 71 el = Element('name') 72 self.assertEqual(el.tag, 'name') 73 el = Element('{}name') 74 self.assertEqual(el.tag, 'name')
75
76 - def test_element_name_empty(self):
77 Element = self.etree.Element 78 el = Element('name') 79 self.assertRaises(ValueError, Element, '{}') 80 self.assertRaises(ValueError, setattr, el, 'tag', '{}') 81 82 self.assertRaises(ValueError, Element, '{test}') 83 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
84
85 - def test_element_name_colon(self):
86 Element = self.etree.Element 87 self.assertRaises(ValueError, Element, 'p:name') 88 self.assertRaises(ValueError, Element, '{test}p:name') 89 90 el = Element('name') 91 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
92
93 - def test_element_name_quote(self):
94 Element = self.etree.Element 95 self.assertRaises(ValueError, Element, "p'name") 96 self.assertRaises(ValueError, Element, 'p"name') 97 98 self.assertRaises(ValueError, Element, "{test}p'name") 99 self.assertRaises(ValueError, Element, '{test}p"name') 100 101 el = Element('name') 102 self.assertRaises(ValueError, setattr, el, 'tag', "p'name") 103 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
104
105 - def test_element_name_space(self):
106 Element = self.etree.Element 107 self.assertRaises(ValueError, Element, ' name ') 108 self.assertRaises(ValueError, Element, 'na me') 109 self.assertRaises(ValueError, Element, '{test} name') 110 111 el = Element('name') 112 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
113
114 - def test_subelement_name_empty(self):
115 Element = self.etree.Element 116 SubElement = self.etree.SubElement 117 118 el = Element('name') 119 self.assertRaises(ValueError, SubElement, el, '{}') 120 self.assertRaises(ValueError, SubElement, el, '{test}')
121
122 - def test_subelement_name_colon(self):
123 Element = self.etree.Element 124 SubElement = self.etree.SubElement 125 126 el = Element('name') 127 self.assertRaises(ValueError, SubElement, el, 'p:name') 128 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
129
130 - def test_subelement_name_quote(self):
131 Element = self.etree.Element 132 SubElement = self.etree.SubElement 133 134 el = Element('name') 135 self.assertRaises(ValueError, SubElement, el, "p'name") 136 self.assertRaises(ValueError, SubElement, el, "{test}p'name") 137 138 self.assertRaises(ValueError, SubElement, el, 'p"name') 139 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
140
141 - def test_subelement_name_space(self):
142 Element = self.etree.Element 143 SubElement = self.etree.SubElement 144 145 el = Element('name') 146 self.assertRaises(ValueError, SubElement, el, ' name ') 147 self.assertRaises(ValueError, SubElement, el, 'na me') 148 self.assertRaises(ValueError, SubElement, el, '{test} name')
149
151 Element = self.etree.Element 152 SubElement = self.etree.SubElement 153 154 el = Element('name') 155 self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'}) 156 self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'}) 157 self.assertEqual(0, len(el))
158
159 - def test_qname_empty(self):
160 QName = self.etree.QName 161 self.assertRaises(ValueError, QName, '') 162 self.assertRaises(ValueError, QName, 'test', '')
163
164 - def test_qname_colon(self):
165 QName = self.etree.QName 166 self.assertRaises(ValueError, QName, 'p:name') 167 self.assertRaises(ValueError, QName, 'test', 'p:name')
168
169 - def test_qname_space(self):
170 QName = self.etree.QName 171 self.assertRaises(ValueError, QName, ' name ') 172 self.assertRaises(ValueError, QName, 'na me') 173 self.assertRaises(ValueError, QName, 'test', ' name')
174
176 # ET doesn't have namespace/localname properties on QNames 177 QName = self.etree.QName 178 namespace, localname = 'http://myns', 'a' 179 qname = QName(namespace, localname) 180 self.assertEqual(namespace, qname.namespace) 181 self.assertEqual(localname, qname.localname)
182
183 - def test_qname_element(self):
184 # ET doesn't have namespace/localname properties on QNames 185 QName = self.etree.QName 186 qname1 = QName('http://myns', 'a') 187 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'}) 188 189 qname2 = QName(a) 190 self.assertEqual(a.tag, qname1.text) 191 self.assertEqual(qname1.text, qname2.text) 192 self.assertEqual(qname1, qname2)
193
194 - def test_qname_text_resolve(self):
195 # ET doesn't resove QNames as text values 196 etree = self.etree 197 qname = etree.QName('http://myns', 'a') 198 a = etree.Element(qname, nsmap={'p' : 'http://myns'}) 199 a.text = qname 200 201 self.assertEqual("p:a", a.text)
202
203 - def test_nsmap_prefix_invalid(self):
204 etree = self.etree 205 self.assertRaises(ValueError, 206 etree.Element, "root", nsmap={'"' : 'testns'}) 207 self.assertRaises(ValueError, 208 etree.Element, "root", nsmap={'&' : 'testns'}) 209 self.assertRaises(ValueError, 210 etree.Element, "root", nsmap={'a:b' : 'testns'})
211
212 - def test_attribute_has_key(self):
213 # ET in Py 3.x has no "attrib.has_key()" method 214 XML = self.etree.XML 215 216 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />')) 217 self.assertEqual( 218 True, root.attrib.has_key('bar')) 219 self.assertEqual( 220 False, root.attrib.has_key('baz')) 221 self.assertEqual( 222 False, root.attrib.has_key('hah')) 223 self.assertEqual( 224 True, 225 root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
226
227 - def test_attribute_set(self):
228 Element = self.etree.Element 229 root = Element("root") 230 root.set("attr", "TEST") 231 self.assertEqual("TEST", root.get("attr"))
232
233 - def test_attrib_and_keywords(self):
234 Element = self.etree.Element 235 236 root = Element("root") 237 root.set("attr", "TEST") 238 self.assertEqual("TEST", root.attrib["attr"]) 239 240 root2 = Element("root2", root.attrib, attr2='TOAST') 241 self.assertEqual("TEST", root2.attrib["attr"]) 242 self.assertEqual("TOAST", root2.attrib["attr2"]) 243 self.assertEqual(None, root.attrib.get("attr2"))
244
245 - def test_attrib_order(self):
246 Element = self.etree.Element 247 248 keys = ["attr%d" % i for i in range(10)] 249 values = ["TEST-%d" % i for i in range(10)] 250 items = list(zip(keys, values)) 251 252 root = Element("root") 253 for key, value in items: 254 root.set(key, value) 255 self.assertEqual(keys, root.attrib.keys()) 256 self.assertEqual(values, root.attrib.values()) 257 258 root2 = Element("root2", root.attrib, 259 attr_99='TOAST-1', attr_98='TOAST-2') 260 self.assertEqual(['attr_98', 'attr_99'] + keys, 261 root2.attrib.keys()) 262 self.assertEqual(['TOAST-2', 'TOAST-1'] + values, 263 root2.attrib.values()) 264 265 self.assertEqual(keys, root.attrib.keys()) 266 self.assertEqual(values, root.attrib.values())
267
268 - def test_attribute_set_invalid(self):
269 # ElementTree accepts arbitrary attribute values 270 # lxml.etree allows only strings 271 Element = self.etree.Element 272 root = Element("root") 273 self.assertRaises(TypeError, root.set, "newattr", 5) 274 self.assertRaises(TypeError, root.set, "newattr", None)
275
276 - def test_strip_attributes(self):
277 XML = self.etree.XML 278 xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>') 279 280 root = XML(xml) 281 self.etree.strip_attributes(root, 'a') 282 self.assertEqual(_bytes('<test b="10" c="20"><x b="2"></x></test>'), 283 self._writeElement(root)) 284 285 root = XML(xml) 286 self.etree.strip_attributes(root, 'b', 'c') 287 self.assertEqual(_bytes('<test a="5"><x a="4"></x></test>'), 288 self._writeElement(root))
289
290 - def test_strip_attributes_ns(self):
291 XML = self.etree.XML 292 xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>') 293 294 root = XML(xml) 295 self.etree.strip_attributes(root, 'a') 296 self.assertEqual( 297 _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'), 298 self._writeElement(root)) 299 300 root = XML(xml) 301 self.etree.strip_attributes(root, '{http://test/ns}a', 'c') 302 self.assertEqual( 303 _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'), 304 self._writeElement(root)) 305 306 root = XML(xml) 307 self.etree.strip_attributes(root, '{http://test/ns}*') 308 self.assertEqual( 309 _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'), 310 self._writeElement(root))
311
312 - def test_strip_elements(self):
313 XML = self.etree.XML 314 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>') 315 316 root = XML(xml) 317 self.etree.strip_elements(root, 'a') 318 self.assertEqual(_bytes('<test><x></x></test>'), 319 self._writeElement(root)) 320 321 root = XML(xml) 322 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z') 323 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'), 324 self._writeElement(root)) 325 326 root = XML(xml) 327 self.etree.strip_elements(root, 'c') 328 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'), 329 self._writeElement(root))
330
331 - def test_strip_elements_ns(self):
332 XML = self.etree.XML 333 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>') 334 335 root = XML(xml) 336 self.etree.strip_elements(root, 'a') 337 self.assertEqual(_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>'), 338 self._writeElement(root)) 339 340 root = XML(xml) 341 self.etree.strip_elements(root, '{urn:a}b', 'c') 342 self.assertEqual(_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>'), 343 self._writeElement(root)) 344 345 root = XML(xml) 346 self.etree.strip_elements(root, '{urn:a}*', 'c') 347 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 348 self._writeElement(root)) 349 350 root = XML(xml) 351 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False) 352 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 353 self._writeElement(root))
354
355 - def test_strip_tags(self):
356 XML = self.etree.XML 357 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>') 358 359 root = XML(xml) 360 self.etree.strip_tags(root, 'a') 361 self.assertEqual(_bytes('<test>TESTA<b>B<c></c>CT</b>BTAT<x>XA<b></b>BT<c></c>CTAT</x>XT</test>'), 362 self._writeElement(root)) 363 364 root = XML(xml) 365 self.etree.strip_tags(root, 'b', 'c', 'X', 'Y', 'Z') 366 self.assertEqual(_bytes('<test>TEST<a>ABCTBT</a>AT<x>X<a>ABTCT</a>AT</x>XT</test>'), 367 self._writeElement(root)) 368 369 root = XML(xml) 370 self.etree.strip_tags(root, 'c') 371 self.assertEqual(_bytes('<test>TEST<a>A<b>BCT</b>BT</a>AT<x>X<a>A<b></b>BTCT</a>AT</x>XT</test>'), 372 self._writeElement(root))
373
374 - def test_strip_tags_pi_comment(self):
375 XML = self.etree.XML 376 PI = self.etree.ProcessingInstruction 377 Comment = self.etree.Comment 378 xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>') 379 380 root = XML(xml) 381 self.etree.strip_tags(root, PI) 382 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->\n<?PI1?>'), 383 self._writeElement(root)) 384 385 root = XML(xml) 386 self.etree.strip_tags(root, Comment) 387 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT<?PI2?></test>\n<!--comment3-->\n<?PI1?>'), 388 self._writeElement(root)) 389 390 root = XML(xml) 391 self.etree.strip_tags(root, PI, Comment) 392 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'), 393 self._writeElement(root)) 394 395 root = XML(xml) 396 self.etree.strip_tags(root, Comment, PI) 397 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'), 398 self._writeElement(root))
399
401 XML = self.etree.XML 402 ElementTree = self.etree.ElementTree 403 PI = self.etree.ProcessingInstruction 404 Comment = self.etree.Comment 405 xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>') 406 407 root = XML(xml) 408 self.etree.strip_tags(ElementTree(root), PI) 409 self.assertEqual(_bytes('<!--comment1-->\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->'), 410 self._writeElement(root)) 411 412 root = XML(xml) 413 self.etree.strip_tags(ElementTree(root), Comment) 414 self.assertEqual(_bytes('<?PI1?>\n<test>TESTXT<?PI2?></test>\n<?PI1?>'), 415 self._writeElement(root)) 416 417 root = XML(xml) 418 self.etree.strip_tags(ElementTree(root), PI, Comment) 419 self.assertEqual(_bytes('<test>TESTXT</test>'), 420 self._writeElement(root)) 421 422 root = XML(xml) 423 self.etree.strip_tags(ElementTree(root), Comment, PI) 424 self.assertEqual(_bytes('<test>TESTXT</test>'), 425 self._writeElement(root))
426
427 - def test_strip_tags_doc_style(self):
428 XML = self.etree.XML 429 xml = _bytes(''' 430 <div> 431 <div> 432 I like <strong>sheep</strong>. 433 <br/> 434 I like lots of <strong>sheep</strong>. 435 <br/> 436 Click <a href="http://www.sheep.com">here</a> 437 for <a href="http://www.sheep.com">those</a> sheep. 438 <br/> 439 </div> 440 </div> 441 '''.strip()) 442 443 root = XML(xml) 444 self.etree.strip_tags(root, 'a') 445 self.assertEqual(re.sub(_bytes('</?a[^>]*>'), _bytes(''), xml).replace(_bytes('<br/>'), _bytes('<br></br>')), 446 self._writeElement(root)) 447 448 root = XML(xml) 449 self.etree.strip_tags(root, 'a', 'br') 450 self.assertEqual(re.sub(_bytes('</?a[^>]*>'), _bytes(''), 451 re.sub(_bytes('<br[^>]*>'), _bytes(''), xml)), 452 self._writeElement(root))
453
454 - def test_strip_tags_ns(self):
455 XML = self.etree.XML 456 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>') 457 458 root = XML(xml) 459 self.etree.strip_tags(root, 'a') 460 self.assertEqual(_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>'), 461 self._writeElement(root)) 462 463 root = XML(xml) 464 self.etree.strip_tags(root, '{urn:a}b', 'c') 465 self.assertEqual(_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>'), 466 self._writeElement(root)) 467 468 root = XML(xml) 469 self.etree.strip_tags(root, '{urn:a}*', 'c') 470 self.assertEqual(_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>'), 471 self._writeElement(root))
472
473 - def test_strip_tags_and_remove(self):
474 # previously crashed 475 HTML = self.etree.HTML 476 root = HTML(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'))[0][0] 477 self.assertEqual(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'), 478 self.etree.tostring(root)) 479 self.etree.strip_tags(root, 'b') 480 self.assertEqual(_bytes('<div><h1>title</h1> foo <p>boo</p></div>'), 481 self.etree.tostring(root)) 482 root.remove(root[0]) 483 self.assertEqual(_bytes('<div><p>boo</p></div>'), 484 self.etree.tostring(root))
485
486 - def test_pi(self):
487 # lxml.etree separates target and text 488 Element = self.etree.Element 489 SubElement = self.etree.SubElement 490 ProcessingInstruction = self.etree.ProcessingInstruction 491 492 a = Element('a') 493 a.append(ProcessingInstruction('foo', 'some more text')) 494 self.assertEqual(a[0].target, 'foo') 495 self.assertEqual(a[0].text, 'some more text')
496
497 - def test_pi_parse(self):
498 XML = self.etree.XML 499 root = XML(_bytes("<test><?mypi my test ?></test>")) 500 self.assertEqual(root[0].target, "mypi") 501 self.assertEqual(root[0].text, "my test ")
502
504 XML = self.etree.XML 505 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>")) 506 self.assertEqual(root[0].target, "mypi") 507 self.assertEqual(root[0].get('my'), "1") 508 self.assertEqual(root[0].get('test'), " abc ") 509 self.assertEqual(root[0].get('quotes'), "' '") 510 self.assertEqual(root[0].get('only'), None) 511 self.assertEqual(root[0].get('names'), None) 512 self.assertEqual(root[0].get('nope'), None)
513
515 XML = self.etree.XML 516 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>")) 517 self.assertEqual(root[0].target, "mypi") 518 self.assertEqual(root[0].attrib['my'], "1") 519 self.assertEqual(root[0].attrib['test'], " abc ") 520 self.assertEqual(root[0].attrib['quotes'], "' '") 521 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only') 522 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names') 523 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
524
525 - def test_deepcopy_pi(self):
526 # previously caused a crash 527 ProcessingInstruction = self.etree.ProcessingInstruction 528 529 a = ProcessingInstruction("PI", "ONE") 530 b = copy.deepcopy(a) 531 b.text = "ANOTHER" 532 533 self.assertEqual('ONE', a.text) 534 self.assertEqual('ANOTHER', b.text)
535
537 XML = self.etree.XML 538 tostring = self.etree.tostring 539 root = XML(_bytes("<?mypi my test ?><test/><!--comment -->")) 540 tree1 = self.etree.ElementTree(root) 541 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"), 542 tostring(tree1)) 543 544 tree2 = copy.deepcopy(tree1) 545 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"), 546 tostring(tree2)) 547 548 root2 = copy.deepcopy(tree1.getroot()) 549 self.assertEqual(_bytes("<test/>"), 550 tostring(root2))
551
553 XML = self.etree.XML 554 tostring = self.etree.tostring 555 xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') 556 root = XML(xml) 557 tree1 = self.etree.ElementTree(root) 558 self.assertEqual(xml, tostring(tree1)) 559 560 tree2 = copy.deepcopy(tree1) 561 self.assertEqual(xml, tostring(tree2)) 562 563 root2 = copy.deepcopy(tree1.getroot()) 564 self.assertEqual(_bytes("<test/>"), 565 tostring(root2))
566
567 - def test_attribute_set(self):
568 # ElementTree accepts arbitrary attribute values 569 # lxml.etree allows only strings 570 Element = self.etree.Element 571 572 root = Element("root") 573 root.set("attr", "TEST") 574 self.assertEqual("TEST", root.get("attr")) 575 self.assertRaises(TypeError, root.set, "newattr", 5)
576
577 - def test_parse_remove_comments(self):
578 fromstring = self.etree.fromstring 579 tostring = self.etree.tostring 580 XMLParser = self.etree.XMLParser 581 582 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 583 parser = XMLParser(remove_comments=True) 584 root = fromstring(xml, parser) 585 self.assertEqual( 586 _bytes('<a><b><c/></b></a>'), 587 tostring(root))
588
589 - def test_parse_remove_pis(self):
590 parse = self.etree.parse 591 tostring = self.etree.tostring 592 XMLParser = self.etree.XMLParser 593 594 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>') 595 596 f = BytesIO(xml) 597 tree = parse(f) 598 self.assertEqual( 599 xml, 600 tostring(tree)) 601 602 parser = XMLParser(remove_pis=True) 603 tree = parse(f, parser) 604 self.assertEqual( 605 _bytes('<a><b><c/></b></a>'), 606 tostring(tree))
607
609 # ET raises IOError only 610 parse = self.etree.parse 611 self.assertRaises(TypeError, parse, 'notthere.xml', object())
612
614 # ET removes comments 615 iterparse = self.etree.iterparse 616 tostring = self.etree.tostring 617 618 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 619 events = list(iterparse(f)) 620 root = events[-1][1] 621 self.assertEqual(3, len(events)) 622 self.assertEqual( 623 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 624 tostring(root))
625
626 - def test_iterparse_comments(self):
627 # ET removes comments 628 iterparse = self.etree.iterparse 629 tostring = self.etree.tostring 630 631 def name(event, el): 632 if event == 'comment': 633 return el.text 634 else: 635 return el.tag
636 637 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 638 events = list(iterparse(f, events=('end', 'comment'))) 639 root = events[-1][1] 640 self.assertEqual(6, len(events)) 641 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'], 642 [ name(*item) for item in events ]) 643 self.assertEqual( 644 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 645 tostring(root))
646
647 - def test_iterparse_pis(self):
648 # ET removes pis 649 iterparse = self.etree.iterparse 650 tostring = self.etree.tostring 651 ElementTree = self.etree.ElementTree 652 653 def name(event, el): 654 if event == 'pi': 655 return (el.target, el.text) 656 else: 657 return el.tag
658 659 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>') 660 events = list(iterparse(f, events=('end', 'pi'))) 661 root = events[-2][1] 662 self.assertEqual(8, len(events)) 663 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b', 664 ('pid','d'), 'a', ('pie','e')], 665 [ name(*item) for item in events ]) 666 self.assertEqual( 667 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'), 668 tostring(ElementTree(root))) 669
670 - def test_iterparse_remove_comments(self):
671 iterparse = self.etree.iterparse 672 tostring = self.etree.tostring 673 674 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 675 events = list(iterparse(f, remove_comments=True, 676 events=('end', 'comment'))) 677 root = events[-1][1] 678 self.assertEqual(3, len(events)) 679 self.assertEqual(['c', 'b', 'a'], 680 [ el.tag for (event, el) in events ]) 681 self.assertEqual( 682 _bytes('<a><b><c/></b></a>'), 683 tostring(root))
684
685 - def test_iterparse_broken(self):
686 iterparse = self.etree.iterparse 687 f = BytesIO('<a><b><c/></a>') 688 # ET raises ExpatError, lxml raises XMLSyntaxError 689 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
690
691 - def test_iterparse_broken_recover(self):
692 iterparse = self.etree.iterparse 693 f = BytesIO('<a><b><c/></a>') 694 it = iterparse(f, events=('start', 'end'), recover=True) 695 events = [(ev, el.tag) for ev, el in it] 696 root = it.root 697 self.assertTrue(root is not None) 698 699 self.assertEqual(1, events.count(('start', 'a'))) 700 self.assertEqual(1, events.count(('end', 'a'))) 701 702 self.assertEqual(1, events.count(('start', 'b'))) 703 self.assertEqual(1, events.count(('end', 'b'))) 704 705 self.assertEqual(1, events.count(('start', 'c'))) 706 self.assertEqual(1, events.count(('end', 'c')))
707
708 - def test_iterparse_broken_multi_recover(self):
709 iterparse = self.etree.iterparse 710 f = BytesIO('<a><b><c/></d><b><c/></a></b>') 711 it = iterparse(f, events=('start', 'end'), recover=True) 712 events = [(ev, el.tag) for ev, el in it] 713 root = it.root 714 self.assertTrue(root is not None) 715 716 self.assertEqual(1, events.count(('start', 'a'))) 717 self.assertEqual(1, events.count(('end', 'a'))) 718 719 self.assertEqual(2, events.count(('start', 'b'))) 720 self.assertEqual(2, events.count(('end', 'b'))) 721 722 self.assertEqual(2, events.count(('start', 'c'))) 723 self.assertEqual(2, events.count(('end', 'c')))
724
725 - def test_iterparse_strip(self):
726 iterparse = self.etree.iterparse 727 f = BytesIO(""" 728 <a> \n \n <b> b test </b> \n 729 730 \n\t <c> \n </c> </a> \n """) 731 iterator = iterparse(f, remove_blank_text=True) 732 text = [ (element.text, element.tail) 733 for event, element in iterator ] 734 self.assertEqual( 735 [(" b test ", None), (" \n ", None), (None, None)], 736 text)
737
738 - def test_iterparse_tag(self):
739 iterparse = self.etree.iterparse 740 f = BytesIO('<a><b><d/></b><c/></a>') 741 742 iterator = iterparse(f, tag="b", events=('start', 'end')) 743 events = list(iterator) 744 root = iterator.root 745 self.assertEqual( 746 [('start', root[0]), ('end', root[0])], 747 events)
748
749 - def test_iterparse_tag_all(self):
750 iterparse = self.etree.iterparse 751 f = BytesIO('<a><b><d/></b><c/></a>') 752 753 iterator = iterparse(f, tag="*", events=('start', 'end')) 754 events = list(iterator) 755 self.assertEqual( 756 8, 757 len(events))
758
759 - def test_iterparse_tag_ns(self):
760 iterparse = self.etree.iterparse 761 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 762 763 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end')) 764 events = list(iterator) 765 root = iterator.root 766 self.assertEqual( 767 [('start', root[0]), ('end', root[0])], 768 events)
769
770 - def test_iterparse_tag_ns_empty(self):
771 iterparse = self.etree.iterparse 772 f = BytesIO('<a><b><d/></b><c/></a>') 773 iterator = iterparse(f, tag="{}b", events=('start', 'end')) 774 events = list(iterator) 775 root = iterator.root 776 self.assertEqual( 777 [('start', root[0]), ('end', root[0])], 778 events) 779 780 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 781 iterator = iterparse(f, tag="{}b", events=('start', 'end')) 782 events = list(iterator) 783 root = iterator.root 784 self.assertEqual([], events)
785
786 - def test_iterparse_tag_ns_all(self):
787 iterparse = self.etree.iterparse 788 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 789 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end')) 790 events = list(iterator) 791 self.assertEqual(8, len(events))
792
793 - def test_iterparse_tag_ns_empty_all(self):
794 iterparse = self.etree.iterparse 795 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 796 iterator = iterparse(f, tag="{}*", events=('start', 'end')) 797 events = list(iterator) 798 self.assertEqual([], events) 799 800 f = BytesIO('<a><b><d/></b><c/></a>') 801 iterator = iterparse(f, tag="{}*", events=('start', 'end')) 802 events = list(iterator) 803 self.assertEqual(8, len(events))
804
805 - def test_iterparse_encoding_error(self):
806 text = _str('Søk på nettet') 807 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 808 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 809 ).encode('iso-8859-1') 810 811 self.assertRaises(self.etree.ParseError, 812 list, self.etree.iterparse(BytesIO(xml_latin1)))
813
814 - def test_iterparse_encoding_8bit_override(self):
815 text = _str('Søk på nettet', encoding="UTF-8") 816 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 817 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 818 ).encode('iso-8859-1') 819 820 iterator = self.etree.iterparse(BytesIO(xml_latin1), 821 encoding="iso-8859-1") 822 self.assertEqual(1, len(list(iterator))) 823 824 a = iterator.root 825 self.assertEqual(a.text, text)
826
827 - def test_iterparse_keep_cdata(self):
828 tostring = self.etree.tostring 829 f = BytesIO('<root><![CDATA[test]]></root>') 830 context = self.etree.iterparse(f, strip_cdata=False) 831 content = [ el.text for event,el in context ] 832 833 self.assertEqual(['test'], content) 834 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 835 tostring(context.root))
836
837 - def test_parser_encoding_unknown(self):
838 self.assertRaises( 839 LookupError, self.etree.XMLParser, encoding="hopefully unknown")
840
841 - def test_parser_encoding(self):
842 self.etree.XMLParser(encoding="ascii") 843 self.etree.XMLParser(encoding="utf-8") 844 self.etree.XMLParser(encoding="iso-8859-1")
845
846 - def test_feed_parser_recover(self):
847 parser = self.etree.XMLParser(recover=True) 848 849 parser.feed('<?xml version=') 850 parser.feed('"1.0"?><ro') 851 parser.feed('ot><') 852 parser.feed('a test="works"') 853 parser.feed('><othertag/></root') # <a> not closed! 854 parser.feed('>') 855 856 root = parser.close() 857 858 self.assertEqual(root.tag, "root") 859 self.assertEqual(len(root), 1) 860 self.assertEqual(root[0].tag, "a") 861 self.assertEqual(root[0].get("test"), "works") 862 self.assertEqual(len(root[0]), 1) 863 self.assertEqual(root[0][0].tag, "othertag")
864 # FIXME: would be nice to get some errors logged ... 865 #self.assertTrue(len(parser.error_log) > 0, "error log is empty") 866
867 - def test_elementtree_parser_target_type_error(self):
868 assertEqual = self.assertEqual 869 assertFalse = self.assertFalse 870 871 events = [] 872 class Target(object): 873 def start(self, tag, attrib): 874 events.append("start") 875 assertFalse(attrib) 876 assertEqual("TAG", tag)
877 def end(self, tag): 878 events.append("end") 879 assertEqual("TAG", tag) 880 def close(self): 881 return "DONE" # no Element! 882 883 parser = self.etree.XMLParser(target=Target()) 884 tree = self.etree.ElementTree() 885 886 self.assertRaises(TypeError, 887 tree.parse, BytesIO("<TAG/>"), parser=parser) 888 self.assertEqual(["start", "end"], events) 889
890 - def test_parser_target_feed_exception(self):
891 # ET doesn't call .close() on errors 892 events = [] 893 class Target(object): 894 def start(self, tag, attrib): 895 events.append("start-" + tag)
896 def end(self, tag): 897 events.append("end-" + tag) 898 if tag == 'a': 899 raise ValueError("dead and gone") 900 def data(self, data): 901 events.append("data-" + data) 902 def close(self): 903 events.append("close") 904 return "DONE" 905 906 parser = self.etree.XMLParser(target=Target()) 907 908 try: 909 parser.feed(_bytes('<root>A<a>ca</a>B</root>')) 910 done = parser.close() 911 self.fail("error expected, but parsing succeeded") 912 except ValueError: 913 done = 'value error received as expected' 914 915 self.assertEqual(["start-root", "data-A", "start-a", 916 "data-ca", "end-a", "close"], 917 events) 918
919 - def test_parser_target_fromstring_exception(self):
920 # ET doesn't call .close() on errors 921 events = [] 922 class Target(object): 923 def start(self, tag, attrib): 924 events.append("start-" + tag)
925 def end(self, tag): 926 events.append("end-" + tag) 927 if tag == 'a': 928 raise ValueError("dead and gone") 929 def data(self, data): 930 events.append("data-" + data) 931 def close(self): 932 events.append("close") 933 return "DONE" 934 935 parser = self.etree.XMLParser(target=Target()) 936 937 try: 938 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'), 939 parser=parser) 940 self.fail("error expected, but parsing succeeded") 941 except ValueError: 942 done = 'value error received as expected' 943 944 self.assertEqual(["start-root", "data-A", "start-a", 945 "data-ca", "end-a", "close"], 946 events) 947
948 - def test_parser_target_comment(self):
949 events = [] 950 class Target(object): 951 def start(self, tag, attrib): 952 events.append("start-" + tag)
953 def end(self, tag): 954 events.append("end-" + tag) 955 def data(self, data): 956 events.append("data-" + data) 957 def comment(self, text): 958 events.append("comment-" + text) 959 def close(self): 960 return "DONE" 961 962 parser = self.etree.XMLParser(target=Target()) 963 964 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')) 965 done = parser.close() 966 967 self.assertEqual("DONE", done) 968 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b", 969 "start-sub", "end-sub", "comment-c", "data-B", 970 "end-root", "comment-d"], 971 events) 972
973 - def test_parser_target_pi(self):
974 events = [] 975 class Target(object): 976 def start(self, tag, attrib): 977 events.append("start-" + tag)
978 def end(self, tag): 979 events.append("end-" + tag) 980 def data(self, data): 981 events.append("data-" + data) 982 def pi(self, target, data): 983 events.append("pi-" + target + "-" + data) 984 def close(self): 985 return "DONE" 986 987 parser = self.etree.XMLParser(target=Target()) 988 989 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>')) 990 done = parser.close() 991 992 self.assertEqual("DONE", done) 993 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b", 994 "data-B", "end-root", "pi-test-c"], 995 events) 996
997 - def test_parser_target_cdata(self):
998 events = [] 999 class Target(object): 1000 def start(self, tag, attrib): 1001 events.append("start-" + tag)
1002 def end(self, tag): 1003 events.append("end-" + tag) 1004 def data(self, data): 1005 events.append("data-" + data) 1006 def close(self): 1007 return "DONE" 1008 1009 parser = self.etree.XMLParser(target=Target(), 1010 strip_cdata=False) 1011 1012 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>')) 1013 done = parser.close() 1014 1015 self.assertEqual("DONE", done) 1016 self.assertEqual(["start-root", "data-A", "start-a", 1017 "data-ca", "end-a", "data-B", "end-root"], 1018 events) 1019
1020 - def test_parser_target_recover(self):
1021 events = [] 1022 class Target(object): 1023 def start(self, tag, attrib): 1024 events.append("start-" + tag)
1025 def end(self, tag): 1026 events.append("end-" + tag) 1027 def data(self, data): 1028 events.append("data-" + data) 1029 def close(self): 1030 events.append("close") 1031 return "DONE" 1032 1033 parser = self.etree.XMLParser(target=Target(), 1034 recover=True) 1035 1036 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>')) 1037 done = parser.close() 1038 1039 self.assertEqual("DONE", done) 1040 self.assertEqual(["start-root", "data-A", "start-a", 1041 "data-ca", "end-a", "data-B", 1042 "end-root", "close"], 1043 events) 1044
1045 - def test_iterwalk_tag(self):
1046 iterwalk = self.etree.iterwalk 1047 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 1048 1049 iterator = iterwalk(root, tag="b", events=('start', 'end')) 1050 events = list(iterator) 1051 self.assertEqual( 1052 [('start', root[0]), ('end', root[0])], 1053 events)
1054
1055 - def test_iterwalk_tag_all(self):
1056 iterwalk = self.etree.iterwalk 1057 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 1058 1059 iterator = iterwalk(root, tag="*", events=('start', 'end')) 1060 events = list(iterator) 1061 self.assertEqual( 1062 8, 1063 len(events))
1064
1065 - def test_iterwalk(self):
1066 iterwalk = self.etree.iterwalk 1067 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1068 1069 events = list(iterwalk(root)) 1070 self.assertEqual( 1071 [('end', root[0]), ('end', root[1]), ('end', root)], 1072 events)
1073
1074 - def test_iterwalk_start(self):
1075 iterwalk = self.etree.iterwalk 1076 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1077 1078 iterator = iterwalk(root, events=('start',)) 1079 events = list(iterator) 1080 self.assertEqual( 1081 [('start', root), ('start', root[0]), ('start', root[1])], 1082 events)
1083
1084 - def test_iterwalk_start_end(self):
1085 iterwalk = self.etree.iterwalk 1086 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1087 1088 iterator = iterwalk(root, events=('start','end')) 1089 events = list(iterator) 1090 self.assertEqual( 1091 [('start', root), ('start', root[0]), ('end', root[0]), 1092 ('start', root[1]), ('end', root[1]), ('end', root)], 1093 events)
1094
1095 - def test_iterwalk_clear(self):
1096 iterwalk = self.etree.iterwalk 1097 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1098 1099 iterator = iterwalk(root) 1100 for event, elem in iterator: 1101 elem.clear() 1102 1103 self.assertEqual(0, 1104 len(root))
1105
1106 - def test_iterwalk_attrib_ns(self):
1107 iterwalk = self.etree.iterwalk 1108 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')) 1109 1110 attr_name = '{testns}bla' 1111 events = [] 1112 iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 1113 for event, elem in iterator: 1114 events.append(event) 1115 if event == 'start': 1116 if elem.tag != '{ns1}a': 1117 elem.set(attr_name, 'value') 1118 1119 self.assertEqual( 1120 ['start-ns', 'start', 'start', 'start-ns', 'start', 1121 'end', 'end-ns', 'end', 'end', 'end-ns'], 1122 events) 1123 1124 self.assertEqual( 1125 None, 1126 root.get(attr_name)) 1127 self.assertEqual( 1128 'value', 1129 root[0].get(attr_name))
1130
1131 - def test_iterwalk_getiterator(self):
1132 iterwalk = self.etree.iterwalk 1133 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 1134 1135 counts = [] 1136 for event, elem in iterwalk(root): 1137 counts.append(len(list(elem.getiterator()))) 1138 self.assertEqual( 1139 [1,2,1,4], 1140 counts)
1141
1142 - def test_resolve_string_dtd(self):
1143 parse = self.etree.parse 1144 parser = self.etree.XMLParser(dtd_validation=True) 1145 assertEqual = self.assertEqual 1146 test_url = _str("__nosuch.dtd") 1147 1148 class MyResolver(self.etree.Resolver): 1149 def resolve(self, url, id, context): 1150 assertEqual(url, test_url) 1151 return self.resolve_string( 1152 _str('''<!ENTITY myentity "%s"> 1153 <!ELEMENT doc ANY>''') % url, context)
1154 1155 parser.resolvers.add(MyResolver()) 1156 1157 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1158 tree = parse(StringIO(xml), parser) 1159 root = tree.getroot() 1160 self.assertEqual(root.text, test_url) 1161
1162 - def test_resolve_bytes_dtd(self):
1163 parse = self.etree.parse 1164 parser = self.etree.XMLParser(dtd_validation=True) 1165 assertEqual = self.assertEqual 1166 test_url = _str("__nosuch.dtd") 1167 1168 class MyResolver(self.etree.Resolver): 1169 def resolve(self, url, id, context): 1170 assertEqual(url, test_url) 1171 return self.resolve_string( 1172 (_str('''<!ENTITY myentity "%s"> 1173 <!ELEMENT doc ANY>''') % url).encode('utf-8'), 1174 context)
1175 1176 parser.resolvers.add(MyResolver()) 1177 1178 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1179 tree = parse(StringIO(xml), parser) 1180 root = tree.getroot() 1181 self.assertEqual(root.text, test_url) 1182
1183 - def test_resolve_filelike_dtd(self):
1184 parse = self.etree.parse 1185 parser = self.etree.XMLParser(dtd_validation=True) 1186 assertEqual = self.assertEqual 1187 test_url = _str("__nosuch.dtd") 1188 1189 class MyResolver(self.etree.Resolver): 1190 def resolve(self, url, id, context): 1191 assertEqual(url, test_url) 1192 return self.resolve_file( 1193 SillyFileLike( 1194 _str('''<!ENTITY myentity "%s"> 1195 <!ELEMENT doc ANY>''') % url), context)
1196 1197 parser.resolvers.add(MyResolver()) 1198 1199 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1200 tree = parse(StringIO(xml), parser) 1201 root = tree.getroot() 1202 self.assertEqual(root.text, test_url) 1203
1204 - def test_resolve_filename_dtd(self):
1205 parse = self.etree.parse 1206 parser = self.etree.XMLParser(attribute_defaults=True) 1207 assertEqual = self.assertEqual 1208 test_url = _str("__nosuch.dtd") 1209 1210 class MyResolver(self.etree.Resolver): 1211 def resolve(self, url, id, context): 1212 assertEqual(url, test_url) 1213 return self.resolve_filename( 1214 fileInTestDir('test.dtd'), context)
1215 1216 parser.resolvers.add(MyResolver()) 1217 1218 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1219 tree = parse(StringIO(xml), parser) 1220 root = tree.getroot() 1221 self.assertEqual( 1222 root.attrib, {'default': 'valueA'}) 1223 self.assertEqual( 1224 root[0].attrib, {'default': 'valueB'}) 1225
1226 - def test_resolve_filename_dtd_relative(self):
1227 parse = self.etree.parse 1228 parser = self.etree.XMLParser(attribute_defaults=True) 1229 assertEqual = self.assertEqual 1230 test_url = _str("__nosuch.dtd") 1231 1232 class MyResolver(self.etree.Resolver): 1233 def resolve(self, url, id, context): 1234 assertEqual(url, fileInTestDir(test_url)) 1235 return self.resolve_filename( 1236 fileInTestDir('test.dtd'), context)
1237 1238 parser.resolvers.add(MyResolver()) 1239 1240 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1241 tree = parse(StringIO(xml), parser, 1242 base_url=fileInTestDir('__test.xml')) 1243 root = tree.getroot() 1244 self.assertEqual( 1245 root.attrib, {'default': 'valueA'}) 1246 self.assertEqual( 1247 root[0].attrib, {'default': 'valueB'}) 1248
1249 - def test_resolve_file_dtd(self):
1250 parse = self.etree.parse 1251 parser = self.etree.XMLParser(attribute_defaults=True) 1252 assertEqual = self.assertEqual 1253 test_url = _str("__nosuch.dtd") 1254 1255 class MyResolver(self.etree.Resolver): 1256 def resolve(self, url, id, context): 1257 assertEqual(url, test_url) 1258 return self.resolve_file( 1259 open(fileInTestDir('test.dtd'), 'rb'), context)
1260 1261 parser.resolvers.add(MyResolver()) 1262 1263 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1264 tree = parse(StringIO(xml), parser) 1265 root = tree.getroot() 1266 self.assertEqual( 1267 root.attrib, {'default': 'valueA'}) 1268 self.assertEqual( 1269 root[0].attrib, {'default': 'valueB'}) 1270
1271 - def test_resolve_empty(self):
1272 parse = self.etree.parse 1273 parser = self.etree.XMLParser(load_dtd=True) 1274 assertEqual = self.assertEqual 1275 test_url = _str("__nosuch.dtd") 1276 1277 class check(object): 1278 resolved = False
1279 1280 class MyResolver(self.etree.Resolver): 1281 def resolve(self, url, id, context): 1282 assertEqual(url, test_url) 1283 check.resolved = True 1284 return self.resolve_empty(context) 1285 1286 parser.resolvers.add(MyResolver()) 1287 1288 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1289 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 1290 self.assertTrue(check.resolved) 1291
1292 - def test_resolve_error(self):
1293 parse = self.etree.parse 1294 parser = self.etree.XMLParser(dtd_validation=True) 1295 1296 class _LocalException(Exception): 1297 pass
1298 1299 class MyResolver(self.etree.Resolver): 1300 def resolve(self, url, id, context): 1301 raise _LocalException 1302 1303 parser.resolvers.add(MyResolver()) 1304 1305 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 1306 self.assertRaises(_LocalException, parse, BytesIO(xml), parser) 1307 1308 if etree.LIBXML_VERSION > (2,6,20):
1309 - def test_entity_parse(self):
1310 parse = self.etree.parse 1311 tostring = self.etree.tostring 1312 parser = self.etree.XMLParser(resolve_entities=False) 1313 Entity = self.etree.Entity 1314 1315 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>') 1316 tree = parse(BytesIO(xml), parser) 1317 root = tree.getroot() 1318 self.assertEqual(root[0].tag, Entity) 1319 self.assertEqual(root[0].text, "&myentity;") 1320 self.assertEqual(root[0].tail, None) 1321 self.assertEqual(root[0].name, "myentity") 1322 1323 self.assertEqual(_bytes('<doc>&myentity;</doc>'), 1324 tostring(root))
1325
1326 - def test_entity_restructure(self):
1327 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp "&#160;"> ]> 1328 <root> 1329 <child1/> 1330 <child2/> 1331 <child3>&nbsp;</child3> 1332 </root>''') 1333 1334 parser = self.etree.XMLParser(resolve_entities=False) 1335 root = etree.fromstring(xml, parser) 1336 self.assertEqual([ el.tag for el in root ], 1337 ['child1', 'child2', 'child3']) 1338 1339 root[0] = root[-1] 1340 self.assertEqual([ el.tag for el in root ], 1341 ['child3', 'child2']) 1342 self.assertEqual(root[0][0].text, '&nbsp;') 1343 self.assertEqual(root[0][0].name, 'nbsp')
1344
1345 - def test_entity_append(self):
1346 Entity = self.etree.Entity 1347 Element = self.etree.Element 1348 tostring = self.etree.tostring 1349 1350 root = Element("root") 1351 root.append( Entity("test") ) 1352 1353 self.assertEqual(root[0].tag, Entity) 1354 self.assertEqual(root[0].text, "&test;") 1355 self.assertEqual(root[0].tail, None) 1356 self.assertEqual(root[0].name, "test") 1357 1358 self.assertEqual(_bytes('<root>&test;</root>'), 1359 tostring(root))
1360
1361 - def test_entity_values(self):
1362 Entity = self.etree.Entity 1363 self.assertEqual(Entity("test").text, '&test;') 1364 self.assertEqual(Entity("#17683").text, '&#17683;') 1365 self.assertEqual(Entity("#x1768").text, '&#x1768;') 1366 self.assertEqual(Entity("#x98AF").text, '&#x98AF;')
1367
1368 - def test_entity_error(self):
1369 Entity = self.etree.Entity 1370 self.assertRaises(ValueError, Entity, 'a b c') 1371 self.assertRaises(ValueError, Entity, 'a,b') 1372 self.assertRaises(ValueError, Entity, 'a\0b') 1373 self.assertRaises(ValueError, Entity, '#abc') 1374 self.assertRaises(ValueError, Entity, '#xxyz')
1375
1376 - def test_cdata(self):
1377 CDATA = self.etree.CDATA 1378 Element = self.etree.Element 1379 tostring = self.etree.tostring 1380 1381 root = Element("root") 1382 root.text = CDATA('test') 1383 1384 self.assertEqual('test', 1385 root.text) 1386 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1387 tostring(root))
1388
1389 - def test_cdata_type(self):
1390 CDATA = self.etree.CDATA 1391 Element = self.etree.Element 1392 root = Element("root") 1393 1394 root.text = CDATA("test") 1395 self.assertEqual('test', root.text) 1396 1397 root.text = CDATA(_str("test")) 1398 self.assertEqual('test', root.text) 1399 1400 self.assertRaises(TypeError, CDATA, 1)
1401
1402 - def test_cdata_errors(self):
1403 CDATA = self.etree.CDATA 1404 Element = self.etree.Element 1405 1406 root = Element("root") 1407 cdata = CDATA('test') 1408 1409 self.assertRaises(TypeError, 1410 setattr, root, 'tail', cdata) 1411 self.assertRaises(TypeError, 1412 root.set, 'attr', cdata) 1413 self.assertRaises(TypeError, 1414 operator.setitem, root.attrib, 'attr', cdata)
1415
1416 - def test_cdata_parser(self):
1417 tostring = self.etree.tostring 1418 parser = self.etree.XMLParser(strip_cdata=False) 1419 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1420 1421 self.assertEqual('test', root.text) 1422 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1423 tostring(root))
1424
1425 - def test_cdata_xpath(self):
1426 tostring = self.etree.tostring 1427 parser = self.etree.XMLParser(strip_cdata=False) 1428 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1429 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1430 tostring(root)) 1431 1432 self.assertEqual(['test'], root.xpath('//text()'))
1433 1434 # TypeError in etree, AssertionError in ElementTree;
1435 - def test_setitem_assert(self):
1436 Element = self.etree.Element 1437 SubElement = self.etree.SubElement 1438 1439 a = Element('a') 1440 b = SubElement(a, 'b') 1441 1442 self.assertRaises(TypeError, 1443 a.__setitem__, 0, 'foo')
1444
1445 - def test_append_error(self):
1446 Element = self.etree.Element 1447 root = Element('root') 1448 # raises AssertionError in ElementTree 1449 self.assertRaises(TypeError, root.append, None) 1450 self.assertRaises(TypeError, root.extend, [None]) 1451 self.assertRaises(TypeError, root.extend, [Element('one'), None]) 1452 self.assertEqual('one', root[0].tag)
1453
1454 - def test_append_recursive_error(self):
1455 Element = self.etree.Element 1456 SubElement = self.etree.SubElement 1457 root = Element('root') 1458 self.assertRaises(ValueError, root.append, root) 1459 child = SubElement(root, 'child') 1460 self.assertRaises(ValueError, child.append, root) 1461 child2 = SubElement(child, 'child2') 1462 self.assertRaises(ValueError, child2.append, root) 1463 self.assertRaises(ValueError, child2.append, child) 1464 self.assertEqual('child2', root[0][0].tag)
1465
1466 - def test_addnext(self):
1467 Element = self.etree.Element 1468 SubElement = self.etree.SubElement 1469 root = Element('root') 1470 SubElement(root, 'a') 1471 SubElement(root, 'b') 1472 1473 self.assertEqual(['a', 'b'], 1474 [c.tag for c in root]) 1475 root[1].addnext(root[0]) 1476 self.assertEqual(['b', 'a'], 1477 [c.tag for c in root])
1478
1479 - def test_addprevious(self):
1480 Element = self.etree.Element 1481 SubElement = self.etree.SubElement 1482 root = Element('root') 1483 SubElement(root, 'a') 1484 SubElement(root, 'b') 1485 1486 self.assertEqual(['a', 'b'], 1487 [c.tag for c in root]) 1488 root[0].addprevious(root[1]) 1489 self.assertEqual(['b', 'a'], 1490 [c.tag for c in root])
1491
1492 - def test_addprevious_noops(self):
1493 Element = self.etree.Element 1494 SubElement = self.etree.SubElement 1495 root = Element('root') 1496 a = SubElement(root, 'a') 1497 b = SubElement(root, 'b') 1498 a.addprevious(a) 1499 self.assertEqual('a', root[0].tag) 1500 self.assertEqual('b', root[1].tag) 1501 b.addprevious(b) 1502 self.assertEqual('a', root[0].tag) 1503 self.assertEqual('b', root[1].tag) 1504 b.addprevious(a) 1505 self.assertEqual('a', root[0].tag) 1506 self.assertEqual('b', root[1].tag)
1507
1508 - def test_addnext_noops(self):
1509 Element = self.etree.Element 1510 SubElement = self.etree.SubElement 1511 root = Element('root') 1512 a = SubElement(root, 'a') 1513 b = SubElement(root, 'b') 1514 a.addnext(a) 1515 self.assertEqual('a', root[0].tag) 1516 self.assertEqual('b', root[1].tag) 1517 b.addnext(b) 1518 self.assertEqual('a', root[0].tag) 1519 self.assertEqual('b', root[1].tag) 1520 a.addnext(b) 1521 self.assertEqual('a', root[0].tag) 1522 self.assertEqual('b', root[1].tag)
1523
1524 - def test_addnext_root(self):
1525 Element = self.etree.Element 1526 a = Element('a') 1527 b = Element('b') 1528 self.assertRaises(TypeError, a.addnext, b)
1529
1530 - def test_addprevious_pi(self):
1531 Element = self.etree.Element 1532 SubElement = self.etree.SubElement 1533 PI = self.etree.PI 1534 root = Element('root') 1535 SubElement(root, 'a') 1536 pi = PI('TARGET', 'TEXT') 1537 pi.tail = "TAIL" 1538 1539 self.assertEqual(_bytes('<root><a></a></root>'), 1540 self._writeElement(root)) 1541 root[0].addprevious(pi) 1542 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 1543 self._writeElement(root))
1544
1545 - def test_addprevious_root_pi(self):
1546 Element = self.etree.Element 1547 PI = self.etree.PI 1548 root = Element('root') 1549 pi = PI('TARGET', 'TEXT') 1550 pi.tail = "TAIL" 1551 1552 self.assertEqual(_bytes('<root></root>'), 1553 self._writeElement(root)) 1554 root.addprevious(pi) 1555 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'), 1556 self._writeElement(root))
1557
1558 - def test_addnext_pi(self):
1559 Element = self.etree.Element 1560 SubElement = self.etree.SubElement 1561 PI = self.etree.PI 1562 root = Element('root') 1563 SubElement(root, 'a') 1564 pi = PI('TARGET', 'TEXT') 1565 pi.tail = "TAIL" 1566 1567 self.assertEqual(_bytes('<root><a></a></root>'), 1568 self._writeElement(root)) 1569 root[0].addnext(pi) 1570 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 1571 self._writeElement(root))
1572
1573 - def test_addnext_root_pi(self):
1574 Element = self.etree.Element 1575 PI = self.etree.PI 1576 root = Element('root') 1577 pi = PI('TARGET', 'TEXT') 1578 pi.tail = "TAIL" 1579 1580 self.assertEqual(_bytes('<root></root>'), 1581 self._writeElement(root)) 1582 root.addnext(pi) 1583 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'), 1584 self._writeElement(root))
1585
1586 - def test_addnext_comment(self):
1587 Element = self.etree.Element 1588 SubElement = self.etree.SubElement 1589 Comment = self.etree.Comment 1590 root = Element('root') 1591 SubElement(root, 'a') 1592 comment = Comment('TEXT ') 1593 comment.tail = "TAIL" 1594 1595 self.assertEqual(_bytes('<root><a></a></root>'), 1596 self._writeElement(root)) 1597 root[0].addnext(comment) 1598 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 1599 self._writeElement(root))
1600
1601 - def test_addnext_root_comment(self):
1602 Element = self.etree.Element 1603 Comment = self.etree.Comment 1604 root = Element('root') 1605 comment = Comment('TEXT ') 1606 comment.tail = "TAIL" 1607 1608 self.assertEqual(_bytes('<root></root>'), 1609 self._writeElement(root)) 1610 root.addnext(comment) 1611 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'), 1612 self._writeElement(root))
1613
1614 - def test_addprevious_comment(self):
1615 Element = self.etree.Element 1616 SubElement = self.etree.SubElement 1617 Comment = self.etree.Comment 1618 root = Element('root') 1619 SubElement(root, 'a') 1620 comment = Comment('TEXT ') 1621 comment.tail = "TAIL" 1622 1623 self.assertEqual(_bytes('<root><a></a></root>'), 1624 self._writeElement(root)) 1625 root[0].addprevious(comment) 1626 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 1627 self._writeElement(root))
1628
1629 - def test_addprevious_root_comment(self):
1630 Element = self.etree.Element 1631 Comment = self.etree.Comment 1632 root = Element('root') 1633 comment = Comment('TEXT ') 1634 comment.tail = "TAIL" 1635 1636 self.assertEqual(_bytes('<root></root>'), 1637 self._writeElement(root)) 1638 root.addprevious(comment) 1639 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'), 1640 self._writeElement(root))
1641 1642 # ET's Elements have items() and key(), but not values()
1643 - def test_attribute_values(self):
1644 XML = self.etree.XML 1645 1646 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 1647 values = root.values() 1648 values.sort() 1649 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1650 1651 # gives error in ElementTree
1652 - def test_comment_empty(self):
1653 Element = self.etree.Element 1654 Comment = self.etree.Comment 1655 1656 a = Element('a') 1657 a.append(Comment()) 1658 self.assertEqual( 1659 _bytes('<a><!----></a>'), 1660 self._writeElement(a))
1661 1662 # ElementTree ignores comments
1663 - def test_comment_parse_empty(self):
1664 ElementTree = self.etree.ElementTree 1665 tostring = self.etree.tostring 1666 1667 xml = _bytes('<a><b/><!----><c/></a>') 1668 f = BytesIO(xml) 1669 doc = ElementTree(file=f) 1670 a = doc.getroot() 1671 self.assertEqual( 1672 '', 1673 a[1].text) 1674 self.assertEqual( 1675 xml, 1676 tostring(a))
1677 1678 # ElementTree ignores comments
1679 - def test_comment_no_proxy_yet(self):
1680 ElementTree = self.etree.ElementTree 1681 1682 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 1683 doc = ElementTree(file=f) 1684 a = doc.getroot() 1685 self.assertEqual( 1686 ' hoi ', 1687 a[1].text)
1688 1689 # does not raise an exception in ElementTree
1690 - def test_comment_immutable(self):
1691 Element = self.etree.Element 1692 Comment = self.etree.Comment 1693 1694 c = Comment() 1695 el = Element('myel') 1696 1697 self.assertRaises(TypeError, c.append, el) 1698 self.assertRaises(TypeError, c.insert, 0, el) 1699 self.assertRaises(TypeError, c.set, "myattr", "test")
1700 1701 # test passing 'None' to dump
1702 - def test_dump_none(self):
1703 self.assertRaises(TypeError, self.etree.dump, None)
1704
1705 - def test_prefix(self):
1706 ElementTree = self.etree.ElementTree 1707 1708 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 1709 doc = ElementTree(file=f) 1710 a = doc.getroot() 1711 self.assertEqual( 1712 None, 1713 a.prefix) 1714 self.assertEqual( 1715 'foo', 1716 a[0].prefix)
1717
1718 - def test_prefix_default_ns(self):
1719 ElementTree = self.etree.ElementTree 1720 1721 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 1722 doc = ElementTree(file=f) 1723 a = doc.getroot() 1724 self.assertEqual( 1725 None, 1726 a.prefix) 1727 self.assertEqual( 1728 None, 1729 a[0].prefix)
1730
1731 - def test_getparent(self):
1732 Element = self.etree.Element 1733 SubElement = self.etree.SubElement 1734 1735 a = Element('a') 1736 b = SubElement(a, 'b') 1737 c = SubElement(a, 'c') 1738 d = SubElement(b, 'd') 1739 self.assertEqual( 1740 None, 1741 a.getparent()) 1742 self.assertEqual( 1743 a, 1744 b.getparent()) 1745 self.assertEqual( 1746 b.getparent(), 1747 c.getparent()) 1748 self.assertEqual( 1749 b, 1750 d.getparent())
1751
1752 - def test_iterchildren(self):
1753 XML = self.etree.XML 1754 1755 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1756 result = [] 1757 for el in root.iterchildren(): 1758 result.append(el.tag) 1759 self.assertEqual(['one', 'two', 'three'], result)
1760
1761 - def test_iterchildren_reversed(self):
1762 XML = self.etree.XML 1763 1764 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1765 result = [] 1766 for el in root.iterchildren(reversed=True): 1767 result.append(el.tag) 1768 self.assertEqual(['three', 'two', 'one'], result)
1769
1770 - def test_iterchildren_tag(self):
1771 XML = self.etree.XML 1772 1773 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1774 result = [] 1775 for el in root.iterchildren(tag='two'): 1776 result.append(el.text) 1777 self.assertEqual(['Two', 'Bla'], result)
1778
1779 - def test_iterchildren_tag_posarg(self):
1780 XML = self.etree.XML 1781 1782 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1783 result = [] 1784 for el in root.iterchildren('two'): 1785 result.append(el.text) 1786 self.assertEqual(['Two', 'Bla'], result)
1787
1788 - def test_iterchildren_tag_reversed(self):
1789 XML = self.etree.XML 1790 1791 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1792 result = [] 1793 for el in root.iterchildren(reversed=True, tag='two'): 1794 result.append(el.text) 1795 self.assertEqual(['Bla', 'Two'], result)
1796
1797 - def test_iterchildren_tag_multiple(self):
1798 XML = self.etree.XML 1799 1800 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1801 result = [] 1802 for el in root.iterchildren(tag=['two', 'three']): 1803 result.append(el.text) 1804 self.assertEqual(['Two', 'Bla', None], result)
1805
1806 - def test_iterchildren_tag_multiple_posarg(self):
1807 XML = self.etree.XML 1808 1809 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1810 result = [] 1811 for el in root.iterchildren('two', 'three'): 1812 result.append(el.text) 1813 self.assertEqual(['Two', 'Bla', None], result)
1814
1815 - def test_iterchildren_tag_multiple_reversed(self):
1816 XML = self.etree.XML 1817 1818 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1819 result = [] 1820 for el in root.iterchildren(reversed=True, tag=['two', 'three']): 1821 result.append(el.text) 1822 self.assertEqual([None, 'Bla', 'Two'], result)
1823
1824 - def test_iterancestors(self):
1825 Element = self.etree.Element 1826 SubElement = self.etree.SubElement 1827 1828 a = Element('a') 1829 b = SubElement(a, 'b') 1830 c = SubElement(a, 'c') 1831 d = SubElement(b, 'd') 1832 self.assertEqual( 1833 [], 1834 list(a.iterancestors())) 1835 self.assertEqual( 1836 [a], 1837 list(b.iterancestors())) 1838 self.assertEqual( 1839 [a], 1840 list(c.iterancestors())) 1841 self.assertEqual( 1842 [b, a], 1843 list(d.iterancestors()))
1844
1845 - def test_iterancestors_tag(self):
1846 Element = self.etree.Element 1847 SubElement = self.etree.SubElement 1848 1849 a = Element('a') 1850 b = SubElement(a, 'b') 1851 c = SubElement(a, 'c') 1852 d = SubElement(b, 'd') 1853 self.assertEqual( 1854 [a], 1855 list(d.iterancestors('a'))) 1856 self.assertEqual( 1857 [a], 1858 list(d.iterancestors(tag='a'))) 1859 1860 self.assertEqual( 1861 [b, a], 1862 list(d.iterancestors('*'))) 1863 self.assertEqual( 1864 [b, a], 1865 list(d.iterancestors(tag='*')))
1866
1867 - def test_iterancestors_tag_multiple(self):
1868 Element = self.etree.Element 1869 SubElement = self.etree.SubElement 1870 1871 a = Element('a') 1872 b = SubElement(a, 'b') 1873 c = SubElement(a, 'c') 1874 d = SubElement(b, 'd') 1875 self.assertEqual( 1876 [b, a], 1877 list(d.iterancestors(tag=('a', 'b')))) 1878 self.assertEqual( 1879 [b, a], 1880 list(d.iterancestors('a', 'b'))) 1881 1882 self.assertEqual( 1883 [], 1884 list(d.iterancestors(tag=('w', 'x', 'y', 'z')))) 1885 self.assertEqual( 1886 [], 1887 list(d.iterancestors('w', 'x', 'y', 'z'))) 1888 1889 self.assertEqual( 1890 [], 1891 list(d.iterancestors(tag=('d', 'x')))) 1892 self.assertEqual( 1893 [], 1894 list(d.iterancestors('d', 'x'))) 1895 1896 self.assertEqual( 1897 [b, a], 1898 list(d.iterancestors(tag=('b', '*')))) 1899 self.assertEqual( 1900 [b, a], 1901 list(d.iterancestors('b', '*'))) 1902 1903 self.assertEqual( 1904 [b], 1905 list(d.iterancestors(tag=('b', 'c')))) 1906 self.assertEqual( 1907 [b], 1908 list(d.iterancestors('b', 'c')))
1909
1910 - def test_iterdescendants(self):
1911 Element = self.etree.Element 1912 SubElement = self.etree.SubElement 1913 1914 a = Element('a') 1915 b = SubElement(a, 'b') 1916 c = SubElement(a, 'c') 1917 d = SubElement(b, 'd') 1918 e = SubElement(c, 'e') 1919 1920 self.assertEqual( 1921 [b, d, c, e], 1922 list(a.iterdescendants())) 1923 self.assertEqual( 1924 [], 1925 list(d.iterdescendants()))
1926
1927 - def test_iterdescendants_tag(self):
1928 Element = self.etree.Element 1929 SubElement = self.etree.SubElement 1930 1931 a = Element('a') 1932 b = SubElement(a, 'b') 1933 c = SubElement(a, 'c') 1934 d = SubElement(b, 'd') 1935 e = SubElement(c, 'e') 1936 1937 self.assertEqual( 1938 [], 1939 list(a.iterdescendants('a'))) 1940 self.assertEqual( 1941 [], 1942 list(a.iterdescendants(tag='a'))) 1943 1944 a2 = SubElement(e, 'a') 1945 self.assertEqual( 1946 [a2], 1947 list(a.iterdescendants('a'))) 1948 1949 self.assertEqual( 1950 [a2], 1951 list(c.iterdescendants('a'))) 1952 self.assertEqual( 1953 [a2], 1954 list(c.iterdescendants(tag='a')))
1955
1956 - def test_iterdescendants_tag_multiple(self):
1957 Element = self.etree.Element 1958 SubElement = self.etree.SubElement 1959 1960 a = Element('a') 1961 b = SubElement(a, 'b') 1962 c = SubElement(a, 'c') 1963 d = SubElement(b, 'd') 1964 e = SubElement(c, 'e') 1965 1966 self.assertEqual( 1967 [b, e], 1968 list(a.iterdescendants(tag=('a', 'b', 'e')))) 1969 self.assertEqual( 1970 [b, e], 1971 list(a.iterdescendants('a', 'b', 'e'))) 1972 1973 a2 = SubElement(e, 'a') 1974 self.assertEqual( 1975 [b, a2], 1976 list(a.iterdescendants(tag=('a', 'b')))) 1977 self.assertEqual( 1978 [b, a2], 1979 list(a.iterdescendants('a', 'b'))) 1980 1981 self.assertEqual( 1982 [], 1983 list(c.iterdescendants(tag=('x', 'y', 'z')))) 1984 self.assertEqual( 1985 [], 1986 list(c.iterdescendants('x', 'y', 'z'))) 1987 1988 self.assertEqual( 1989 [b, d, c, e, a2], 1990 list(a.iterdescendants(tag=('x', 'y', 'z', '*')))) 1991 self.assertEqual( 1992 [b, d, c, e, a2], 1993 list(a.iterdescendants('x', 'y', 'z', '*')))
1994
1995 - def test_getroottree(self):
1996 Element = self.etree.Element 1997 SubElement = self.etree.SubElement 1998 1999 a = Element('a') 2000 b = SubElement(a, 'b') 2001 c = SubElement(a, 'c') 2002 d = SubElement(b, 'd') 2003 self.assertEqual( 2004 a, 2005 a.getroottree().getroot()) 2006 self.assertEqual( 2007 a, 2008 b.getroottree().getroot()) 2009 self.assertEqual( 2010 a, 2011 d.getroottree().getroot())
2012
2013 - def test_getnext(self):
2014 Element = self.etree.Element 2015 SubElement = self.etree.SubElement 2016 2017 a = Element('a') 2018 b = SubElement(a, 'b') 2019 c = SubElement(a, 'c') 2020 self.assertEqual( 2021 None, 2022 a.getnext()) 2023 self.assertEqual( 2024 c, 2025 b.getnext()) 2026 self.assertEqual( 2027 None, 2028 c.getnext())
2029
2030 - def test_getprevious(self):
2031 Element = self.etree.Element 2032 SubElement = self.etree.SubElement 2033 2034 a = Element('a') 2035 b = SubElement(a, 'b') 2036 c = SubElement(a, 'c') 2037 d = SubElement(b, 'd') 2038 self.assertEqual( 2039 None, 2040 a.getprevious()) 2041 self.assertEqual( 2042 b, 2043 c.getprevious()) 2044 self.assertEqual( 2045 None, 2046 b.getprevious())
2047
2048 - def test_itersiblings(self):
2049 Element = self.etree.Element 2050 SubElement = self.etree.SubElement 2051 2052 a = Element('a') 2053 b = SubElement(a, 'b') 2054 c = SubElement(a, 'c') 2055 d = SubElement(b, 'd') 2056 self.assertEqual( 2057 [], 2058 list(a.itersiblings())) 2059 self.assertEqual( 2060 [c], 2061 list(b.itersiblings())) 2062 self.assertEqual( 2063 [], 2064 list(c.itersiblings())) 2065 self.assertEqual( 2066 [b], 2067 list(c.itersiblings(preceding=True))) 2068 self.assertEqual( 2069 [], 2070 list(b.itersiblings(preceding=True)))
2071
2072 - def test_itersiblings_tag(self):
2073 Element = self.etree.Element 2074 SubElement = self.etree.SubElement 2075 2076 a = Element('a') 2077 b = SubElement(a, 'b') 2078 c = SubElement(a, 'c') 2079 d = SubElement(b, 'd') 2080 self.assertEqual( 2081 [], 2082 list(a.itersiblings(tag='XXX'))) 2083 self.assertEqual( 2084 [c], 2085 list(b.itersiblings(tag='c'))) 2086 self.assertEqual( 2087 [c], 2088 list(b.itersiblings(tag='*'))) 2089 self.assertEqual( 2090 [b], 2091 list(c.itersiblings(preceding=True, tag='b'))) 2092 self.assertEqual( 2093 [], 2094 list(c.itersiblings(preceding=True, tag='c')))
2095
2096 - def test_itersiblings_tag_multiple(self):
2097 Element = self.etree.Element 2098 SubElement = self.etree.SubElement 2099 2100 a = Element('a') 2101 b = SubElement(a, 'b') 2102 c = SubElement(a, 'c') 2103 d = SubElement(b, 'd') 2104 e = SubElement(a, 'e') 2105 self.assertEqual( 2106 [], 2107 list(a.itersiblings(tag=('XXX', 'YYY')))) 2108 self.assertEqual( 2109 [c, e], 2110 list(b.itersiblings(tag=('c', 'd', 'e')))) 2111 self.assertEqual( 2112 [b], 2113 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd')))) 2114 self.assertEqual( 2115 [c, b], 2116 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2117
2118 - def test_parseid(self):
2119 parseid = self.etree.parseid 2120 XML = self.etree.XML 2121 xml_text = _bytes(''' 2122 <!DOCTYPE document [ 2123 <!ELEMENT document (h1,p)*> 2124 <!ELEMENT h1 (#PCDATA)> 2125 <!ATTLIST h1 myid ID #REQUIRED> 2126 <!ELEMENT p (#PCDATA)> 2127 <!ATTLIST p someid ID #REQUIRED> 2128 ]> 2129 <document> 2130 <h1 myid="chapter1">...</h1> 2131 <p id="note1" class="note">...</p> 2132 <p>Regular paragraph.</p> 2133 <p xml:id="xmlid">XML:ID paragraph.</p> 2134 <p someid="warn1" class="warning">...</p> 2135 </document> 2136 ''') 2137 2138 tree, dic = parseid(BytesIO(xml_text)) 2139 root = tree.getroot() 2140 root2 = XML(xml_text) 2141 self.assertEqual(self._writeElement(root), 2142 self._writeElement(root2)) 2143 expected = { 2144 "chapter1" : root[0], 2145 "xmlid" : root[3], 2146 "warn1" : root[4] 2147 } 2148 self.assertTrue("chapter1" in dic) 2149 self.assertTrue("warn1" in dic) 2150 self.assertTrue("xmlid" in dic) 2151 self._checkIDDict(dic, expected)
2152
2153 - def test_XMLDTDID(self):
2154 XMLDTDID = self.etree.XMLDTDID 2155 XML = self.etree.XML 2156 xml_text = _bytes(''' 2157 <!DOCTYPE document [ 2158 <!ELEMENT document (h1,p)*> 2159 <!ELEMENT h1 (#PCDATA)> 2160 <!ATTLIST h1 myid ID #REQUIRED> 2161 <!ELEMENT p (#PCDATA)> 2162 <!ATTLIST p someid ID #REQUIRED> 2163 ]> 2164 <document> 2165 <h1 myid="chapter1">...</h1> 2166 <p id="note1" class="note">...</p> 2167 <p>Regular paragraph.</p> 2168 <p xml:id="xmlid">XML:ID paragraph.</p> 2169 <p someid="warn1" class="warning">...</p> 2170 </document> 2171 ''') 2172 2173 root, dic = XMLDTDID(xml_text) 2174 root2 = XML(xml_text) 2175 self.assertEqual(self._writeElement(root), 2176 self._writeElement(root2)) 2177 expected = { 2178 "chapter1" : root[0], 2179 "xmlid" : root[3], 2180 "warn1" : root[4] 2181 } 2182 self.assertTrue("chapter1" in dic) 2183 self.assertTrue("warn1" in dic) 2184 self.assertTrue("xmlid" in dic) 2185 self._checkIDDict(dic, expected)
2186
2187 - def test_XMLDTDID_empty(self):
2188 XMLDTDID = self.etree.XMLDTDID 2189 XML = self.etree.XML 2190 xml_text = _bytes(''' 2191 <document> 2192 <h1 myid="chapter1">...</h1> 2193 <p id="note1" class="note">...</p> 2194 <p>Regular paragraph.</p> 2195 <p someid="warn1" class="warning">...</p> 2196 </document> 2197 ''') 2198 2199 root, dic = XMLDTDID(xml_text) 2200 root2 = XML(xml_text) 2201 self.assertEqual(self._writeElement(root), 2202 self._writeElement(root2)) 2203 expected = {} 2204 self._checkIDDict(dic, expected)
2205
2206 - def _checkIDDict(self, dic, expected):
2207 self.assertEqual(len(dic), 2208 len(expected)) 2209 self.assertEqual(sorted(dic.items()), 2210 sorted(expected.items())) 2211 if sys.version_info < (3,): 2212 self.assertEqual(sorted(dic.iteritems()), 2213 sorted(expected.iteritems())) 2214 self.assertEqual(sorted(dic.keys()), 2215 sorted(expected.keys())) 2216 if sys.version_info < (3,): 2217 self.assertEqual(sorted(dic.iterkeys()), 2218 sorted(expected.iterkeys())) 2219 if sys.version_info < (3,): 2220 self.assertEqual(sorted(dic.values()), 2221 sorted(expected.values())) 2222 self.assertEqual(sorted(dic.itervalues()), 2223 sorted(expected.itervalues()))
2224
2225 - def test_namespaces(self):
2226 etree = self.etree 2227 2228 r = {'foo': 'http://ns.infrae.com/foo'} 2229 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2230 self.assertEqual( 2231 'foo', 2232 e.prefix) 2233 self.assertEqual( 2234 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 2235 self._writeElement(e))
2236
2237 - def test_namespaces_default(self):
2238 etree = self.etree 2239 2240 r = {None: 'http://ns.infrae.com/foo'} 2241 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2242 self.assertEqual( 2243 None, 2244 e.prefix) 2245 self.assertEqual( 2246 '{http://ns.infrae.com/foo}bar', 2247 e.tag) 2248 self.assertEqual( 2249 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 2250 self._writeElement(e))
2251
2252 - def test_namespaces_default_and_attr(self):
2253 etree = self.etree 2254 2255 r = {None: 'http://ns.infrae.com/foo', 2256 'hoi': 'http://ns.infrae.com/hoi'} 2257 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2258 e.set('{http://ns.infrae.com/hoi}test', 'value') 2259 self.assertEqual( 2260 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 2261 self._writeElement(e))
2262
2263 - def test_attribute_keeps_namespace_prefix_on_merge(self):
2264 etree = self.etree 2265 2266 root = etree.Element('{http://test/ns}root', 2267 nsmap={None: 'http://test/ns'}) 2268 sub = etree.Element('{http://test/ns}sub', 2269 nsmap={'test': 'http://test/ns'}) 2270 2271 sub.attrib['{http://test/ns}attr'] = 'value' 2272 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2273 self.assertEqual( 2274 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 2275 etree.tostring(sub)) 2276 2277 root.append(sub) 2278 self.assertEqual( 2279 _bytes('<root xmlns="http://test/ns">' 2280 '<sub xmlns:test="http://test/ns" test:attr="value"/>' 2281 '</root>'), 2282 etree.tostring(root))
2283
2284 - def test_attribute_keeps_namespace_prefix_on_merge_with_nons(self):
2285 etree = self.etree 2286 2287 root = etree.Element('root') 2288 sub = etree.Element('{http://test/ns}sub', 2289 nsmap={'test': 'http://test/ns'}) 2290 2291 sub.attrib['{http://test/ns}attr'] = 'value' 2292 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2293 self.assertEqual( 2294 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 2295 etree.tostring(sub)) 2296 2297 root.append(sub) 2298 self.assertEqual( 2299 _bytes('<root>' 2300 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>' 2301 '</root>'), 2302 etree.tostring(root))
2303
2304 - def test_attribute_gets_namespace_prefix_on_merge_with_nons(self):
2305 etree = self.etree 2306 2307 root = etree.Element('root') 2308 sub = etree.Element('{http://test/ns}sub', 2309 nsmap={None: 'http://test/ns'}) 2310 2311 sub.attrib['{http://test/ns}attr'] = 'value' 2312 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2313 self.assertEqual( 2314 _bytes('<sub xmlns="http://test/ns" ' 2315 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 2316 etree.tostring(sub)) 2317 2318 root.append(sub) 2319 self.assertEqual( 2320 _bytes('<root>' 2321 '<sub xmlns="http://test/ns"' 2322 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>' 2323 '</root>'), 2324 etree.tostring(root))
2325
2326 - def test_attribute_gets_namespace_prefix_on_merge(self):
2327 etree = self.etree 2328 2329 root = etree.Element('{http://test/ns}root', 2330 nsmap={'test': 'http://test/ns', 2331 None: 'http://test/ns'}) 2332 sub = etree.Element('{http://test/ns}sub', 2333 nsmap={None: 'http://test/ns'}) 2334 2335 sub.attrib['{http://test/ns}attr'] = 'value' 2336 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2337 self.assertEqual( 2338 _bytes('<sub xmlns="http://test/ns" ' 2339 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 2340 etree.tostring(sub)) 2341 2342 root.append(sub) 2343 self.assertEqual( 2344 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">' 2345 '<test:sub test:attr="value"/>' 2346 '</test:root>'), 2347 etree.tostring(root))
2348
2349 - def test_namespaces_elementtree(self):
2350 etree = self.etree 2351 r = {None: 'http://ns.infrae.com/foo', 2352 'hoi': 'http://ns.infrae.com/hoi'} 2353 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 2354 tree = etree.ElementTree(element=e) 2355 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 2356 self.assertEqual( 2357 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 2358 self._writeElement(e))
2359
2360 - def test_namespaces_default_copy_element(self):
2361 etree = self.etree 2362 2363 r = {None: 'http://ns.infrae.com/foo'} 2364 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2365 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2366 2367 e1.append(e2) 2368 2369 self.assertEqual( 2370 None, 2371 e1.prefix) 2372 self.assertEqual( 2373 None, 2374 e1[0].prefix) 2375 self.assertEqual( 2376 '{http://ns.infrae.com/foo}bar', 2377 e1.tag) 2378 self.assertEqual( 2379 '{http://ns.infrae.com/foo}bar', 2380 e1[0].tag)
2381
2382 - def test_namespaces_copy_element(self):
2383 etree = self.etree 2384 2385 r = {None: 'http://ns.infrae.com/BAR'} 2386 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 2387 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2388 2389 e1.append(e2) 2390 2391 self.assertEqual( 2392 None, 2393 e1.prefix) 2394 self.assertNotEqual( 2395 None, 2396 e2.prefix) 2397 self.assertEqual( 2398 '{http://ns.infrae.com/BAR}bar', 2399 e1.tag) 2400 self.assertEqual( 2401 '{http://ns.infrae.com/foo}bar', 2402 e2.tag)
2403
2404 - def test_namespaces_reuse_after_move(self):
2405 ns_href = "http://a.b.c" 2406 one = self.etree.fromstring( 2407 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 2408 baz = one[0][0] 2409 2410 two = self.etree.fromstring( 2411 _bytes('<root xmlns:ns="%s"/>' % ns_href)) 2412 two.append(baz) 2413 del one # make sure the source document is deallocated 2414 2415 self.assertEqual('{%s}baz' % ns_href, baz.tag) 2416 self.assertEqual( 2417 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 2418 self.etree.tostring(two))
2419
2420 - def test_namespace_cleanup(self):
2421 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>') 2422 root = self.etree.fromstring(xml) 2423 self.assertEqual(xml, 2424 self.etree.tostring(root)) 2425 self.etree.cleanup_namespaces(root) 2426 self.assertEqual( 2427 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 2428 self.etree.tostring(root))
2429
2430 - def test_element_nsmap(self):
2431 etree = self.etree 2432 2433 r = {None: 'http://ns.infrae.com/foo', 2434 'hoi': 'http://ns.infrae.com/hoi'} 2435 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2436 self.assertEqual( 2437 r, 2438 e.nsmap)
2439
2440 - def test_subelement_nsmap(self):
2441 etree = self.etree 2442 2443 re = {None: 'http://ns.infrae.com/foo', 2444 'hoi': 'http://ns.infrae.com/hoi'} 2445 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 2446 2447 rs = {None: 'http://ns.infrae.com/honk', 2448 'top': 'http://ns.infrae.com/top'} 2449 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 2450 2451 r = re.copy() 2452 r.update(rs) 2453 self.assertEqual(re, e.nsmap) 2454 self.assertEqual(r, s.nsmap)
2455
2456 - def test_html_prefix_nsmap(self):
2457 etree = self.etree 2458 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description') 2459 self.assertEqual({'hha': None}, el.nsmap)
2460
2461 - def test_getiterator_filter_multiple(self):
2462 Element = self.etree.Element 2463 SubElement = self.etree.SubElement 2464 2465 a = Element('a') 2466 b = SubElement(a, 'b') 2467 c = SubElement(a, 'c') 2468 d = SubElement(b, 'd') 2469 e = SubElement(c, 'e') 2470 f = SubElement(c, 'f') 2471 2472 self.assertEqual( 2473 [a, b], 2474 list(a.getiterator('a', 'b'))) 2475 self.assertEqual( 2476 [], 2477 list(a.getiterator('x', 'y'))) 2478 self.assertEqual( 2479 [a, f], 2480 list(a.getiterator('f', 'a'))) 2481 self.assertEqual( 2482 [c, e, f], 2483 list(c.getiterator('c', '*', 'a'))) 2484 self.assertEqual( 2485 [], 2486 list(a.getiterator( (), () )))
2487
2488 - def test_getiterator_filter_multiple_tuple(self):
2489 Element = self.etree.Element 2490 SubElement = self.etree.SubElement 2491 2492 a = Element('a') 2493 b = SubElement(a, 'b') 2494 c = SubElement(a, 'c') 2495 d = SubElement(b, 'd') 2496 e = SubElement(c, 'e') 2497 f = SubElement(c, 'f') 2498 2499 self.assertEqual( 2500 [a, b], 2501 list(a.getiterator( ('a', 'b') ))) 2502 self.assertEqual( 2503 [], 2504 list(a.getiterator( ('x', 'y') ))) 2505 self.assertEqual( 2506 [a, f], 2507 list(a.getiterator( ('f', 'a') ))) 2508 self.assertEqual( 2509 [c, e, f], 2510 list(c.getiterator( ('c', '*', 'a') ))) 2511 self.assertEqual( 2512 [], 2513 list(a.getiterator( () )))
2514
2515 - def test_getiterator_filter_namespace(self):
2516 Element = self.etree.Element 2517 SubElement = self.etree.SubElement 2518 2519 a = Element('{a}a') 2520 b = SubElement(a, '{a}b') 2521 c = SubElement(a, '{a}c') 2522 d = SubElement(b, '{b}d') 2523 e = SubElement(c, '{a}e') 2524 f = SubElement(c, '{b}f') 2525 g = SubElement(c, 'g') 2526 2527 self.assertEqual( 2528 [a], 2529 list(a.getiterator('{a}a'))) 2530 self.assertEqual( 2531 [], 2532 list(a.getiterator('{b}a'))) 2533 self.assertEqual( 2534 [], 2535 list(a.getiterator('a'))) 2536 self.assertEqual( 2537 [a,b,d,c,e,f,g], 2538 list(a.getiterator('*'))) 2539 self.assertEqual( 2540 [f], 2541 list(c.getiterator('{b}*'))) 2542 self.assertEqual( 2543 [d, f], 2544 list(a.getiterator('{b}*'))) 2545 self.assertEqual( 2546 [g], 2547 list(a.getiterator('g'))) 2548 self.assertEqual( 2549 [g], 2550 list(a.getiterator('{}g'))) 2551 self.assertEqual( 2552 [g], 2553 list(a.getiterator('{}*')))
2554
2555 - def test_getiterator_filter_local_name(self):
2556 Element = self.etree.Element 2557 SubElement = self.etree.SubElement 2558 2559 a = Element('{a}a') 2560 b = SubElement(a, '{nsA}b') 2561 c = SubElement(b, '{nsB}b') 2562 d = SubElement(a, 'b') 2563 e = SubElement(a, '{nsA}e') 2564 f = SubElement(e, '{nsB}e') 2565 g = SubElement(e, 'e') 2566 2567 self.assertEqual( 2568 [b, c, d], 2569 list(a.getiterator('{*}b'))) 2570 self.assertEqual( 2571 [e, f, g], 2572 list(a.getiterator('{*}e'))) 2573 self.assertEqual( 2574 [a, b, c, d, e, f, g], 2575 list(a.getiterator('{*}*')))
2576
2577 - def test_getiterator_filter_entities(self):
2578 Element = self.etree.Element 2579 Entity = self.etree.Entity 2580 SubElement = self.etree.SubElement 2581 2582 a = Element('a') 2583 b = SubElement(a, 'b') 2584 entity_b = Entity("TEST-b") 2585 b.append(entity_b) 2586 2587 self.assertEqual( 2588 [entity_b], 2589 list(a.getiterator(Entity))) 2590 2591 entity_a = Entity("TEST-a") 2592 a.append(entity_a) 2593 2594 self.assertEqual( 2595 [entity_b, entity_a], 2596 list(a.getiterator(Entity))) 2597 2598 self.assertEqual( 2599 [entity_b], 2600 list(b.getiterator(Entity)))
2601
2602 - def test_getiterator_filter_element(self):
2603 Element = self.etree.Element 2604 Comment = self.etree.Comment 2605 PI = self.etree.PI 2606 SubElement = self.etree.SubElement 2607 2608 a = Element('a') 2609 b = SubElement(a, 'b') 2610 a.append(Comment("test")) 2611 a.append(PI("pi", "content")) 2612 c = SubElement(a, 'c') 2613 2614 self.assertEqual( 2615 [a, b, c], 2616 list(a.getiterator(Element)))
2617
2618 - def test_getiterator_filter_all_comment_pi(self):
2619 # ElementTree iterates over everything here 2620 Element = self.etree.Element 2621 Comment = self.etree.Comment 2622 PI = self.etree.PI 2623 SubElement = self.etree.SubElement 2624 2625 a = Element('a') 2626 b = SubElement(a, 'b') 2627 a.append(Comment("test")) 2628 a.append(PI("pi", "content")) 2629 c = SubElement(a, 'c') 2630 2631 self.assertEqual( 2632 [a, b, c], 2633 list(a.getiterator('*')))
2634
2635 - def test_elementtree_find_qname(self):
2636 XML = self.etree.XML 2637 ElementTree = self.etree.ElementTree 2638 QName = self.etree.QName 2639 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 2640 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
2641
2642 - def test_elementtree_findall_qname(self):
2643 XML = self.etree.XML 2644 ElementTree = self.etree.ElementTree 2645 QName = self.etree.QName 2646 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 2647 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
2648
2649 - def test_elementtree_findall_ns_qname(self):
2650 XML = self.etree.XML 2651 ElementTree = self.etree.ElementTree 2652 QName = self.etree.QName 2653 tree = ElementTree(XML( 2654 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))) 2655 self.assertEqual(len(list(tree.findall(QName("b")))), 2) 2656 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
2657
2658 - def test_findall_ns(self):
2659 XML = self.etree.XML 2660 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')) 2661 self.assertEqual(len(root.findall(".//{X}b")), 2) 2662 self.assertEqual(len(root.findall(".//{X}*")), 2) 2663 self.assertEqual(len(root.findall(".//b")), 3)
2664
2665 - def test_findall_different_nsmaps(self):
2666 XML = self.etree.XML 2667 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 2668 nsmap = {'xx': 'X'} 2669 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 2670 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2) 2671 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 2672 nsmap = {'xx': 'Y'} 2673 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) 2674 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1) 2675 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2676
2677 - def test_findall_different_nsmaps(self):
2678 XML = self.etree.XML 2679 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 2680 nsmap = {'xx': 'X'} 2681 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 2682 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2) 2683 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 2684 nsmap = {'xx': 'Y'} 2685 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) 2686 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1) 2687 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2688
2689 - def test_findall_syntax_error(self):
2690 XML = self.etree.XML 2691 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>')) 2692 self.assertRaises(SyntaxError, root.findall, '') 2693 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element 2694 self.assertRaises(SyntaxError, root.findall, './//')
2695
2696 - def test_index(self):
2697 etree = self.etree 2698 e = etree.Element('foo') 2699 for i in range(10): 2700 etree.SubElement(e, 'a%s' % i) 2701 for i in range(10): 2702 self.assertEqual( 2703 i, 2704 e.index(e[i])) 2705 self.assertEqual( 2706 3, e.index(e[3], 3)) 2707 self.assertRaises( 2708 ValueError, e.index, e[3], 4) 2709 self.assertRaises( 2710 ValueError, e.index, e[3], 0, 2) 2711 self.assertRaises( 2712 ValueError, e.index, e[8], 0, -3) 2713 self.assertRaises( 2714 ValueError, e.index, e[8], -5, -3) 2715 self.assertEqual( 2716 8, e.index(e[8], 0, -1)) 2717 self.assertEqual( 2718 8, e.index(e[8], -12, -1)) 2719 self.assertEqual( 2720 0, e.index(e[0], -12, -1))
2721
2722 - def test_replace(self):
2723 etree = self.etree 2724 e = etree.Element('foo') 2725 for i in range(10): 2726 el = etree.SubElement(e, 'a%s' % i) 2727 el.text = "text%d" % i 2728 el.tail = "tail%d" % i 2729 2730 child0 = e[0] 2731 child1 = e[1] 2732 child2 = e[2] 2733 2734 e.replace(e[0], e[1]) 2735 self.assertEqual( 2736 9, len(e)) 2737 self.assertEqual( 2738 child1, e[0]) 2739 self.assertEqual( 2740 child1.text, "text1") 2741 self.assertEqual( 2742 child1.tail, "tail1") 2743 self.assertEqual( 2744 child0.tail, "tail0") 2745 self.assertEqual( 2746 child2, e[1]) 2747 2748 e.replace(e[-1], e[0]) 2749 self.assertEqual( 2750 child1, e[-1]) 2751 self.assertEqual( 2752 child1.text, "text1") 2753 self.assertEqual( 2754 child1.tail, "tail1") 2755 self.assertEqual( 2756 child2, e[0])
2757
2758 - def test_replace_new(self):
2759 etree = self.etree 2760 e = etree.Element('foo') 2761 for i in range(10): 2762 etree.SubElement(e, 'a%s' % i) 2763 2764 new_element = etree.Element("test") 2765 new_element.text = "TESTTEXT" 2766 new_element.tail = "TESTTAIL" 2767 child1 = e[1] 2768 e.replace(e[0], new_element) 2769 self.assertEqual( 2770 new_element, e[0]) 2771 self.assertEqual( 2772 "TESTTEXT", 2773 e[0].text) 2774 self.assertEqual( 2775 "TESTTAIL", 2776 e[0].tail) 2777 self.assertEqual( 2778 child1, e[1])
2779
2780 - def test_setslice_all_empty_reversed(self):
2781 Element = self.etree.Element 2782 SubElement = self.etree.SubElement 2783 2784 a = Element('a') 2785 2786 e = Element('e') 2787 f = Element('f') 2788 g = Element('g') 2789 2790 s = [e, f, g] 2791 a[::-1] = s 2792 self.assertEqual( 2793 [g, f, e], 2794 list(a))
2795
2796 - def test_setslice_step(self):
2797 Element = self.etree.Element 2798 SubElement = self.etree.SubElement 2799 2800 a = Element('a') 2801 b = SubElement(a, 'b') 2802 c = SubElement(a, 'c') 2803 d = SubElement(a, 'd') 2804 e = SubElement(a, 'e') 2805 2806 x = Element('x') 2807 y = Element('y') 2808 2809 a[1::2] = [x, y] 2810 self.assertEqual( 2811 [b, x, d, y], 2812 list(a))
2813
2814 - def test_setslice_step_negative(self):
2815 Element = self.etree.Element 2816 SubElement = self.etree.SubElement 2817 2818 a = Element('a') 2819 b = SubElement(a, 'b') 2820 c = SubElement(a, 'c') 2821 d = SubElement(a, 'd') 2822 e = SubElement(a, 'e') 2823 2824 x = Element('x') 2825 y = Element('y') 2826 2827 a[1::-1] = [x, y] 2828 self.assertEqual( 2829 [y, x, d, e], 2830 list(a))
2831
2832 - def test_setslice_step_negative2(self):
2833 Element = self.etree.Element 2834 SubElement = self.etree.SubElement 2835 2836 a = Element('a') 2837 b = SubElement(a, 'b') 2838 c = SubElement(a, 'c') 2839 d = SubElement(a, 'd') 2840 e = SubElement(a, 'e') 2841 2842 x = Element('x') 2843 y = Element('y') 2844 2845 a[::-2] = [x, y] 2846 self.assertEqual( 2847 [b, y, d, x], 2848 list(a))
2849
2850 - def test_setslice_step_overrun(self):
2851 Element = self.etree.Element 2852 SubElement = self.etree.SubElement 2853 try: 2854 slice 2855 except NameError: 2856 print("slice() not found") 2857 return 2858 2859 a = Element('a') 2860 b = SubElement(a, 'b') 2861 c = SubElement(a, 'c') 2862 d = SubElement(a, 'd') 2863 e = SubElement(a, 'e') 2864 2865 x = Element('x') 2866 y = Element('y') 2867 z = Element('z') 2868 2869 self.assertRaises( 2870 ValueError, 2871 operator.setitem, a, slice(1,None,2), [x, y, z]) 2872 2873 self.assertEqual( 2874 [b, c, d, e], 2875 list(a))
2876
2877 - def test_sourceline_XML(self):
2878 XML = self.etree.XML 2879 root = XML(_bytes('''<?xml version="1.0"?> 2880 <root><test> 2881 2882 <bla/></test> 2883 </root> 2884 ''')) 2885 2886 self.assertEqual( 2887 [2, 2, 4], 2888 [ el.sourceline for el in root.getiterator() ])
2889
2890 - def test_sourceline_parse(self):
2891 parse = self.etree.parse 2892 tree = parse(fileInTestDir('include/test_xinclude.xml')) 2893 2894 self.assertEqual( 2895 [1, 2, 3], 2896 [ el.sourceline for el in tree.getiterator() ])
2897
2898 - def test_sourceline_iterparse_end(self):
2899 iterparse = self.etree.iterparse 2900 lines = [ el.sourceline for (event, el) in 2901 iterparse(fileInTestDir('include/test_xinclude.xml')) ] 2902 2903 self.assertEqual( 2904 [2, 3, 1], 2905 lines)
2906
2907 - def test_sourceline_iterparse_start(self):
2908 iterparse = self.etree.iterparse 2909 lines = [ el.sourceline for (event, el) in 2910 iterparse(fileInTestDir('include/test_xinclude.xml'), 2911 events=("start",)) ] 2912 2913 self.assertEqual( 2914 [1, 2, 3], 2915 lines)
2916
2917 - def test_sourceline_element(self):
2918 Element = self.etree.Element 2919 SubElement = self.etree.SubElement 2920 el = Element("test") 2921 self.assertEqual(None, el.sourceline) 2922 2923 child = SubElement(el, "test") 2924 self.assertEqual(None, el.sourceline) 2925 self.assertEqual(None, child.sourceline)
2926
2927 - def test_XML_base_url_docinfo(self):
2928 etree = self.etree 2929 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2930 docinfo = root.getroottree().docinfo 2931 self.assertEqual(docinfo.URL, "http://no/such/url")
2932
2933 - def test_XML_set_base_url_docinfo(self):
2934 etree = self.etree 2935 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 2936 docinfo = root.getroottree().docinfo 2937 self.assertEqual(docinfo.URL, "http://no/such/url") 2938 docinfo.URL = "https://secret/url" 2939 self.assertEqual(docinfo.URL, "https://secret/url")
2940
2941 - def test_parse_stringio_base_url(self):
2942 etree = self.etree 2943 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url") 2944 docinfo = tree.docinfo 2945 self.assertEqual(docinfo.URL, "http://no/such/url")
2946
2947 - def test_parse_base_url_docinfo(self):
2948 etree = self.etree 2949 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 2950 base_url="http://no/such/url") 2951 docinfo = tree.docinfo 2952 self.assertEqual(docinfo.URL, "http://no/such/url")
2953
2954 - def test_HTML_base_url_docinfo(self):
2955 etree = self.etree 2956 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url") 2957 docinfo = root.getroottree().docinfo 2958 self.assertEqual(docinfo.URL, "http://no/such/url")
2959
2960 - def test_docinfo_public(self):
2961 etree = self.etree 2962 xml_header = '<?xml version="1.0" encoding="ascii"?>' 2963 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 2964 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 2965 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 2966 2967 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 2968 2969 tree = etree.parse(BytesIO(xml)) 2970 docinfo = tree.docinfo 2971 self.assertEqual(docinfo.encoding, "ascii") 2972 self.assertEqual(docinfo.xml_version, "1.0") 2973 self.assertEqual(docinfo.public_id, pub_id) 2974 self.assertEqual(docinfo.system_url, sys_id) 2975 self.assertEqual(docinfo.root_name, 'html') 2976 self.assertEqual(docinfo.doctype, doctype_string)
2977
2978 - def test_docinfo_system(self):
2979 etree = self.etree 2980 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 2981 sys_id = "some.dtd" 2982 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 2983 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 2984 2985 tree = etree.parse(BytesIO(xml)) 2986 docinfo = tree.docinfo 2987 self.assertEqual(docinfo.encoding, "UTF-8") 2988 self.assertEqual(docinfo.xml_version, "1.0") 2989 self.assertEqual(docinfo.public_id, None) 2990 self.assertEqual(docinfo.system_url, sys_id) 2991 self.assertEqual(docinfo.root_name, 'html') 2992 self.assertEqual(docinfo.doctype, doctype_string)
2993
2994 - def test_docinfo_empty(self):
2995 etree = self.etree 2996 xml = _bytes('<html><body></body></html>') 2997 tree = etree.parse(BytesIO(xml)) 2998 docinfo = tree.docinfo 2999 self.assertEqual(docinfo.encoding, "UTF-8") 3000 self.assertEqual(docinfo.xml_version, "1.0") 3001 self.assertEqual(docinfo.public_id, None) 3002 self.assertEqual(docinfo.system_url, None) 3003 self.assertEqual(docinfo.root_name, 'html') 3004 self.assertEqual(docinfo.doctype, '')
3005
3006 - def test_docinfo_name_only(self):
3007 etree = self.etree 3008 xml = _bytes('<!DOCTYPE root><root></root>') 3009 tree = etree.parse(BytesIO(xml)) 3010 docinfo = tree.docinfo 3011 self.assertEqual(docinfo.encoding, "UTF-8") 3012 self.assertEqual(docinfo.xml_version, "1.0") 3013 self.assertEqual(docinfo.public_id, None) 3014 self.assertEqual(docinfo.system_url, None) 3015 self.assertEqual(docinfo.root_name, 'root') 3016 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
3017
3018 - def test_doctype_name_only_roundtrip(self):
3019 etree = self.etree 3020 xml = _bytes('<!DOCTYPE root>\n<root/>') 3021 tree = etree.parse(BytesIO(xml)) 3022 self.assertEqual(xml, etree.tostring(tree))
3023
3024 - def test_doctype_output_override(self):
3025 etree = self.etree 3026 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 3027 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 3028 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)) 3029 3030 xml = _bytes('<!DOCTYPE root>\n<root/>') 3031 tree = etree.parse(BytesIO(xml)) 3032 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string), 3033 etree.tostring(tree, doctype=doctype_string))
3034
3035 - def test_xml_base(self):
3036 etree = self.etree 3037 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3038 self.assertEqual(root.base, "http://no/such/url") 3039 self.assertEqual( 3040 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 3041 root.base = "https://secret/url" 3042 self.assertEqual(root.base, "https://secret/url") 3043 self.assertEqual( 3044 root.get('{http://www.w3.org/XML/1998/namespace}base'), 3045 "https://secret/url")
3046
3047 - def test_xml_base_attribute(self):
3048 etree = self.etree 3049 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3050 self.assertEqual(root.base, "http://no/such/url") 3051 self.assertEqual( 3052 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 3053 root.set('{http://www.w3.org/XML/1998/namespace}base', 3054 "https://secret/url") 3055 self.assertEqual(root.base, "https://secret/url") 3056 self.assertEqual( 3057 root.get('{http://www.w3.org/XML/1998/namespace}base'), 3058 "https://secret/url")
3059
3060 - def test_html_base(self):
3061 etree = self.etree 3062 root = etree.HTML(_bytes("<html><body></body></html>"), 3063 base_url="http://no/such/url") 3064 self.assertEqual(root.base, "http://no/such/url")
3065
3066 - def test_html_base_tag(self):
3067 etree = self.etree 3068 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 3069 self.assertEqual(root.base, "http://no/such/url")
3070
3071 - def test_parse_fileobject_unicode(self):
3072 # parse from a file object that returns unicode strings 3073 f = LargeFileLikeUnicode() 3074 tree = self.etree.parse(f) 3075 root = tree.getroot() 3076 self.assertTrue(root.tag.endswith('root'))
3077
3078 - def test_dtd_io(self):
3079 # check that DTDs that go in also go back out 3080 xml = _bytes('''\ 3081 <!DOCTYPE test SYSTEM "test.dtd" [ 3082 <!ENTITY entity "tasty"> 3083 <!ELEMENT test (a)> 3084 <!ELEMENT a (#PCDATA)> 3085 ]> 3086 <test><a>test-test</a></test>\ 3087 ''') 3088 tree = self.etree.parse(BytesIO(xml)) 3089 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 3090 xml.replace(_bytes(" "), _bytes("")))
3091
3092 - def test_byte_zero(self):
3093 Element = self.etree.Element 3094 3095 a = Element('a') 3096 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 3097 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 3098 3099 self.assertRaises(ValueError, Element, 'ha\0ho')
3100
3101 - def test_unicode_byte_zero(self):
3102 Element = self.etree.Element 3103 3104 a = Element('a') 3105 self.assertRaises(ValueError, setattr, a, "text", 3106 _str('ha\0ho')) 3107 self.assertRaises(ValueError, setattr, a, "tail", 3108 _str('ha\0ho')) 3109 3110 self.assertRaises(ValueError, Element, 3111 _str('ha\0ho'))
3112
3113 - def test_byte_invalid(self):
3114 Element = self.etree.Element 3115 3116 a = Element('a') 3117 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 3118 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 3119 3120 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 3121 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 3122 3123 self.assertRaises(ValueError, Element, 'ha\x07ho') 3124 self.assertRaises(ValueError, Element, 'ha\x02ho')
3125
3126 - def test_unicode_byte_invalid(self):
3127 Element = self.etree.Element 3128 3129 a = Element('a') 3130 self.assertRaises(ValueError, setattr, a, "text", 3131 _str('ha\x07ho')) 3132 self.assertRaises(ValueError, setattr, a, "text", 3133 _str('ha\x02ho')) 3134 3135 self.assertRaises(ValueError, setattr, a, "tail", 3136 _str('ha\x07ho')) 3137 self.assertRaises(ValueError, setattr, a, "tail", 3138 _str('ha\x02ho')) 3139 3140 self.assertRaises(ValueError, Element, 3141 _str('ha\x07ho')) 3142 self.assertRaises(ValueError, Element, 3143 _str('ha\x02ho'))
3144
3145 - def test_unicode_byte_invalid_sequence(self):
3146 Element = self.etree.Element 3147 3148 a = Element('a') 3149 self.assertRaises(ValueError, setattr, a, "text", 3150 _str('ha\u1234\x07ho')) 3151 self.assertRaises(ValueError, setattr, a, "text", 3152 _str('ha\u1234\x02ho')) 3153 3154 self.assertRaises(ValueError, setattr, a, "tail", 3155 _str('ha\u1234\x07ho')) 3156 self.assertRaises(ValueError, setattr, a, "tail", 3157 _str('ha\u1234\x02ho')) 3158 3159 self.assertRaises(ValueError, Element, 3160 _str('ha\u1234\x07ho')) 3161 self.assertRaises(ValueError, Element, 3162 _str('ha\u1234\x02ho'))
3163
3164 - def test_encoding_tostring_utf16(self):
3165 # ElementTree fails to serialize this 3166 tostring = self.etree.tostring 3167 Element = self.etree.Element 3168 SubElement = self.etree.SubElement 3169 3170 a = Element('a') 3171 b = SubElement(a, 'b') 3172 c = SubElement(a, 'c') 3173 3174 result = tostring(a, encoding='UTF-16') 3175 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3176 canonicalize(result))
3177
3178 - def test_tostring_none(self):
3179 # ElementTree raises an AssertionError here 3180 tostring = self.etree.tostring 3181 self.assertRaises(TypeError, self.etree.tostring, None)
3182
3183 - def test_tostring_pretty(self):
3184 tostring = self.etree.tostring 3185 Element = self.etree.Element 3186 SubElement = self.etree.SubElement 3187 3188 a = Element('a') 3189 b = SubElement(a, 'b') 3190 c = SubElement(a, 'c') 3191 3192 result = tostring(a) 3193 self.assertEqual(result, _bytes("<a><b/><c/></a>")) 3194 3195 result = tostring(a, pretty_print=False) 3196 self.assertEqual(result, _bytes("<a><b/><c/></a>")) 3197 3198 result = tostring(a, pretty_print=True) 3199 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3200
3201 - def test_tostring_with_tail(self):
3202 tostring = self.etree.tostring 3203 Element = self.etree.Element 3204 SubElement = self.etree.SubElement 3205 3206 a = Element('a') 3207 a.tail = "aTAIL" 3208 b = SubElement(a, 'b') 3209 b.tail = "bTAIL" 3210 c = SubElement(a, 'c') 3211 3212 result = tostring(a) 3213 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 3214 3215 result = tostring(a, with_tail=False) 3216 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>")) 3217 3218 result = tostring(a, with_tail=True) 3219 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3220
3221 - def test_standalone(self):
3222 tostring = self.etree.tostring 3223 XML = self.etree.XML 3224 ElementTree = self.etree.ElementTree 3225 Element = self.etree.Element 3226 3227 tree = Element("root").getroottree() 3228 self.assertEqual(None, tree.docinfo.standalone) 3229 3230 tree = XML(_bytes("<root/>")).getroottree() 3231 self.assertEqual(None, tree.docinfo.standalone) 3232 3233 tree = XML(_bytes( 3234 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>" 3235 )).getroottree() 3236 self.assertEqual(True, tree.docinfo.standalone) 3237 3238 tree = XML(_bytes( 3239 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>" 3240 )).getroottree() 3241 self.assertEqual(False, tree.docinfo.standalone)
3242
3243 - def test_tostring_standalone(self):
3244 tostring = self.etree.tostring 3245 XML = self.etree.XML 3246 ElementTree = self.etree.ElementTree 3247 3248 root = XML(_bytes("<root/>")) 3249 3250 tree = ElementTree(root) 3251 self.assertEqual(None, tree.docinfo.standalone) 3252 3253 result = tostring(root, xml_declaration=True, encoding="ASCII") 3254 self.assertEqual(result, _bytes( 3255 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 3256 3257 result = tostring(root, xml_declaration=True, encoding="ASCII", 3258 standalone=True) 3259 self.assertEqual(result, _bytes( 3260 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 3261 3262 tree = ElementTree(XML(result)) 3263 self.assertEqual(True, tree.docinfo.standalone) 3264 3265 result = tostring(root, xml_declaration=True, encoding="ASCII", 3266 standalone=False) 3267 self.assertEqual(result, _bytes( 3268 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>")) 3269 3270 tree = ElementTree(XML(result)) 3271 self.assertEqual(False, tree.docinfo.standalone)
3272
3273 - def test_tostring_standalone_in_out(self):
3274 tostring = self.etree.tostring 3275 XML = self.etree.XML 3276 ElementTree = self.etree.ElementTree 3277 3278 root = XML(_bytes( 3279 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>")) 3280 3281 tree = ElementTree(root) 3282 self.assertEqual(True, tree.docinfo.standalone) 3283 3284 result = tostring(root, xml_declaration=True, encoding="ASCII") 3285 self.assertEqual(result, _bytes( 3286 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 3287 3288 result = tostring(root, xml_declaration=True, encoding="ASCII", 3289 standalone=True) 3290 self.assertEqual(result, _bytes( 3291 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3292
3293 - def test_tostring_method_text_encoding(self):
3294 tostring = self.etree.tostring 3295 Element = self.etree.Element 3296 SubElement = self.etree.SubElement 3297 3298 a = Element('a') 3299 a.text = "A" 3300 a.tail = "tail" 3301 b = SubElement(a, 'b') 3302 b.text = "B" 3303 b.tail = _str("Søk på nettet") 3304 c = SubElement(a, 'c') 3305 c.text = "C" 3306 3307 result = tostring(a, method="text", encoding="UTF-16") 3308 3309 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"), 3310 result)
3311
3312 - def test_tostring_method_text_unicode(self):
3313 tostring = self.etree.tostring 3314 Element = self.etree.Element 3315 SubElement = self.etree.SubElement 3316 3317 a = Element('a') 3318 a.text = _str('Søk på nettetA') 3319 a.tail = "tail" 3320 b = SubElement(a, 'b') 3321 b.text = "B" 3322 b.tail = _str('Søk på nettetB') 3323 c = SubElement(a, 'c') 3324 c.text = "C" 3325 3326 self.assertRaises(UnicodeEncodeError, 3327 tostring, a, method="text") 3328 3329 self.assertEqual( 3330 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 3331 tostring(a, encoding="UTF-8", method="text"))
3332
3333 - def test_tounicode(self):
3334 tounicode = self.etree.tounicode 3335 Element = self.etree.Element 3336 SubElement = self.etree.SubElement 3337 3338 a = Element('a') 3339 b = SubElement(a, 'b') 3340 c = SubElement(a, 'c') 3341 3342 self.assertTrue(isinstance(tounicode(a), _unicode)) 3343 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3344 canonicalize(tounicode(a)))
3345
3346 - def test_tounicode_element(self):
3347 tounicode = self.etree.tounicode 3348 Element = self.etree.Element 3349 SubElement = self.etree.SubElement 3350 3351 a = Element('a') 3352 b = SubElement(a, 'b') 3353 c = SubElement(a, 'c') 3354 d = SubElement(c, 'd') 3355 self.assertTrue(isinstance(tounicode(b), _unicode)) 3356 self.assertTrue(isinstance(tounicode(c), _unicode)) 3357 self.assertEqual(_bytes('<b></b>'), 3358 canonicalize(tounicode(b))) 3359 self.assertEqual(_bytes('<c><d></d></c>'), 3360 canonicalize(tounicode(c)))
3361
3362 - def test_tounicode_none(self):
3363 tounicode = self.etree.tounicode 3364 self.assertRaises(TypeError, self.etree.tounicode, None)
3365
3366 - def test_tounicode_element_tail(self):
3367 tounicode = self.etree.tounicode 3368 Element = self.etree.Element 3369 SubElement = self.etree.SubElement 3370 3371 a = Element('a') 3372 b = SubElement(a, 'b') 3373 c = SubElement(a, 'c') 3374 d = SubElement(c, 'd') 3375 b.tail = 'Foo' 3376 3377 self.assertTrue(isinstance(tounicode(b), _unicode)) 3378 self.assertTrue(tounicode(b) == '<b/>Foo' or 3379 tounicode(b) == '<b />Foo')
3380
3381 - def test_tounicode_pretty(self):
3382 tounicode = self.etree.tounicode 3383 Element = self.etree.Element 3384 SubElement = self.etree.SubElement 3385 3386 a = Element('a') 3387 b = SubElement(a, 'b') 3388 c = SubElement(a, 'c') 3389 3390 result = tounicode(a) 3391 self.assertEqual(result, "<a><b/><c/></a>") 3392 3393 result = tounicode(a, pretty_print=False) 3394 self.assertEqual(result, "<a><b/><c/></a>") 3395 3396 result = tounicode(a, pretty_print=True) 3397 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3398
3399 - def test_tostring_unicode(self):
3400 tostring = self.etree.tostring 3401 Element = self.etree.Element 3402 SubElement = self.etree.SubElement 3403 3404 a = Element('a') 3405 b = SubElement(a, 'b') 3406 c = SubElement(a, 'c') 3407 3408 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode)) 3409 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3410 canonicalize(tostring(a, encoding=_unicode)))
3411
3412 - def test_tostring_unicode_element(self):
3413 tostring = self.etree.tostring 3414 Element = self.etree.Element 3415 SubElement = self.etree.SubElement 3416 3417 a = Element('a') 3418 b = SubElement(a, 'b') 3419 c = SubElement(a, 'c') 3420 d = SubElement(c, 'd') 3421 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 3422 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode)) 3423 self.assertEqual(_bytes('<b></b>'), 3424 canonicalize(tostring(b, encoding=_unicode))) 3425 self.assertEqual(_bytes('<c><d></d></c>'), 3426 canonicalize(tostring(c, encoding=_unicode)))
3427
3428 - def test_tostring_unicode_none(self):
3429 tostring = self.etree.tostring 3430 self.assertRaises(TypeError, self.etree.tostring, 3431 None, encoding=_unicode)
3432
3433 - def test_tostring_unicode_element_tail(self):
3434 tostring = self.etree.tostring 3435 Element = self.etree.Element 3436 SubElement = self.etree.SubElement 3437 3438 a = Element('a') 3439 b = SubElement(a, 'b') 3440 c = SubElement(a, 'c') 3441 d = SubElement(c, 'd') 3442 b.tail = 'Foo' 3443 3444 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 3445 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or 3446 tostring(b, encoding=_unicode) == '<b />Foo')
3447
3448 - def test_tostring_unicode_pretty(self):
3449 tostring = self.etree.tostring 3450 Element = self.etree.Element 3451 SubElement = self.etree.SubElement 3452 3453 a = Element('a') 3454 b = SubElement(a, 'b') 3455 c = SubElement(a, 'c') 3456 3457 result = tostring(a, encoding=_unicode) 3458 self.assertEqual(result, "<a><b/><c/></a>") 3459 3460 result = tostring(a, encoding=_unicode, pretty_print=False) 3461 self.assertEqual(result, "<a><b/><c/></a>") 3462 3463 result = tostring(a, encoding=_unicode, pretty_print=True) 3464 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3465
3466 - def test_pypy_proxy_collect(self):
3467 root = etree.Element('parent') 3468 etree.SubElement(root, 'child') 3469 3470 self.assertEqual(len(root), 1) 3471 self.assertEqual(root[0].tag, 'child') 3472 3473 # in PyPy, GC used to kill the Python proxy instance without cleanup 3474 gc.collect() 3475 self.assertEqual(len(root), 1) 3476 self.assertEqual(root[0].tag, 'child')
3477
3478 - def test_element_refcycle(self):
3479 class SubEl(etree.ElementBase): 3480 pass
3481 3482 el1 = SubEl() 3483 el2 = SubEl() 3484 self.assertEqual('SubEl', el1.tag) 3485 self.assertEqual('SubEl', el2.tag) 3486 el1.other = el2 3487 el2.other = el1 3488 3489 del el1, el2 3490 gc.collect() 3491 # not really testing anything here, but it shouldn't crash 3492 3493 # helper methods 3494
3495 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3496 """Write out element for comparison. 3497 """ 3498 ElementTree = self.etree.ElementTree 3499 f = BytesIO() 3500 tree = ElementTree(element=element) 3501 tree.write(f, encoding=encoding, compression=compression) 3502 data = f.getvalue() 3503 if compression: 3504 data = zlib.decompress(data) 3505 return canonicalize(data)
3506 3507
3508 -class _XIncludeTestCase(HelperTestCase):
3509 - def test_xinclude_text(self):
3510 filename = fileInTestDir('test_broken.xml') 3511 root = etree.XML(_bytes('''\ 3512 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 3513 <xi:include href="%s" parse="text"/> 3514 </doc> 3515 ''' % filename)) 3516 old_text = root.text 3517 content = read_file(filename) 3518 old_tail = root[0].tail 3519 3520 self.include( etree.ElementTree(root) ) 3521 self.assertEqual(old_text + content + old_tail, 3522 root.text)
3523
3524 - def test_xinclude(self):
3525 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 3526 self.assertNotEqual( 3527 'a', 3528 tree.getroot()[1].tag) 3529 # process xincludes 3530 self.include( tree ) 3531 # check whether we find it replaced with included data 3532 self.assertEqual( 3533 'a', 3534 tree.getroot()[1].tag)
3535
3536 - def test_xinclude_resolver(self):
3537 class res(etree.Resolver): 3538 include_text = read_file(fileInTestDir('test.xml')) 3539 called = {} 3540 def resolve(self, url, id, context): 3541 if url.endswith(".dtd"): 3542 self.called["dtd"] = True 3543 return self.resolve_filename( 3544 fileInTestDir('test.dtd'), context) 3545 elif url.endswith("test_xinclude.xml"): 3546 self.called["input"] = True 3547 return None # delegate to default resolver 3548 else: 3549 self.called["include"] = True 3550 return self.resolve_string(self.include_text, context)
3551 3552 res_instance = res() 3553 parser = etree.XMLParser(load_dtd = True) 3554 parser.resolvers.add(res_instance) 3555 3556 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 3557 parser = parser) 3558 3559 self.include(tree) 3560 3561 called = list(res_instance.called.items()) 3562 called.sort() 3563 self.assertEqual( 3564 [("dtd", True), ("include", True), ("input", True)], 3565 called) 3566
3567 -class ETreeXIncludeTestCase(_XIncludeTestCase):
3568 - def include(self, tree):
3569 tree.xinclude()
3570 3571
3572 -class ElementIncludeTestCase(_XIncludeTestCase):
3573 from lxml import ElementInclude
3574 - def include(self, tree):
3575 self.ElementInclude.include(tree.getroot())
3576 3577
3578 -class ETreeC14NTestCase(HelperTestCase):
3579 - def test_c14n(self):
3580 tree = self.parse(_bytes('<a><b/></a>')) 3581 f = BytesIO() 3582 tree.write_c14n(f) 3583 s = f.getvalue() 3584 self.assertEqual(_bytes('<a><b></b></a>'), 3585 s)
3586
3587 - def test_c14n_gzip(self):
3588 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3589 f = BytesIO() 3590 tree.write_c14n(f, compression=9) 3591 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue())) 3592 try: 3593 s = gzfile.read() 3594 finally: 3595 gzfile.close() 3596 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 3597 s)
3598
3599 - def test_c14n_file(self):
3600 tree = self.parse(_bytes('<a><b/></a>')) 3601 handle, filename = tempfile.mkstemp() 3602 try: 3603 tree.write_c14n(filename) 3604 data = read_file(filename, 'rb') 3605 finally: 3606 os.close(handle) 3607 os.remove(filename) 3608 self.assertEqual(_bytes('<a><b></b></a>'), 3609 data)
3610
3611 - def test_c14n_file_gzip(self):
3612 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3613 handle, filename = tempfile.mkstemp() 3614 try: 3615 tree.write_c14n(filename, compression=9) 3616 f = gzip.open(filename, 'rb') 3617 try: 3618 data = f.read() 3619 finally: 3620 f.close() 3621 finally: 3622 os.close(handle) 3623 os.remove(filename) 3624 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 3625 data)
3626
3627 - def test_c14n_with_comments(self):
3628 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3629 f = BytesIO() 3630 tree.write_c14n(f) 3631 s = f.getvalue() 3632 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3633 s) 3634 f = BytesIO() 3635 tree.write_c14n(f, with_comments=True) 3636 s = f.getvalue() 3637 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3638 s) 3639 f = BytesIO() 3640 tree.write_c14n(f, with_comments=False) 3641 s = f.getvalue() 3642 self.assertEqual(_bytes('<a><b></b></a>'), 3643 s)
3644
3646 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3647 s = etree.tostring(tree, method='c14n') 3648 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3649 s) 3650 s = etree.tostring(tree, method='c14n', with_comments=True) 3651 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3652 s) 3653 s = etree.tostring(tree, method='c14n', with_comments=False) 3654 self.assertEqual(_bytes('<a><b></b></a>'), 3655 s)
3656
3658 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3659 s = etree.tostring(tree.getroot(), method='c14n') 3660 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 3661 s) 3662 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True) 3663 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 3664 s) 3665 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False) 3666 self.assertEqual(_bytes('<a><b></b></a>'), 3667 s)
3668
3669 - def test_c14n_exclusive(self):
3670 tree = self.parse(_bytes( 3671 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3672 f = BytesIO() 3673 tree.write_c14n(f) 3674 s = f.getvalue() 3675 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3676 s) 3677 f = BytesIO() 3678 tree.write_c14n(f, exclusive=False) 3679 s = f.getvalue() 3680 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3681 s) 3682 f = BytesIO() 3683 tree.write_c14n(f, exclusive=True) 3684 s = f.getvalue() 3685 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 3686 s) 3687 3688 f = BytesIO() 3689 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z']) 3690 s = f.getvalue() 3691 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'), 3692 s)
3693
3695 tree = self.parse(_bytes( 3696 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3697 s = etree.tostring(tree, method='c14n') 3698 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3699 s) 3700 s = etree.tostring(tree, method='c14n', exclusive=False) 3701 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3702 s) 3703 s = etree.tostring(tree, method='c14n', exclusive=True) 3704 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 3705 s) 3706 3707 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 3708 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'), 3709 s)
3710
3712 tree = self.parse(_bytes( 3713 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3714 s = etree.tostring(tree.getroot(), method='c14n') 3715 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3716 s) 3717 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False) 3718 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3719 s) 3720 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True) 3721 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 3722 s) 3723 3724 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False) 3725 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 3726 s) 3727 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True) 3728 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'), 3729 s) 3730 3731 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 3732 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 3733 s)
3734
3736 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)""" 3737 tree = self.parse(_bytes( 3738 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3739 3740 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z']) 3741 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3742 s)
3743 3744
3745 -class ETreeWriteTestCase(HelperTestCase):
3746 - def test_write(self):
3747 tree = self.parse(_bytes('<a><b/></a>')) 3748 f = BytesIO() 3749 tree.write(f) 3750 s = f.getvalue() 3751 self.assertEqual(_bytes('<a><b/></a>'), 3752 s)
3753
3754 - def test_write_gzip(self):
3755 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3756 f = BytesIO() 3757 tree.write(f, compression=9) 3758 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue())) 3759 try: 3760 s = gzfile.read() 3761 finally: 3762 gzfile.close() 3763 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3764 s)
3765
3766 - def test_write_gzip_level(self):
3767 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3768 f = BytesIO() 3769 tree.write(f, compression=0) 3770 s0 = f.getvalue() 3771 3772 f = BytesIO() 3773 tree.write(f) 3774 self.assertEqual(f.getvalue(), s0) 3775 3776 f = BytesIO() 3777 tree.write(f, compression=1) 3778 s = f.getvalue() 3779 self.assertTrue(len(s) <= len(s0)) 3780 gzfile = gzip.GzipFile(fileobj=BytesIO(s)) 3781 try: 3782 s1 = gzfile.read() 3783 finally: 3784 gzfile.close() 3785 3786 f = BytesIO() 3787 tree.write(f, compression=9) 3788 s = f.getvalue() 3789 self.assertTrue(len(s) <= len(s0)) 3790 gzfile = gzip.GzipFile(fileobj=BytesIO(s)) 3791 try: 3792 s9 = gzfile.read() 3793 finally: 3794 gzfile.close() 3795 3796 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3797 s0) 3798 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3799 s1) 3800 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3801 s9)
3802
3803 - def test_write_file(self):
3804 tree = self.parse(_bytes('<a><b/></a>')) 3805 handle, filename = tempfile.mkstemp() 3806 try: 3807 tree.write(filename) 3808 data = read_file(filename, 'rb') 3809 finally: 3810 os.close(handle) 3811 os.remove(filename) 3812 self.assertEqual(_bytes('<a><b/></a>'), 3813 data)
3814
3815 - def test_write_file_gzip(self):
3816 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3817 handle, filename = tempfile.mkstemp() 3818 try: 3819 tree.write(filename, compression=9) 3820 f = gzip.open(filename, 'rb') 3821 try: 3822 data = f.read() 3823 finally: 3824 f.close() 3825 finally: 3826 os.close(handle) 3827 os.remove(filename) 3828 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3829 data)
3830
3831 - def test_write_file_gzip_parse(self):
3832 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3833 handle, filename = tempfile.mkstemp() 3834 try: 3835 tree.write(filename, compression=9) 3836 data = etree.tostring(etree.parse(filename)) 3837 finally: 3838 os.close(handle) 3839 os.remove(filename) 3840 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3841 data)
3842
3844 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3845 handle, filename = tempfile.mkstemp() 3846 try: 3847 tree.write(filename, compression=9) 3848 data = etree.tostring(etree.parse( 3849 gzip.GzipFile(filename))) 3850 finally: 3851 os.close(handle) 3852 os.remove(filename) 3853 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3854 data)
3855
3856 -class ETreeErrorLogTest(HelperTestCase):
3857 etree = etree 3858
3859 - def test_parse_error_logging(self):
3860 parse = self.etree.parse 3861 f = BytesIO('<a><b></c></b></a>') 3862 self.etree.clear_error_log() 3863 try: 3864 parse(f) 3865 logs = None 3866 except SyntaxError: 3867 e = sys.exc_info()[1] 3868 logs = e.error_log 3869 f.close() 3870 self.assertTrue([ log for log in logs 3871 if 'mismatch' in log.message ]) 3872 self.assertTrue([ log for log in logs 3873 if 'PARSER' in log.domain_name]) 3874 self.assertTrue([ log for log in logs 3875 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ]) 3876 self.assertTrue([ log for log in logs 3877 if 1 == log.line ]) 3878 self.assertTrue([ log for log in logs 3879 if 15 == log.column ])
3880
3881 - def _test_python_error_logging(self):
3882 """This can't really be tested as long as there isn't a way to 3883 reset the logging setup ... 3884 """ 3885 parse = self.etree.parse 3886 3887 messages = [] 3888 class Logger(self.etree.PyErrorLog): 3889 def log(self, entry, message, *args): 3890 messages.append(message)
3891 3892 self.etree.use_global_python_log(Logger()) 3893 f = BytesIO('<a><b></c></b></a>') 3894 try: 3895 parse(f) 3896 except SyntaxError: 3897 pass 3898 f.close() 3899 3900 self.assertTrue([ message for message in messages 3901 if 'mismatch' in message ]) 3902 self.assertTrue([ message for message in messages 3903 if ':PARSER:' in message]) 3904 self.assertTrue([ message for message in messages 3905 if ':ERR_TAG_NAME_MISMATCH:' in message ]) 3906 self.assertTrue([ message for message in messages 3907 if ':1:15:' in message ]) 3908 3909
3910 -class XMLPullParserTest(unittest.TestCase):
3911 etree = etree 3912
3913 - def assert_event_tags(self, events, expected):
3914 self.assertEqual([(action, elem.tag) for action, elem in events], 3915 expected)
3916
3918 class Target(object): 3919 def start(self, tag, attrib): 3920 return 'start(%s)' % tag
3921 def end(self, tag): 3922 return 'end(%s)' % tag
3923 def close(self): 3924 return 'close()' 3925 3926 parser = self.etree.XMLPullParser(target=Target()) 3927 events = parser.read_events() 3928 3929 parser.feed('<root><element>') 3930 self.assertFalse(list(events)) 3931 self.assertFalse(list(events)) 3932 parser.feed('</element><child>') 3933 self.assertEqual([('end', 'end(element)')], list(events)) 3934 parser.feed('</child>') 3935 self.assertEqual([('end', 'end(child)')], list(events)) 3936 parser.feed('</root>') 3937 self.assertEqual([('end', 'end(root)')], list(events)) 3938 self.assertFalse(list(events)) 3939 self.assertEqual('close()', parser.close()) 3940
3941 - def test_pull_from_simple_target_start_end(self):
3942 class Target(object): 3943 def start(self, tag, attrib): 3944 return 'start(%s)' % tag
3945 def end(self, tag): 3946 return 'end(%s)' % tag 3947 def close(self): 3948 return 'close()' 3949 3950 parser = self.etree.XMLPullParser( 3951 ['start', 'end'], target=Target()) 3952 events = parser.read_events() 3953 3954 parser.feed('<root><element>') 3955 self.assertEqual( 3956 [('start', 'start(root)'), ('start', 'start(element)')], 3957 list(events)) 3958 self.assertFalse(list(events)) 3959 parser.feed('</element><child>') 3960 self.assertEqual( 3961 [('end', 'end(element)'), ('start', 'start(child)')], 3962 list(events)) 3963 parser.feed('</child>') 3964 self.assertEqual( 3965 [('end', 'end(child)')], 3966 list(events)) 3967 parser.feed('</root>') 3968 self.assertEqual( 3969 [('end', 'end(root)')], 3970 list(events)) 3971 self.assertFalse(list(events)) 3972 self.assertEqual('close()', parser.close()) 3973
3974 - def test_pull_from_tree_builder(self):
3975 parser = self.etree.XMLPullParser( 3976 ['start', 'end'], target=etree.TreeBuilder()) 3977 events = parser.read_events() 3978 3979 parser.feed('<root><element>') 3980 self.assert_event_tags( 3981 events, [('start', 'root'), ('start', 'element')]) 3982 self.assertFalse(list(events)) 3983 parser.feed('</element><child>') 3984 self.assert_event_tags( 3985 events, [('end', 'element'), ('start', 'child')]) 3986 parser.feed('</child>') 3987 self.assert_event_tags( 3988 events, [('end', 'child')]) 3989 parser.feed('</root>') 3990 self.assert_event_tags( 3991 events, [('end', 'root')]) 3992 self.assertFalse(list(events)) 3993 root = parser.close() 3994 self.assertEqual('root', root.tag)
3995
3996 - def test_pull_from_tree_builder_subclass(self):
3997 class Target(etree.TreeBuilder): 3998 def end(self, tag): 3999 el = super(Target, self).end(tag) 4000 el.tag += '-huhu' 4001 return el
4002 4003 parser = self.etree.XMLPullParser( 4004 ['start', 'end'], target=Target()) 4005 events = parser.read_events() 4006 4007 parser.feed('<root><element>') 4008 self.assert_event_tags( 4009 events, [('start', 'root'), ('start', 'element')]) 4010 self.assertFalse(list(events)) 4011 parser.feed('</element><child>') 4012 self.assert_event_tags( 4013 events, [('end', 'element-huhu'), ('start', 'child')]) 4014 parser.feed('</child>') 4015 self.assert_event_tags( 4016 events, [('end', 'child-huhu')]) 4017 parser.feed('</root>') 4018 self.assert_event_tags( 4019 events, [('end', 'root-huhu')]) 4020 self.assertFalse(list(events)) 4021 root = parser.close() 4022 self.assertEqual('root-huhu', root.tag) 4023 4024
4025 -def test_suite():
4026 suite = unittest.TestSuite() 4027 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 4028 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 4029 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 4030 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 4031 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)]) 4032 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)]) 4033 suite.addTests([unittest.makeSuite(XMLPullParserTest)]) 4034 suite.addTests( 4035 [make_doctest('../../../doc/tutorial.txt')]) 4036 if sys.version_info >= (2,6): 4037 # now requires the 'with' statement 4038 suite.addTests( 4039 [make_doctest('../../../doc/api.txt')]) 4040 suite.addTests( 4041 [make_doctest('../../../doc/FAQ.txt')]) 4042 suite.addTests( 4043 [make_doctest('../../../doc/parsing.txt')]) 4044 suite.addTests( 4045 [make_doctest('../../../doc/resolvers.txt')]) 4046 return suite
4047 4048 if __name__ == '__main__': 4049 print('to test use test.py %s' % __file__) 4050