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