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_addnext_cycle(self):
1494 Element = self.etree.Element 1495 SubElement = self.etree.SubElement 1496 root = Element('root') 1497 a = SubElement(root, 'a') 1498 b = SubElement(a, 'b') 1499 # appending parent as sibling is forbidden 1500 self.assertRaises(ValueError, b.addnext, a) 1501 self.assertEqual(['a'], [c.tag for c in root]) 1502 self.assertEqual(['b'], [c.tag for c in a])
1503
1504 - def test_addprevious_cycle(self):
1505 Element = self.etree.Element 1506 SubElement = self.etree.SubElement 1507 root = Element('root') 1508 a = SubElement(root, 'a') 1509 b = SubElement(a, 'b') 1510 # appending parent as sibling is forbidden 1511 self.assertRaises(ValueError, b.addprevious, a) 1512 self.assertEqual(['a'], [c.tag for c in root]) 1513 self.assertEqual(['b'], [c.tag for c in a])
1514
1515 - def test_addnext_cycle_long(self):
1516 Element = self.etree.Element 1517 SubElement = self.etree.SubElement 1518 root = Element('root') 1519 a = SubElement(root, 'a') 1520 b = SubElement(a, 'b') 1521 c = SubElement(b, 'c') 1522 # appending parent as sibling is forbidden 1523 self.assertRaises(ValueError, c.addnext, a)
1524
1525 - def test_addprevious_cycle_long(self):
1526 Element = self.etree.Element 1527 SubElement = self.etree.SubElement 1528 root = Element('root') 1529 a = SubElement(root, 'a') 1530 b = SubElement(a, 'b') 1531 c = SubElement(b, 'c') 1532 # appending parent as sibling is forbidden 1533 self.assertRaises(ValueError, c.addprevious, a)
1534
1535 - def test_addprevious_noops(self):
1536 Element = self.etree.Element 1537 SubElement = self.etree.SubElement 1538 root = Element('root') 1539 a = SubElement(root, 'a') 1540 b = SubElement(root, 'b') 1541 a.addprevious(a) 1542 self.assertEqual('a', root[0].tag) 1543 self.assertEqual('b', root[1].tag) 1544 b.addprevious(b) 1545 self.assertEqual('a', root[0].tag) 1546 self.assertEqual('b', root[1].tag) 1547 b.addprevious(a) 1548 self.assertEqual('a', root[0].tag) 1549 self.assertEqual('b', root[1].tag)
1550
1551 - def test_addnext_noops(self):
1552 Element = self.etree.Element 1553 SubElement = self.etree.SubElement 1554 root = Element('root') 1555 a = SubElement(root, 'a') 1556 b = SubElement(root, 'b') 1557 a.addnext(a) 1558 self.assertEqual('a', root[0].tag) 1559 self.assertEqual('b', root[1].tag) 1560 b.addnext(b) 1561 self.assertEqual('a', root[0].tag) 1562 self.assertEqual('b', root[1].tag) 1563 a.addnext(b) 1564 self.assertEqual('a', root[0].tag) 1565 self.assertEqual('b', root[1].tag)
1566
1567 - def test_addnext_root(self):
1568 Element = self.etree.Element 1569 a = Element('a') 1570 b = Element('b') 1571 self.assertRaises(TypeError, a.addnext, b)
1572
1573 - def test_addprevious_pi(self):
1574 Element = self.etree.Element 1575 SubElement = self.etree.SubElement 1576 PI = self.etree.PI 1577 root = Element('root') 1578 SubElement(root, 'a') 1579 pi = PI('TARGET', 'TEXT') 1580 pi.tail = "TAIL" 1581 1582 self.assertEqual(_bytes('<root><a></a></root>'), 1583 self._writeElement(root)) 1584 root[0].addprevious(pi) 1585 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 1586 self._writeElement(root))
1587
1588 - def test_addprevious_root_pi(self):
1589 Element = self.etree.Element 1590 PI = self.etree.PI 1591 root = Element('root') 1592 pi = PI('TARGET', 'TEXT') 1593 pi.tail = "TAIL" 1594 1595 self.assertEqual(_bytes('<root></root>'), 1596 self._writeElement(root)) 1597 root.addprevious(pi) 1598 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'), 1599 self._writeElement(root))
1600
1601 - def test_addnext_pi(self):
1602 Element = self.etree.Element 1603 SubElement = self.etree.SubElement 1604 PI = self.etree.PI 1605 root = Element('root') 1606 SubElement(root, 'a') 1607 pi = PI('TARGET', 'TEXT') 1608 pi.tail = "TAIL" 1609 1610 self.assertEqual(_bytes('<root><a></a></root>'), 1611 self._writeElement(root)) 1612 root[0].addnext(pi) 1613 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 1614 self._writeElement(root))
1615
1616 - def test_addnext_root_pi(self):
1617 Element = self.etree.Element 1618 PI = self.etree.PI 1619 root = Element('root') 1620 pi = PI('TARGET', 'TEXT') 1621 pi.tail = "TAIL" 1622 1623 self.assertEqual(_bytes('<root></root>'), 1624 self._writeElement(root)) 1625 root.addnext(pi) 1626 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'), 1627 self._writeElement(root))
1628
1629 - def test_addnext_comment(self):
1630 Element = self.etree.Element 1631 SubElement = self.etree.SubElement 1632 Comment = self.etree.Comment 1633 root = Element('root') 1634 SubElement(root, 'a') 1635 comment = Comment('TEXT ') 1636 comment.tail = "TAIL" 1637 1638 self.assertEqual(_bytes('<root><a></a></root>'), 1639 self._writeElement(root)) 1640 root[0].addnext(comment) 1641 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 1642 self._writeElement(root))
1643
1644 - def test_addnext_root_comment(self):
1645 Element = self.etree.Element 1646 Comment = self.etree.Comment 1647 root = Element('root') 1648 comment = Comment('TEXT ') 1649 comment.tail = "TAIL" 1650 1651 self.assertEqual(_bytes('<root></root>'), 1652 self._writeElement(root)) 1653 root.addnext(comment) 1654 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'), 1655 self._writeElement(root))
1656
1657 - def test_addprevious_comment(self):
1658 Element = self.etree.Element 1659 SubElement = self.etree.SubElement 1660 Comment = self.etree.Comment 1661 root = Element('root') 1662 SubElement(root, 'a') 1663 comment = Comment('TEXT ') 1664 comment.tail = "TAIL" 1665 1666 self.assertEqual(_bytes('<root><a></a></root>'), 1667 self._writeElement(root)) 1668 root[0].addprevious(comment) 1669 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 1670 self._writeElement(root))
1671
1672 - def test_addprevious_root_comment(self):
1673 Element = self.etree.Element 1674 Comment = self.etree.Comment 1675 root = Element('root') 1676 comment = Comment('TEXT ') 1677 comment.tail = "TAIL" 1678 1679 self.assertEqual(_bytes('<root></root>'), 1680 self._writeElement(root)) 1681 root.addprevious(comment) 1682 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'), 1683 self._writeElement(root))
1684 1685 # ET's Elements have items() and key(), but not values()
1686 - def test_attribute_values(self):
1687 XML = self.etree.XML 1688 1689 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 1690 values = root.values() 1691 values.sort() 1692 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1693 1694 # gives error in ElementTree
1695 - def test_comment_empty(self):
1696 Element = self.etree.Element 1697 Comment = self.etree.Comment 1698 1699 a = Element('a') 1700 a.append(Comment()) 1701 self.assertEqual( 1702 _bytes('<a><!----></a>'), 1703 self._writeElement(a))
1704 1705 # ElementTree ignores comments
1706 - def test_comment_parse_empty(self):
1707 ElementTree = self.etree.ElementTree 1708 tostring = self.etree.tostring 1709 1710 xml = _bytes('<a><b/><!----><c/></a>') 1711 f = BytesIO(xml) 1712 doc = ElementTree(file=f) 1713 a = doc.getroot() 1714 self.assertEqual( 1715 '', 1716 a[1].text) 1717 self.assertEqual( 1718 xml, 1719 tostring(a))
1720 1721 # ElementTree ignores comments
1722 - def test_comment_no_proxy_yet(self):
1723 ElementTree = self.etree.ElementTree 1724 1725 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 1726 doc = ElementTree(file=f) 1727 a = doc.getroot() 1728 self.assertEqual( 1729 ' hoi ', 1730 a[1].text)
1731 1732 # does not raise an exception in ElementTree
1733 - def test_comment_immutable(self):
1734 Element = self.etree.Element 1735 Comment = self.etree.Comment 1736 1737 c = Comment() 1738 el = Element('myel') 1739 1740 self.assertRaises(TypeError, c.append, el) 1741 self.assertRaises(TypeError, c.insert, 0, el) 1742 self.assertRaises(TypeError, c.set, "myattr", "test")
1743
1744 - def test_comment_immutable_attrib(self):
1745 c = self.etree.Comment() 1746 self.assertEqual(0, len(c.attrib)) 1747 1748 self.assertFalse(c.attrib.__contains__('nope')) 1749 self.assertFalse('nope' in c.attrib) 1750 self.assertFalse('nope' in c.attrib.keys()) 1751 self.assertFalse('nope' in c.attrib.values()) 1752 self.assertFalse(('nope', 'huhu') in c.attrib.items()) 1753 1754 self.assertEqual([], list(c.attrib)) 1755 self.assertEqual([], list(c.attrib.keys())) 1756 self.assertEqual([], list(c.attrib.items())) 1757 self.assertEqual([], list(c.attrib.values())) 1758 self.assertEqual([], list(c.attrib.iterkeys())) 1759 self.assertEqual([], list(c.attrib.iteritems())) 1760 self.assertEqual([], list(c.attrib.itervalues())) 1761 1762 self.assertEqual('HUHU', c.attrib.pop('nope', 'HUHU')) 1763 self.assertRaises(KeyError, c.attrib.pop, 'nope') 1764 1765 self.assertRaises(KeyError, c.attrib.__getitem__, 'only') 1766 self.assertRaises(KeyError, c.attrib.__getitem__, 'names') 1767 self.assertRaises(KeyError, c.attrib.__getitem__, 'nope') 1768 self.assertRaises(KeyError, c.attrib.__setitem__, 'nope', 'yep') 1769 self.assertRaises(KeyError, c.attrib.__delitem__, 'nope')
1770 1771 # test passing 'None' to dump()
1772 - def test_dump_none(self):
1773 self.assertRaises(TypeError, self.etree.dump, None)
1774
1775 - def test_prefix(self):
1776 ElementTree = self.etree.ElementTree 1777 1778 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 1779 doc = ElementTree(file=f) 1780 a = doc.getroot() 1781 self.assertEqual( 1782 None, 1783 a.prefix) 1784 self.assertEqual( 1785 'foo', 1786 a[0].prefix)
1787
1788 - def test_prefix_default_ns(self):
1789 ElementTree = self.etree.ElementTree 1790 1791 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 1792 doc = ElementTree(file=f) 1793 a = doc.getroot() 1794 self.assertEqual( 1795 None, 1796 a.prefix) 1797 self.assertEqual( 1798 None, 1799 a[0].prefix)
1800
1801 - def test_getparent(self):
1802 Element = self.etree.Element 1803 SubElement = self.etree.SubElement 1804 1805 a = Element('a') 1806 b = SubElement(a, 'b') 1807 c = SubElement(a, 'c') 1808 d = SubElement(b, 'd') 1809 self.assertEqual( 1810 None, 1811 a.getparent()) 1812 self.assertEqual( 1813 a, 1814 b.getparent()) 1815 self.assertEqual( 1816 b.getparent(), 1817 c.getparent()) 1818 self.assertEqual( 1819 b, 1820 d.getparent())
1821
1822 - def test_iterchildren(self):
1823 XML = self.etree.XML 1824 1825 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1826 result = [] 1827 for el in root.iterchildren(): 1828 result.append(el.tag) 1829 self.assertEqual(['one', 'two', 'three'], result)
1830
1831 - def test_iterchildren_reversed(self):
1832 XML = self.etree.XML 1833 1834 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1835 result = [] 1836 for el in root.iterchildren(reversed=True): 1837 result.append(el.tag) 1838 self.assertEqual(['three', 'two', 'one'], result)
1839
1840 - def test_iterchildren_tag(self):
1841 XML = self.etree.XML 1842 1843 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1844 result = [] 1845 for el in root.iterchildren(tag='two'): 1846 result.append(el.text) 1847 self.assertEqual(['Two', 'Bla'], result)
1848
1849 - def test_iterchildren_tag_posarg(self):
1850 XML = self.etree.XML 1851 1852 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1853 result = [] 1854 for el in root.iterchildren('two'): 1855 result.append(el.text) 1856 self.assertEqual(['Two', 'Bla'], result)
1857
1858 - def test_iterchildren_tag_reversed(self):
1859 XML = self.etree.XML 1860 1861 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1862 result = [] 1863 for el in root.iterchildren(reversed=True, tag='two'): 1864 result.append(el.text) 1865 self.assertEqual(['Bla', 'Two'], result)
1866
1867 - def test_iterchildren_tag_multiple(self):
1868 XML = self.etree.XML 1869 1870 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1871 result = [] 1872 for el in root.iterchildren(tag=['two', 'three']): 1873 result.append(el.text) 1874 self.assertEqual(['Two', 'Bla', None], result)
1875
1876 - def test_iterchildren_tag_multiple_posarg(self):
1877 XML = self.etree.XML 1878 1879 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1880 result = [] 1881 for el in root.iterchildren('two', 'three'): 1882 result.append(el.text) 1883 self.assertEqual(['Two', 'Bla', None], result)
1884
1885 - def test_iterchildren_tag_multiple_reversed(self):
1886 XML = self.etree.XML 1887 1888 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1889 result = [] 1890 for el in root.iterchildren(reversed=True, tag=['two', 'three']): 1891 result.append(el.text) 1892 self.assertEqual([None, 'Bla', 'Two'], result)
1893
1894 - def test_iterancestors(self):
1895 Element = self.etree.Element 1896 SubElement = self.etree.SubElement 1897 1898 a = Element('a') 1899 b = SubElement(a, 'b') 1900 c = SubElement(a, 'c') 1901 d = SubElement(b, 'd') 1902 self.assertEqual( 1903 [], 1904 list(a.iterancestors())) 1905 self.assertEqual( 1906 [a], 1907 list(b.iterancestors())) 1908 self.assertEqual( 1909 [a], 1910 list(c.iterancestors())) 1911 self.assertEqual( 1912 [b, a], 1913 list(d.iterancestors()))
1914
1915 - def test_iterancestors_tag(self):
1916 Element = self.etree.Element 1917 SubElement = self.etree.SubElement 1918 1919 a = Element('a') 1920 b = SubElement(a, 'b') 1921 c = SubElement(a, 'c') 1922 d = SubElement(b, 'd') 1923 self.assertEqual( 1924 [a], 1925 list(d.iterancestors('a'))) 1926 self.assertEqual( 1927 [a], 1928 list(d.iterancestors(tag='a'))) 1929 1930 self.assertEqual( 1931 [b, a], 1932 list(d.iterancestors('*'))) 1933 self.assertEqual( 1934 [b, a], 1935 list(d.iterancestors(tag='*')))
1936
1937 - def test_iterancestors_tag_multiple(self):
1938 Element = self.etree.Element 1939 SubElement = self.etree.SubElement 1940 1941 a = Element('a') 1942 b = SubElement(a, 'b') 1943 c = SubElement(a, 'c') 1944 d = SubElement(b, 'd') 1945 self.assertEqual( 1946 [b, a], 1947 list(d.iterancestors(tag=('a', 'b')))) 1948 self.assertEqual( 1949 [b, a], 1950 list(d.iterancestors('a', 'b'))) 1951 1952 self.assertEqual( 1953 [], 1954 list(d.iterancestors(tag=('w', 'x', 'y', 'z')))) 1955 self.assertEqual( 1956 [], 1957 list(d.iterancestors('w', 'x', 'y', 'z'))) 1958 1959 self.assertEqual( 1960 [], 1961 list(d.iterancestors(tag=('d', 'x')))) 1962 self.assertEqual( 1963 [], 1964 list(d.iterancestors('d', 'x'))) 1965 1966 self.assertEqual( 1967 [b, a], 1968 list(d.iterancestors(tag=('b', '*')))) 1969 self.assertEqual( 1970 [b, a], 1971 list(d.iterancestors('b', '*'))) 1972 1973 self.assertEqual( 1974 [b], 1975 list(d.iterancestors(tag=('b', 'c')))) 1976 self.assertEqual( 1977 [b], 1978 list(d.iterancestors('b', 'c')))
1979
1980 - def test_iterdescendants(self):
1981 Element = self.etree.Element 1982 SubElement = self.etree.SubElement 1983 1984 a = Element('a') 1985 b = SubElement(a, 'b') 1986 c = SubElement(a, 'c') 1987 d = SubElement(b, 'd') 1988 e = SubElement(c, 'e') 1989 1990 self.assertEqual( 1991 [b, d, c, e], 1992 list(a.iterdescendants())) 1993 self.assertEqual( 1994 [], 1995 list(d.iterdescendants()))
1996
1997 - def test_iterdescendants_tag(self):
1998 Element = self.etree.Element 1999 SubElement = self.etree.SubElement 2000 2001 a = Element('a') 2002 b = SubElement(a, 'b') 2003 c = SubElement(a, 'c') 2004 d = SubElement(b, 'd') 2005 e = SubElement(c, 'e') 2006 2007 self.assertEqual( 2008 [], 2009 list(a.iterdescendants('a'))) 2010 self.assertEqual( 2011 [], 2012 list(a.iterdescendants(tag='a'))) 2013 2014 a2 = SubElement(e, 'a') 2015 self.assertEqual( 2016 [a2], 2017 list(a.iterdescendants('a'))) 2018 2019 self.assertEqual( 2020 [a2], 2021 list(c.iterdescendants('a'))) 2022 self.assertEqual( 2023 [a2], 2024 list(c.iterdescendants(tag='a')))
2025
2026 - def test_iterdescendants_tag_multiple(self):
2027 Element = self.etree.Element 2028 SubElement = self.etree.SubElement 2029 2030 a = Element('a') 2031 b = SubElement(a, 'b') 2032 c = SubElement(a, 'c') 2033 d = SubElement(b, 'd') 2034 e = SubElement(c, 'e') 2035 2036 self.assertEqual( 2037 [b, e], 2038 list(a.iterdescendants(tag=('a', 'b', 'e')))) 2039 self.assertEqual( 2040 [b, e], 2041 list(a.iterdescendants('a', 'b', 'e'))) 2042 2043 a2 = SubElement(e, 'a') 2044 self.assertEqual( 2045 [b, a2], 2046 list(a.iterdescendants(tag=('a', 'b')))) 2047 self.assertEqual( 2048 [b, a2], 2049 list(a.iterdescendants('a', 'b'))) 2050 2051 self.assertEqual( 2052 [], 2053 list(c.iterdescendants(tag=('x', 'y', 'z')))) 2054 self.assertEqual( 2055 [], 2056 list(c.iterdescendants('x', 'y', 'z'))) 2057 2058 self.assertEqual( 2059 [b, d, c, e, a2], 2060 list(a.iterdescendants(tag=('x', 'y', 'z', '*')))) 2061 self.assertEqual( 2062 [b, d, c, e, a2], 2063 list(a.iterdescendants('x', 'y', 'z', '*')))
2064
2065 - def test_getroottree(self):
2066 Element = self.etree.Element 2067 SubElement = self.etree.SubElement 2068 2069 a = Element('a') 2070 b = SubElement(a, 'b') 2071 c = SubElement(a, 'c') 2072 d = SubElement(b, 'd') 2073 self.assertEqual( 2074 a, 2075 a.getroottree().getroot()) 2076 self.assertEqual( 2077 a, 2078 b.getroottree().getroot()) 2079 self.assertEqual( 2080 a, 2081 d.getroottree().getroot())
2082
2083 - def test_getnext(self):
2084 Element = self.etree.Element 2085 SubElement = self.etree.SubElement 2086 2087 a = Element('a') 2088 b = SubElement(a, 'b') 2089 c = SubElement(a, 'c') 2090 self.assertEqual( 2091 None, 2092 a.getnext()) 2093 self.assertEqual( 2094 c, 2095 b.getnext()) 2096 self.assertEqual( 2097 None, 2098 c.getnext())
2099
2100 - def test_getprevious(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 None, 2110 a.getprevious()) 2111 self.assertEqual( 2112 b, 2113 c.getprevious()) 2114 self.assertEqual( 2115 None, 2116 b.getprevious())
2117
2118 - def test_itersiblings(self):
2119 Element = self.etree.Element 2120 SubElement = self.etree.SubElement 2121 2122 a = Element('a') 2123 b = SubElement(a, 'b') 2124 c = SubElement(a, 'c') 2125 d = SubElement(b, 'd') 2126 self.assertEqual( 2127 [], 2128 list(a.itersiblings())) 2129 self.assertEqual( 2130 [c], 2131 list(b.itersiblings())) 2132 self.assertEqual( 2133 [], 2134 list(c.itersiblings())) 2135 self.assertEqual( 2136 [b], 2137 list(c.itersiblings(preceding=True))) 2138 self.assertEqual( 2139 [], 2140 list(b.itersiblings(preceding=True)))
2141
2142 - def test_itersiblings_tag(self):
2143 Element = self.etree.Element 2144 SubElement = self.etree.SubElement 2145 2146 a = Element('a') 2147 b = SubElement(a, 'b') 2148 c = SubElement(a, 'c') 2149 d = SubElement(b, 'd') 2150 self.assertEqual( 2151 [], 2152 list(a.itersiblings(tag='XXX'))) 2153 self.assertEqual( 2154 [c], 2155 list(b.itersiblings(tag='c'))) 2156 self.assertEqual( 2157 [c], 2158 list(b.itersiblings(tag='*'))) 2159 self.assertEqual( 2160 [b], 2161 list(c.itersiblings(preceding=True, tag='b'))) 2162 self.assertEqual( 2163 [], 2164 list(c.itersiblings(preceding=True, tag='c')))
2165
2166 - def test_itersiblings_tag_multiple(self):
2167 Element = self.etree.Element 2168 SubElement = self.etree.SubElement 2169 2170 a = Element('a') 2171 b = SubElement(a, 'b') 2172 c = SubElement(a, 'c') 2173 d = SubElement(b, 'd') 2174 e = SubElement(a, 'e') 2175 self.assertEqual( 2176 [], 2177 list(a.itersiblings(tag=('XXX', 'YYY')))) 2178 self.assertEqual( 2179 [c, e], 2180 list(b.itersiblings(tag=('c', 'd', 'e')))) 2181 self.assertEqual( 2182 [b], 2183 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd')))) 2184 self.assertEqual( 2185 [c, b], 2186 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2187
2188 - def test_parseid(self):
2189 parseid = self.etree.parseid 2190 XML = self.etree.XML 2191 xml_text = _bytes(''' 2192 <!DOCTYPE document [ 2193 <!ELEMENT document (h1,p)*> 2194 <!ELEMENT h1 (#PCDATA)> 2195 <!ATTLIST h1 myid ID #REQUIRED> 2196 <!ELEMENT p (#PCDATA)> 2197 <!ATTLIST p someid ID #REQUIRED> 2198 ]> 2199 <document> 2200 <h1 myid="chapter1">...</h1> 2201 <p id="note1" class="note">...</p> 2202 <p>Regular paragraph.</p> 2203 <p xml:id="xmlid">XML:ID paragraph.</p> 2204 <p someid="warn1" class="warning">...</p> 2205 </document> 2206 ''') 2207 2208 tree, dic = parseid(BytesIO(xml_text)) 2209 root = tree.getroot() 2210 root2 = XML(xml_text) 2211 self.assertEqual(self._writeElement(root), 2212 self._writeElement(root2)) 2213 expected = { 2214 "chapter1" : root[0], 2215 "xmlid" : root[3], 2216 "warn1" : root[4] 2217 } 2218 self.assertTrue("chapter1" in dic) 2219 self.assertTrue("warn1" in dic) 2220 self.assertTrue("xmlid" in dic) 2221 self._checkIDDict(dic, expected)
2222
2223 - def test_XMLDTDID(self):
2224 XMLDTDID = self.etree.XMLDTDID 2225 XML = self.etree.XML 2226 xml_text = _bytes(''' 2227 <!DOCTYPE document [ 2228 <!ELEMENT document (h1,p)*> 2229 <!ELEMENT h1 (#PCDATA)> 2230 <!ATTLIST h1 myid ID #REQUIRED> 2231 <!ELEMENT p (#PCDATA)> 2232 <!ATTLIST p someid ID #REQUIRED> 2233 ]> 2234 <document> 2235 <h1 myid="chapter1">...</h1> 2236 <p id="note1" class="note">...</p> 2237 <p>Regular paragraph.</p> 2238 <p xml:id="xmlid">XML:ID paragraph.</p> 2239 <p someid="warn1" class="warning">...</p> 2240 </document> 2241 ''') 2242 2243 root, dic = XMLDTDID(xml_text) 2244 root2 = XML(xml_text) 2245 self.assertEqual(self._writeElement(root), 2246 self._writeElement(root2)) 2247 expected = { 2248 "chapter1" : root[0], 2249 "xmlid" : root[3], 2250 "warn1" : root[4] 2251 } 2252 self.assertTrue("chapter1" in dic) 2253 self.assertTrue("warn1" in dic) 2254 self.assertTrue("xmlid" in dic) 2255 self._checkIDDict(dic, expected)
2256
2257 - def test_XMLDTDID_empty(self):
2258 XMLDTDID = self.etree.XMLDTDID 2259 XML = self.etree.XML 2260 xml_text = _bytes(''' 2261 <document> 2262 <h1 myid="chapter1">...</h1> 2263 <p id="note1" class="note">...</p> 2264 <p>Regular paragraph.</p> 2265 <p someid="warn1" class="warning">...</p> 2266 </document> 2267 ''') 2268 2269 root, dic = XMLDTDID(xml_text) 2270 root2 = XML(xml_text) 2271 self.assertEqual(self._writeElement(root), 2272 self._writeElement(root2)) 2273 expected = {} 2274 self._checkIDDict(dic, expected)
2275
2276 - def _checkIDDict(self, dic, expected):
2277 self.assertEqual(len(dic), 2278 len(expected)) 2279 self.assertEqual(sorted(dic.items()), 2280 sorted(expected.items())) 2281 if sys.version_info < (3,): 2282 self.assertEqual(sorted(dic.iteritems()), 2283 sorted(expected.iteritems())) 2284 self.assertEqual(sorted(dic.keys()), 2285 sorted(expected.keys())) 2286 if sys.version_info < (3,): 2287 self.assertEqual(sorted(dic.iterkeys()), 2288 sorted(expected.iterkeys())) 2289 if sys.version_info < (3,): 2290 self.assertEqual(sorted(dic.values()), 2291 sorted(expected.values())) 2292 self.assertEqual(sorted(dic.itervalues()), 2293 sorted(expected.itervalues()))
2294
2295 - def test_namespaces(self):
2296 etree = self.etree 2297 2298 r = {'foo': 'http://ns.infrae.com/foo'} 2299 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2300 self.assertEqual( 2301 'foo', 2302 e.prefix) 2303 self.assertEqual( 2304 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 2305 self._writeElement(e))
2306
2307 - def test_namespaces_default(self):
2308 etree = self.etree 2309 2310 r = {None: 'http://ns.infrae.com/foo'} 2311 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2312 self.assertEqual( 2313 None, 2314 e.prefix) 2315 self.assertEqual( 2316 '{http://ns.infrae.com/foo}bar', 2317 e.tag) 2318 self.assertEqual( 2319 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 2320 self._writeElement(e))
2321
2322 - def test_namespaces_default_and_attr(self):
2323 etree = self.etree 2324 2325 r = {None: 'http://ns.infrae.com/foo', 2326 'hoi': 'http://ns.infrae.com/hoi'} 2327 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2328 e.set('{http://ns.infrae.com/hoi}test', 'value') 2329 self.assertEqual( 2330 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 2331 self._writeElement(e))
2332
2333 - def test_attribute_keeps_namespace_prefix_on_merge(self):
2334 etree = self.etree 2335 2336 root = etree.Element('{http://test/ns}root', 2337 nsmap={None: 'http://test/ns'}) 2338 sub = etree.Element('{http://test/ns}sub', 2339 nsmap={'test': 'http://test/ns'}) 2340 2341 sub.attrib['{http://test/ns}attr'] = 'value' 2342 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2343 self.assertEqual( 2344 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 2345 etree.tostring(sub)) 2346 2347 root.append(sub) 2348 self.assertEqual( 2349 _bytes('<root xmlns="http://test/ns">' 2350 '<sub xmlns:test="http://test/ns" test:attr="value"/>' 2351 '</root>'), 2352 etree.tostring(root))
2353
2354 - def test_attribute_keeps_namespace_prefix_on_merge_with_nons(self):
2355 etree = self.etree 2356 2357 root = etree.Element('root') 2358 sub = etree.Element('{http://test/ns}sub', 2359 nsmap={'test': 'http://test/ns'}) 2360 2361 sub.attrib['{http://test/ns}attr'] = 'value' 2362 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2363 self.assertEqual( 2364 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 2365 etree.tostring(sub)) 2366 2367 root.append(sub) 2368 self.assertEqual( 2369 _bytes('<root>' 2370 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>' 2371 '</root>'), 2372 etree.tostring(root))
2373
2374 - def test_attribute_gets_namespace_prefix_on_merge_with_nons(self):
2375 etree = self.etree 2376 2377 root = etree.Element('root') 2378 sub = etree.Element('{http://test/ns}sub', 2379 nsmap={None: 'http://test/ns'}) 2380 2381 sub.attrib['{http://test/ns}attr'] = 'value' 2382 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2383 self.assertEqual( 2384 _bytes('<sub xmlns="http://test/ns" ' 2385 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 2386 etree.tostring(sub)) 2387 2388 root.append(sub) 2389 self.assertEqual( 2390 _bytes('<root>' 2391 '<sub xmlns="http://test/ns"' 2392 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>' 2393 '</root>'), 2394 etree.tostring(root))
2395
2396 - def test_attribute_gets_namespace_prefix_on_merge(self):
2397 etree = self.etree 2398 2399 root = etree.Element('{http://test/ns}root', 2400 nsmap={'test': 'http://test/ns', 2401 None: 'http://test/ns'}) 2402 sub = etree.Element('{http://test/ns}sub', 2403 nsmap={None: 'http://test/ns'}) 2404 2405 sub.attrib['{http://test/ns}attr'] = 'value' 2406 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2407 self.assertEqual( 2408 _bytes('<sub xmlns="http://test/ns" ' 2409 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 2410 etree.tostring(sub)) 2411 2412 root.append(sub) 2413 self.assertEqual( 2414 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">' 2415 '<test:sub test:attr="value"/>' 2416 '</test:root>'), 2417 etree.tostring(root))
2418
2419 - def test_namespaces_elementtree(self):
2420 etree = self.etree 2421 r = {None: 'http://ns.infrae.com/foo', 2422 'hoi': 'http://ns.infrae.com/hoi'} 2423 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 2424 tree = etree.ElementTree(element=e) 2425 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 2426 self.assertEqual( 2427 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 2428 self._writeElement(e))
2429
2430 - def test_namespaces_default_copy_element(self):
2431 etree = self.etree 2432 2433 r = {None: 'http://ns.infrae.com/foo'} 2434 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2435 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2436 2437 e1.append(e2) 2438 2439 self.assertEqual( 2440 None, 2441 e1.prefix) 2442 self.assertEqual( 2443 None, 2444 e1[0].prefix) 2445 self.assertEqual( 2446 '{http://ns.infrae.com/foo}bar', 2447 e1.tag) 2448 self.assertEqual( 2449 '{http://ns.infrae.com/foo}bar', 2450 e1[0].tag)
2451
2452 - def test_namespaces_copy_element(self):
2453 etree = self.etree 2454 2455 r = {None: 'http://ns.infrae.com/BAR'} 2456 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 2457 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2458 2459 e1.append(e2) 2460 2461 self.assertEqual( 2462 None, 2463 e1.prefix) 2464 self.assertNotEqual( 2465 None, 2466 e2.prefix) 2467 self.assertEqual( 2468 '{http://ns.infrae.com/BAR}bar', 2469 e1.tag) 2470 self.assertEqual( 2471 '{http://ns.infrae.com/foo}bar', 2472 e2.tag)
2473
2474 - def test_namespaces_reuse_after_move(self):
2475 ns_href = "http://a.b.c" 2476 one = self.etree.fromstring( 2477 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 2478 baz = one[0][0] 2479 2480 two = self.etree.fromstring( 2481 _bytes('<root xmlns:ns="%s"/>' % ns_href)) 2482 two.append(baz) 2483 del one # make sure the source document is deallocated 2484 2485 self.assertEqual('{%s}baz' % ns_href, baz.tag) 2486 self.assertEqual( 2487 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 2488 self.etree.tostring(two))
2489
2490 - def test_namespace_cleanup(self):
2491 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>') 2492 root = self.etree.fromstring(xml) 2493 self.assertEqual(xml, 2494 self.etree.tostring(root)) 2495 self.etree.cleanup_namespaces(root) 2496 self.assertEqual( 2497 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 2498 self.etree.tostring(root))
2499
2500 - def test_element_nsmap(self):
2501 etree = self.etree 2502 2503 r = {None: 'http://ns.infrae.com/foo', 2504 'hoi': 'http://ns.infrae.com/hoi'} 2505 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2506 self.assertEqual( 2507 r, 2508 e.nsmap)
2509
2510 - def test_subelement_nsmap(self):
2511 etree = self.etree 2512 2513 re = {None: 'http://ns.infrae.com/foo', 2514 'hoi': 'http://ns.infrae.com/hoi'} 2515 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 2516 2517 rs = {None: 'http://ns.infrae.com/honk', 2518 'top': 'http://ns.infrae.com/top'} 2519 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 2520 2521 r = re.copy() 2522 r.update(rs) 2523 self.assertEqual(re, e.nsmap) 2524 self.assertEqual(r, s.nsmap)
2525
2526 - def test_html_prefix_nsmap(self):
2527 etree = self.etree 2528 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description') 2529 self.assertEqual({'hha': None}, el.nsmap)
2530
2531 - def test_getiterator_filter_multiple(self):
2532 Element = self.etree.Element 2533 SubElement = self.etree.SubElement 2534 2535 a = Element('a') 2536 b = SubElement(a, 'b') 2537 c = SubElement(a, 'c') 2538 d = SubElement(b, 'd') 2539 e = SubElement(c, 'e') 2540 f = SubElement(c, 'f') 2541 2542 self.assertEqual( 2543 [a, b], 2544 list(a.getiterator('a', 'b'))) 2545 self.assertEqual( 2546 [], 2547 list(a.getiterator('x', 'y'))) 2548 self.assertEqual( 2549 [a, f], 2550 list(a.getiterator('f', 'a'))) 2551 self.assertEqual( 2552 [c, e, f], 2553 list(c.getiterator('c', '*', 'a'))) 2554 self.assertEqual( 2555 [], 2556 list(a.getiterator( (), () )))
2557
2558 - def test_getiterator_filter_multiple_tuple(self):
2559 Element = self.etree.Element 2560 SubElement = self.etree.SubElement 2561 2562 a = Element('a') 2563 b = SubElement(a, 'b') 2564 c = SubElement(a, 'c') 2565 d = SubElement(b, 'd') 2566 e = SubElement(c, 'e') 2567 f = SubElement(c, 'f') 2568 2569 self.assertEqual( 2570 [a, b], 2571 list(a.getiterator( ('a', 'b') ))) 2572 self.assertEqual( 2573 [], 2574 list(a.getiterator( ('x', 'y') ))) 2575 self.assertEqual( 2576 [a, f], 2577 list(a.getiterator( ('f', 'a') ))) 2578 self.assertEqual( 2579 [c, e, f], 2580 list(c.getiterator( ('c', '*', 'a') ))) 2581 self.assertEqual( 2582 [], 2583 list(a.getiterator( () )))
2584
2585 - def test_getiterator_filter_namespace(self):
2586 Element = self.etree.Element 2587 SubElement = self.etree.SubElement 2588 2589 a = Element('{a}a') 2590 b = SubElement(a, '{a}b') 2591 c = SubElement(a, '{a}c') 2592 d = SubElement(b, '{b}d') 2593 e = SubElement(c, '{a}e') 2594 f = SubElement(c, '{b}f') 2595 g = SubElement(c, 'g') 2596 2597 self.assertEqual( 2598 [a], 2599 list(a.getiterator('{a}a'))) 2600 self.assertEqual( 2601 [], 2602 list(a.getiterator('{b}a'))) 2603 self.assertEqual( 2604 [], 2605 list(a.getiterator('a'))) 2606 self.assertEqual( 2607 [a,b,d,c,e,f,g], 2608 list(a.getiterator('*'))) 2609 self.assertEqual( 2610 [f], 2611 list(c.getiterator('{b}*'))) 2612 self.assertEqual( 2613 [d, f], 2614 list(a.getiterator('{b}*'))) 2615 self.assertEqual( 2616 [g], 2617 list(a.getiterator('g'))) 2618 self.assertEqual( 2619 [g], 2620 list(a.getiterator('{}g'))) 2621 self.assertEqual( 2622 [g], 2623 list(a.getiterator('{}*')))
2624
2625 - def test_getiterator_filter_local_name(self):
2626 Element = self.etree.Element 2627 SubElement = self.etree.SubElement 2628 2629 a = Element('{a}a') 2630 b = SubElement(a, '{nsA}b') 2631 c = SubElement(b, '{nsB}b') 2632 d = SubElement(a, 'b') 2633 e = SubElement(a, '{nsA}e') 2634 f = SubElement(e, '{nsB}e') 2635 g = SubElement(e, 'e') 2636 2637 self.assertEqual( 2638 [b, c, d], 2639 list(a.getiterator('{*}b'))) 2640 self.assertEqual( 2641 [e, f, g], 2642 list(a.getiterator('{*}e'))) 2643 self.assertEqual( 2644 [a, b, c, d, e, f, g], 2645 list(a.getiterator('{*}*')))
2646
2647 - def test_getiterator_filter_entities(self):
2648 Element = self.etree.Element 2649 Entity = self.etree.Entity 2650 SubElement = self.etree.SubElement 2651 2652 a = Element('a') 2653 b = SubElement(a, 'b') 2654 entity_b = Entity("TEST-b") 2655 b.append(entity_b) 2656 2657 self.assertEqual( 2658 [entity_b], 2659 list(a.getiterator(Entity))) 2660 2661 entity_a = Entity("TEST-a") 2662 a.append(entity_a) 2663 2664 self.assertEqual( 2665 [entity_b, entity_a], 2666 list(a.getiterator(Entity))) 2667 2668 self.assertEqual( 2669 [entity_b], 2670 list(b.getiterator(Entity)))
2671
2672 - def test_getiterator_filter_element(self):
2673 Element = self.etree.Element 2674 Comment = self.etree.Comment 2675 PI = self.etree.PI 2676 SubElement = self.etree.SubElement 2677 2678 a = Element('a') 2679 b = SubElement(a, 'b') 2680 a.append(Comment("test")) 2681 a.append(PI("pi", "content")) 2682 c = SubElement(a, 'c') 2683 2684 self.assertEqual( 2685 [a, b, c], 2686 list(a.getiterator(Element)))
2687
2688 - def test_getiterator_filter_all_comment_pi(self):
2689 # ElementTree iterates over everything here 2690 Element = self.etree.Element 2691 Comment = self.etree.Comment 2692 PI = self.etree.PI 2693 SubElement = self.etree.SubElement 2694 2695 a = Element('a') 2696 b = SubElement(a, 'b') 2697 a.append(Comment("test")) 2698 a.append(PI("pi", "content")) 2699 c = SubElement(a, 'c') 2700 2701 self.assertEqual( 2702 [a, b, c], 2703 list(a.getiterator('*')))
2704
2705 - def test_elementtree_find_qname(self):
2706 XML = self.etree.XML 2707 ElementTree = self.etree.ElementTree 2708 QName = self.etree.QName 2709 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 2710 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
2711
2712 - def test_elementtree_findall_qname(self):
2713 XML = self.etree.XML 2714 ElementTree = self.etree.ElementTree 2715 QName = self.etree.QName 2716 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 2717 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
2718
2719 - def test_elementtree_findall_ns_qname(self):
2720 XML = self.etree.XML 2721 ElementTree = self.etree.ElementTree 2722 QName = self.etree.QName 2723 tree = ElementTree(XML( 2724 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))) 2725 self.assertEqual(len(list(tree.findall(QName("b")))), 2) 2726 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
2727
2728 - def test_findall_ns(self):
2729 XML = self.etree.XML 2730 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')) 2731 self.assertEqual(len(root.findall(".//{X}b")), 2) 2732 self.assertEqual(len(root.findall(".//{X}*")), 2) 2733 self.assertEqual(len(root.findall(".//b")), 3)
2734
2735 - def test_findall_different_nsmaps(self):
2736 XML = self.etree.XML 2737 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 2738 nsmap = {'xx': 'X'} 2739 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 2740 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2) 2741 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 2742 nsmap = {'xx': 'Y'} 2743 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) 2744 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1) 2745 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2746
2747 - def test_findall_different_nsmaps(self):
2748 XML = self.etree.XML 2749 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 2750 nsmap = {'xx': 'X'} 2751 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 2752 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2) 2753 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 2754 nsmap = {'xx': 'Y'} 2755 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) 2756 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1) 2757 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2758
2759 - def test_findall_syntax_error(self):
2760 XML = self.etree.XML 2761 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>')) 2762 self.assertRaises(SyntaxError, root.findall, '') 2763 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element 2764 self.assertRaises(SyntaxError, root.findall, './//')
2765
2766 - def test_index(self):
2767 etree = self.etree 2768 e = etree.Element('foo') 2769 for i in range(10): 2770 etree.SubElement(e, 'a%s' % i) 2771 for i in range(10): 2772 self.assertEqual( 2773 i, 2774 e.index(e[i])) 2775 self.assertEqual( 2776 3, e.index(e[3], 3)) 2777 self.assertRaises( 2778 ValueError, e.index, e[3], 4) 2779 self.assertRaises( 2780 ValueError, e.index, e[3], 0, 2) 2781 self.assertRaises( 2782 ValueError, e.index, e[8], 0, -3) 2783 self.assertRaises( 2784 ValueError, e.index, e[8], -5, -3) 2785 self.assertEqual( 2786 8, e.index(e[8], 0, -1)) 2787 self.assertEqual( 2788 8, e.index(e[8], -12, -1)) 2789 self.assertEqual( 2790 0, e.index(e[0], -12, -1))
2791
2792 - def test_replace(self):
2793 etree = self.etree 2794 e = etree.Element('foo') 2795 for i in range(10): 2796 el = etree.SubElement(e, 'a%s' % i) 2797 el.text = "text%d" % i 2798 el.tail = "tail%d" % i 2799 2800 child0 = e[0] 2801 child1 = e[1] 2802 child2 = e[2] 2803 2804 e.replace(e[0], e[1]) 2805 self.assertEqual( 2806 9, len(e)) 2807 self.assertEqual( 2808 child1, e[0]) 2809 self.assertEqual( 2810 child1.text, "text1") 2811 self.assertEqual( 2812 child1.tail, "tail1") 2813 self.assertEqual( 2814 child0.tail, "tail0") 2815 self.assertEqual( 2816 child2, e[1]) 2817 2818 e.replace(e[-1], e[0]) 2819 self.assertEqual( 2820 child1, e[-1]) 2821 self.assertEqual( 2822 child1.text, "text1") 2823 self.assertEqual( 2824 child1.tail, "tail1") 2825 self.assertEqual( 2826 child2, e[0])
2827
2828 - def test_replace_new(self):
2829 etree = self.etree 2830 e = etree.Element('foo') 2831 for i in range(10): 2832 etree.SubElement(e, 'a%s' % i) 2833 2834 new_element = etree.Element("test") 2835 new_element.text = "TESTTEXT" 2836 new_element.tail = "TESTTAIL" 2837 child1 = e[1] 2838 e.replace(e[0], new_element) 2839 self.assertEqual( 2840 new_element, e[0]) 2841 self.assertEqual( 2842 "TESTTEXT", 2843 e[0].text) 2844 self.assertEqual( 2845 "TESTTAIL", 2846 e[0].tail) 2847 self.assertEqual( 2848 child1, e[1])
2849
2850 - def test_setslice_all_empty_reversed(self):
2851 Element = self.etree.Element 2852 SubElement = self.etree.SubElement 2853 2854 a = Element('a') 2855 2856 e = Element('e') 2857 f = Element('f') 2858 g = Element('g') 2859 2860 s = [e, f, g] 2861 a[::-1] = s 2862 self.assertEqual( 2863 [g, f, e], 2864 list(a))
2865
2866 - def test_setslice_step(self):
2867 Element = self.etree.Element 2868 SubElement = self.etree.SubElement 2869 2870 a = Element('a') 2871 b = SubElement(a, 'b') 2872 c = SubElement(a, 'c') 2873 d = SubElement(a, 'd') 2874 e = SubElement(a, 'e') 2875 2876 x = Element('x') 2877 y = Element('y') 2878 2879 a[1::2] = [x, y] 2880 self.assertEqual( 2881 [b, x, d, y], 2882 list(a))
2883
2884 - def test_setslice_step_negative(self):
2885 Element = self.etree.Element 2886 SubElement = self.etree.SubElement 2887 2888 a = Element('a') 2889 b = SubElement(a, 'b') 2890 c = SubElement(a, 'c') 2891 d = SubElement(a, 'd') 2892 e = SubElement(a, 'e') 2893 2894 x = Element('x') 2895 y = Element('y') 2896 2897 a[1::-1] = [x, y] 2898 self.assertEqual( 2899 [y, x, d, e], 2900 list(a))
2901
2902 - def test_setslice_step_negative2(self):
2903 Element = self.etree.Element 2904 SubElement = self.etree.SubElement 2905 2906 a = Element('a') 2907 b = SubElement(a, 'b') 2908 c = SubElement(a, 'c') 2909 d = SubElement(a, 'd') 2910 e = SubElement(a, 'e') 2911 2912 x = Element('x') 2913 y = Element('y') 2914 2915 a[::-2] = [x, y] 2916 self.assertEqual( 2917 [b, y, d, x], 2918 list(a))
2919
2920 - def test_setslice_step_overrun(self):
2921 Element = self.etree.Element 2922 SubElement = self.etree.SubElement 2923 try: 2924 slice 2925 except NameError: 2926 print("slice() not found") 2927 return 2928 2929 a = Element('a') 2930 b = SubElement(a, 'b') 2931 c = SubElement(a, 'c') 2932 d = SubElement(a, 'd') 2933 e = SubElement(a, 'e') 2934 2935 x = Element('x') 2936 y = Element('y') 2937 z = Element('z') 2938 2939 self.assertRaises( 2940 ValueError, 2941 operator.setitem, a, slice(1,None,2), [x, y, z]) 2942 2943 self.assertEqual( 2944 [b, c, d, e], 2945 list(a))
2946
2947 - def test_sourceline_XML(self):
2948 XML = self.etree.XML 2949 root = XML(_bytes('''<?xml version="1.0"?> 2950 <root><test> 2951 2952 <bla/></test> 2953 </root> 2954 ''')) 2955 2956 self.assertEqual( 2957 [2, 2, 4], 2958 [ el.sourceline for el in root.getiterator() ])
2959
2960 - def test_large_sourceline_XML(self):
2961 XML = self.etree.XML 2962 root = XML(_bytes( 2963 '<?xml version="1.0"?>\n' 2964 '<root>' + '\n' * 65536 + 2965 '<p>' + '\n' * 65536 + '</p>\n' + 2966 '<br/>\n' 2967 '</root>')) 2968 2969 if self.etree.LIBXML_VERSION >= (2, 9): 2970 expected = [2, 131074, 131076] 2971 else: 2972 expected = [2, 65535, 65535] 2973 2974 self.assertEqual(expected, [el.sourceline for el in root.iter()])
2975
2976 - def test_sourceline_parse(self):
2977 parse = self.etree.parse 2978 tree = parse(fileInTestDir('include/test_xinclude.xml')) 2979 2980 self.assertEqual( 2981 [1, 2, 3], 2982 [ el.sourceline for el in tree.getiterator() ])
2983
2984 - def test_sourceline_iterparse_end(self):
2985 iterparse = self.etree.iterparse 2986 lines = [ el.sourceline for (event, el) in 2987 iterparse(fileInTestDir('include/test_xinclude.xml')) ] 2988 2989 self.assertEqual( 2990 [2, 3, 1], 2991 lines)
2992
2993 - def test_sourceline_iterparse_start(self):
2994 iterparse = self.etree.iterparse 2995 lines = [ el.sourceline for (event, el) in 2996 iterparse(fileInTestDir('include/test_xinclude.xml'), 2997 events=("start",)) ] 2998 2999 self.assertEqual( 3000 [1, 2, 3], 3001 lines)
3002
3003 - def test_sourceline_element(self):
3004 Element = self.etree.Element 3005 SubElement = self.etree.SubElement 3006 el = Element("test") 3007 self.assertEqual(None, el.sourceline) 3008 3009 child = SubElement(el, "test") 3010 self.assertEqual(None, el.sourceline) 3011 self.assertEqual(None, child.sourceline)
3012
3013 - def test_XML_base_url_docinfo(self):
3014 etree = self.etree 3015 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3016 docinfo = root.getroottree().docinfo 3017 self.assertEqual(docinfo.URL, "http://no/such/url")
3018
3019 - def test_XML_set_base_url_docinfo(self):
3020 etree = self.etree 3021 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3022 docinfo = root.getroottree().docinfo 3023 self.assertEqual(docinfo.URL, "http://no/such/url") 3024 docinfo.URL = "https://secret/url" 3025 self.assertEqual(docinfo.URL, "https://secret/url")
3026
3027 - def test_parse_stringio_base_url(self):
3028 etree = self.etree 3029 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url") 3030 docinfo = tree.docinfo 3031 self.assertEqual(docinfo.URL, "http://no/such/url")
3032
3033 - def test_parse_base_url_docinfo(self):
3034 etree = self.etree 3035 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 3036 base_url="http://no/such/url") 3037 docinfo = tree.docinfo 3038 self.assertEqual(docinfo.URL, "http://no/such/url")
3039
3040 - def test_HTML_base_url_docinfo(self):
3041 etree = self.etree 3042 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url") 3043 docinfo = root.getroottree().docinfo 3044 self.assertEqual(docinfo.URL, "http://no/such/url")
3045
3046 - def test_docinfo_public(self):
3047 etree = self.etree 3048 xml_header = '<?xml version="1.0" encoding="ascii"?>' 3049 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 3050 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 3051 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 3052 3053 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 3054 3055 tree = etree.parse(BytesIO(xml)) 3056 docinfo = tree.docinfo 3057 self.assertEqual(docinfo.encoding, "ascii") 3058 self.assertEqual(docinfo.xml_version, "1.0") 3059 self.assertEqual(docinfo.public_id, pub_id) 3060 self.assertEqual(docinfo.system_url, sys_id) 3061 self.assertEqual(docinfo.root_name, 'html') 3062 self.assertEqual(docinfo.doctype, doctype_string)
3063
3064 - def test_docinfo_system(self):
3065 etree = self.etree 3066 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 3067 sys_id = "some.dtd" 3068 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 3069 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 3070 3071 tree = etree.parse(BytesIO(xml)) 3072 docinfo = tree.docinfo 3073 self.assertEqual(docinfo.encoding, "UTF-8") 3074 self.assertEqual(docinfo.xml_version, "1.0") 3075 self.assertEqual(docinfo.public_id, None) 3076 self.assertEqual(docinfo.system_url, sys_id) 3077 self.assertEqual(docinfo.root_name, 'html') 3078 self.assertEqual(docinfo.doctype, doctype_string)
3079
3080 - def test_docinfo_empty(self):
3081 etree = self.etree 3082 xml = _bytes('<html><body></body></html>') 3083 tree = etree.parse(BytesIO(xml)) 3084 docinfo = tree.docinfo 3085 self.assertEqual(docinfo.encoding, "UTF-8") 3086 self.assertEqual(docinfo.xml_version, "1.0") 3087 self.assertEqual(docinfo.public_id, None) 3088 self.assertEqual(docinfo.system_url, None) 3089 self.assertEqual(docinfo.root_name, 'html') 3090 self.assertEqual(docinfo.doctype, '')
3091
3092 - def test_docinfo_name_only(self):
3093 etree = self.etree 3094 xml = _bytes('<!DOCTYPE root><root></root>') 3095 tree = etree.parse(BytesIO(xml)) 3096 docinfo = tree.docinfo 3097 self.assertEqual(docinfo.encoding, "UTF-8") 3098 self.assertEqual(docinfo.xml_version, "1.0") 3099 self.assertEqual(docinfo.public_id, None) 3100 self.assertEqual(docinfo.system_url, None) 3101 self.assertEqual(docinfo.root_name, 'root') 3102 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
3103
3104 - def test_doctype_name_only_roundtrip(self):
3105 etree = self.etree 3106 xml = _bytes('<!DOCTYPE root>\n<root/>') 3107 tree = etree.parse(BytesIO(xml)) 3108 self.assertEqual(xml, etree.tostring(tree))
3109
3110 - def test_doctype_output_override(self):
3111 etree = self.etree 3112 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 3113 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 3114 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)) 3115 3116 xml = _bytes('<!DOCTYPE root>\n<root/>') 3117 tree = etree.parse(BytesIO(xml)) 3118 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string), 3119 etree.tostring(tree, doctype=doctype_string))
3120
3121 - def test_xml_base(self):
3122 etree = self.etree 3123 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3124 self.assertEqual(root.base, "http://no/such/url") 3125 self.assertEqual( 3126 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 3127 root.base = "https://secret/url" 3128 self.assertEqual(root.base, "https://secret/url") 3129 self.assertEqual( 3130 root.get('{http://www.w3.org/XML/1998/namespace}base'), 3131 "https://secret/url")
3132
3133 - def test_xml_base_attribute(self):
3134 etree = self.etree 3135 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3136 self.assertEqual(root.base, "http://no/such/url") 3137 self.assertEqual( 3138 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 3139 root.set('{http://www.w3.org/XML/1998/namespace}base', 3140 "https://secret/url") 3141 self.assertEqual(root.base, "https://secret/url") 3142 self.assertEqual( 3143 root.get('{http://www.w3.org/XML/1998/namespace}base'), 3144 "https://secret/url")
3145
3146 - def test_html_base(self):
3147 etree = self.etree 3148 root = etree.HTML(_bytes("<html><body></body></html>"), 3149 base_url="http://no/such/url") 3150 self.assertEqual(root.base, "http://no/such/url")
3151
3152 - def test_html_base_tag(self):
3153 etree = self.etree 3154 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 3155 self.assertEqual(root.base, "http://no/such/url")
3156
3157 - def test_parse_fileobject_unicode(self):
3158 # parse from a file object that returns unicode strings 3159 f = LargeFileLikeUnicode() 3160 tree = self.etree.parse(f) 3161 root = tree.getroot() 3162 self.assertTrue(root.tag.endswith('root'))
3163
3164 - def test_dtd_io(self):
3165 # check that DTDs that go in also go back out 3166 xml = _bytes('''\ 3167 <!DOCTYPE test SYSTEM "test.dtd" [ 3168 <!ENTITY entity "tasty"> 3169 <!ELEMENT test (a)> 3170 <!ELEMENT a (#PCDATA)> 3171 ]> 3172 <test><a>test-test</a></test>\ 3173 ''') 3174 tree = self.etree.parse(BytesIO(xml)) 3175 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 3176 xml.replace(_bytes(" "), _bytes("")))
3177
3178 - def test_byte_zero(self):
3179 Element = self.etree.Element 3180 3181 a = Element('a') 3182 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 3183 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 3184 3185 self.assertRaises(ValueError, Element, 'ha\0ho')
3186
3187 - def test_unicode_byte_zero(self):
3188 Element = self.etree.Element 3189 3190 a = Element('a') 3191 self.assertRaises(ValueError, setattr, a, "text", 3192 _str('ha\0ho')) 3193 self.assertRaises(ValueError, setattr, a, "tail", 3194 _str('ha\0ho')) 3195 3196 self.assertRaises(ValueError, Element, 3197 _str('ha\0ho'))
3198
3199 - def test_byte_invalid(self):
3200 Element = self.etree.Element 3201 3202 a = Element('a') 3203 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 3204 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 3205 3206 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 3207 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 3208 3209 self.assertRaises(ValueError, Element, 'ha\x07ho') 3210 self.assertRaises(ValueError, Element, 'ha\x02ho')
3211
3212 - def test_unicode_byte_invalid(self):
3213 Element = self.etree.Element 3214 3215 a = Element('a') 3216 self.assertRaises(ValueError, setattr, a, "text", 3217 _str('ha\x07ho')) 3218 self.assertRaises(ValueError, setattr, a, "text", 3219 _str('ha\x02ho')) 3220 3221 self.assertRaises(ValueError, setattr, a, "tail", 3222 _str('ha\x07ho')) 3223 self.assertRaises(ValueError, setattr, a, "tail", 3224 _str('ha\x02ho')) 3225 3226 self.assertRaises(ValueError, Element, 3227 _str('ha\x07ho')) 3228 self.assertRaises(ValueError, Element, 3229 _str('ha\x02ho'))
3230
3231 - def test_unicode_byte_invalid_sequence(self):
3232 Element = self.etree.Element 3233 3234 a = Element('a') 3235 self.assertRaises(ValueError, setattr, a, "text", 3236 _str('ha\u1234\x07ho')) 3237 self.assertRaises(ValueError, setattr, a, "text", 3238 _str('ha\u1234\x02ho')) 3239 3240 self.assertRaises(ValueError, setattr, a, "tail", 3241 _str('ha\u1234\x07ho')) 3242 self.assertRaises(ValueError, setattr, a, "tail", 3243 _str('ha\u1234\x02ho')) 3244 3245 self.assertRaises(ValueError, Element, 3246 _str('ha\u1234\x07ho')) 3247 self.assertRaises(ValueError, Element, 3248 _str('ha\u1234\x02ho'))
3249
3250 - def test_encoding_tostring_utf16(self):
3251 # ElementTree fails to serialize this 3252 tostring = self.etree.tostring 3253 Element = self.etree.Element 3254 SubElement = self.etree.SubElement 3255 3256 a = Element('a') 3257 b = SubElement(a, 'b') 3258 c = SubElement(a, 'c') 3259 3260 result = tostring(a, encoding='UTF-16') 3261 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3262 canonicalize(result))
3263
3264 - def test_tostring_none(self):
3265 # ElementTree raises an AssertionError here 3266 tostring = self.etree.tostring 3267 self.assertRaises(TypeError, self.etree.tostring, None)
3268
3269 - def test_tostring_pretty(self):
3270 tostring = self.etree.tostring 3271 Element = self.etree.Element 3272 SubElement = self.etree.SubElement 3273 3274 a = Element('a') 3275 b = SubElement(a, 'b') 3276 c = SubElement(a, 'c') 3277 3278 result = tostring(a) 3279 self.assertEqual(result, _bytes("<a><b/><c/></a>")) 3280 3281 result = tostring(a, pretty_print=False) 3282 self.assertEqual(result, _bytes("<a><b/><c/></a>")) 3283 3284 result = tostring(a, pretty_print=True) 3285 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3286
3287 - def test_tostring_with_tail(self):
3288 tostring = self.etree.tostring 3289 Element = self.etree.Element 3290 SubElement = self.etree.SubElement 3291 3292 a = Element('a') 3293 a.tail = "aTAIL" 3294 b = SubElement(a, 'b') 3295 b.tail = "bTAIL" 3296 c = SubElement(a, 'c') 3297 3298 result = tostring(a) 3299 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 3300 3301 result = tostring(a, with_tail=False) 3302 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>")) 3303 3304 result = tostring(a, with_tail=True) 3305 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3306
3307 - def test_tostring_method_html_with_tail(self):
3308 tostring = self.etree.tostring 3309 html = self.etree.fromstring( 3310 '<html><body>' 3311 '<div><p>Some text<i>\r\n</i></p></div>\r\n' 3312 '</body></html>', 3313 parser=self.etree.HTMLParser()) 3314 self.assertEqual(html.tag, 'html') 3315 div = html.find('.//div') 3316 self.assertEqual(div.tail, '\r\n') 3317 result = tostring(div, method='html') 3318 self.assertEqual( 3319 result, 3320 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 3321 result = tostring(div, method='html', with_tail=True) 3322 self.assertEqual( 3323 result, 3324 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 3325 result = tostring(div, method='html', with_tail=False) 3326 self.assertEqual( 3327 result, 3328 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3329
3330 - def test_standalone(self):
3331 tostring = self.etree.tostring 3332 XML = self.etree.XML 3333 ElementTree = self.etree.ElementTree 3334 Element = self.etree.Element 3335 3336 tree = Element("root").getroottree() 3337 self.assertEqual(None, tree.docinfo.standalone) 3338 3339 tree = XML(_bytes("<root/>")).getroottree() 3340 self.assertEqual(None, tree.docinfo.standalone) 3341 3342 tree = XML(_bytes( 3343 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>" 3344 )).getroottree() 3345 self.assertEqual(True, tree.docinfo.standalone) 3346 3347 tree = XML(_bytes( 3348 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>" 3349 )).getroottree() 3350 self.assertEqual(False, tree.docinfo.standalone)
3351
3352 - def test_tostring_standalone(self):
3353 tostring = self.etree.tostring 3354 XML = self.etree.XML 3355 ElementTree = self.etree.ElementTree 3356 3357 root = XML(_bytes("<root/>")) 3358 3359 tree = ElementTree(root) 3360 self.assertEqual(None, tree.docinfo.standalone) 3361 3362 result = tostring(root, xml_declaration=True, encoding="ASCII") 3363 self.assertEqual(result, _bytes( 3364 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 3365 3366 result = tostring(root, xml_declaration=True, encoding="ASCII", 3367 standalone=True) 3368 self.assertEqual(result, _bytes( 3369 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 3370 3371 tree = ElementTree(XML(result)) 3372 self.assertEqual(True, tree.docinfo.standalone) 3373 3374 result = tostring(root, xml_declaration=True, encoding="ASCII", 3375 standalone=False) 3376 self.assertEqual(result, _bytes( 3377 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>")) 3378 3379 tree = ElementTree(XML(result)) 3380 self.assertEqual(False, tree.docinfo.standalone)
3381
3382 - def test_tostring_standalone_in_out(self):
3383 tostring = self.etree.tostring 3384 XML = self.etree.XML 3385 ElementTree = self.etree.ElementTree 3386 3387 root = XML(_bytes( 3388 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>")) 3389 3390 tree = ElementTree(root) 3391 self.assertEqual(True, tree.docinfo.standalone) 3392 3393 result = tostring(root, xml_declaration=True, encoding="ASCII") 3394 self.assertEqual(result, _bytes( 3395 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 3396 3397 result = tostring(root, xml_declaration=True, encoding="ASCII", 3398 standalone=True) 3399 self.assertEqual(result, _bytes( 3400 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3401
3402 - def test_tostring_method_text_encoding(self):
3403 tostring = self.etree.tostring 3404 Element = self.etree.Element 3405 SubElement = self.etree.SubElement 3406 3407 a = Element('a') 3408 a.text = "A" 3409 a.tail = "tail" 3410 b = SubElement(a, 'b') 3411 b.text = "B" 3412 b.tail = _str("Søk på nettet") 3413 c = SubElement(a, 'c') 3414 c.text = "C" 3415 3416 result = tostring(a, method="text", encoding="UTF-16") 3417 3418 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"), 3419 result)
3420
3421 - def test_tostring_method_text_unicode(self):
3422 tostring = self.etree.tostring 3423 Element = self.etree.Element 3424 SubElement = self.etree.SubElement 3425 3426 a = Element('a') 3427 a.text = _str('Søk på nettetA') 3428 a.tail = "tail" 3429 b = SubElement(a, 'b') 3430 b.text = "B" 3431 b.tail = _str('Søk på nettetB') 3432 c = SubElement(a, 'c') 3433 c.text = "C" 3434 3435 self.assertRaises(UnicodeEncodeError, 3436 tostring, a, method="text") 3437 3438 self.assertEqual( 3439 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 3440 tostring(a, encoding="UTF-8", method="text"))
3441
3442 - def test_tounicode(self):
3443 tounicode = self.etree.tounicode 3444 Element = self.etree.Element 3445 SubElement = self.etree.SubElement 3446 3447 a = Element('a') 3448 b = SubElement(a, 'b') 3449 c = SubElement(a, 'c') 3450 3451 self.assertTrue(isinstance(tounicode(a), _unicode)) 3452 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3453 canonicalize(tounicode(a)))
3454
3455 - def test_tounicode_element(self):
3456 tounicode = self.etree.tounicode 3457 Element = self.etree.Element 3458 SubElement = self.etree.SubElement 3459 3460 a = Element('a') 3461 b = SubElement(a, 'b') 3462 c = SubElement(a, 'c') 3463 d = SubElement(c, 'd') 3464 self.assertTrue(isinstance(tounicode(b), _unicode)) 3465 self.assertTrue(isinstance(tounicode(c), _unicode)) 3466 self.assertEqual(_bytes('<b></b>'), 3467 canonicalize(tounicode(b))) 3468 self.assertEqual(_bytes('<c><d></d></c>'), 3469 canonicalize(tounicode(c)))
3470
3471 - def test_tounicode_none(self):
3472 tounicode = self.etree.tounicode 3473 self.assertRaises(TypeError, self.etree.tounicode, None)
3474
3475 - def test_tounicode_element_tail(self):
3476 tounicode = self.etree.tounicode 3477 Element = self.etree.Element 3478 SubElement = self.etree.SubElement 3479 3480 a = Element('a') 3481 b = SubElement(a, 'b') 3482 c = SubElement(a, 'c') 3483 d = SubElement(c, 'd') 3484 b.tail = 'Foo' 3485 3486 self.assertTrue(isinstance(tounicode(b), _unicode)) 3487 self.assertTrue(tounicode(b) == '<b/>Foo' or 3488 tounicode(b) == '<b />Foo')
3489
3490 - def test_tounicode_pretty(self):
3491 tounicode = self.etree.tounicode 3492 Element = self.etree.Element 3493 SubElement = self.etree.SubElement 3494 3495 a = Element('a') 3496 b = SubElement(a, 'b') 3497 c = SubElement(a, 'c') 3498 3499 result = tounicode(a) 3500 self.assertEqual(result, "<a><b/><c/></a>") 3501 3502 result = tounicode(a, pretty_print=False) 3503 self.assertEqual(result, "<a><b/><c/></a>") 3504 3505 result = tounicode(a, pretty_print=True) 3506 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3507
3508 - def test_tostring_unicode(self):
3509 tostring = self.etree.tostring 3510 Element = self.etree.Element 3511 SubElement = self.etree.SubElement 3512 3513 a = Element('a') 3514 b = SubElement(a, 'b') 3515 c = SubElement(a, 'c') 3516 3517 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode)) 3518 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3519 canonicalize(tostring(a, encoding=_unicode)))
3520
3521 - def test_tostring_unicode_element(self):
3522 tostring = self.etree.tostring 3523 Element = self.etree.Element 3524 SubElement = self.etree.SubElement 3525 3526 a = Element('a') 3527 b = SubElement(a, 'b') 3528 c = SubElement(a, 'c') 3529 d = SubElement(c, 'd') 3530 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 3531 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode)) 3532 self.assertEqual(_bytes('<b></b>'), 3533 canonicalize(tostring(b, encoding=_unicode))) 3534 self.assertEqual(_bytes('<c><d></d></c>'), 3535 canonicalize(tostring(c, encoding=_unicode)))
3536
3537 - def test_tostring_unicode_none(self):
3538 tostring = self.etree.tostring 3539 self.assertRaises(TypeError, self.etree.tostring, 3540 None, encoding=_unicode)
3541
3542 - def test_tostring_unicode_element_tail(self):
3543 tostring = self.etree.tostring 3544 Element = self.etree.Element 3545 SubElement = self.etree.SubElement 3546 3547 a = Element('a') 3548 b = SubElement(a, 'b') 3549 c = SubElement(a, 'c') 3550 d = SubElement(c, 'd') 3551 b.tail = 'Foo' 3552 3553 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 3554 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or 3555 tostring(b, encoding=_unicode) == '<b />Foo')
3556
3557 - def test_tostring_unicode_pretty(self):
3558 tostring = self.etree.tostring 3559 Element = self.etree.Element 3560 SubElement = self.etree.SubElement 3561 3562 a = Element('a') 3563 b = SubElement(a, 'b') 3564 c = SubElement(a, 'c') 3565 3566 result = tostring(a, encoding=_unicode) 3567 self.assertEqual(result, "<a><b/><c/></a>") 3568 3569 result = tostring(a, encoding=_unicode, pretty_print=False) 3570 self.assertEqual(result, "<a><b/><c/></a>") 3571 3572 result = tostring(a, encoding=_unicode, pretty_print=True) 3573 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3574
3575 - def test_pypy_proxy_collect(self):
3576 root = etree.Element('parent') 3577 etree.SubElement(root, 'child') 3578 3579 self.assertEqual(len(root), 1) 3580 self.assertEqual(root[0].tag, 'child') 3581 3582 # in PyPy, GC used to kill the Python proxy instance without cleanup 3583 gc.collect() 3584 self.assertEqual(len(root), 1) 3585 self.assertEqual(root[0].tag, 'child')
3586
3587 - def test_element_refcycle(self):
3588 class SubEl(etree.ElementBase): 3589 pass
3590 3591 el1 = SubEl() 3592 el2 = SubEl() 3593 self.assertEqual('SubEl', el1.tag) 3594 self.assertEqual('SubEl', el2.tag) 3595 el1.other = el2 3596 el2.other = el1 3597 3598 del el1, el2 3599 gc.collect() 3600 # not really testing anything here, but it shouldn't crash 3601
3602 - def test_proxy_collect_siblings(self):
3603 root = etree.Element('parent') 3604 c1 = etree.SubElement(root, 'child1') 3605 c2 = etree.SubElement(root, 'child2') 3606 3607 root.remove(c1) 3608 root.remove(c2) 3609 c1.addnext(c2) 3610 del c1 3611 # trigger deallocation attempt of c1 3612 c2.getprevious() 3613 # make sure it wasn't deallocated 3614 self.assertEqual('child1', c2.getprevious().tag)
3615
3616 - def test_proxy_collect_siblings_text(self):
3617 root = etree.Element('parent') 3618 c1 = etree.SubElement(root, 'child1') 3619 c2 = etree.SubElement(root, 'child2') 3620 3621 root.remove(c1) 3622 root.remove(c2) 3623 c1.addnext(c2) 3624 c1.tail = 'abc' 3625 c2.tail = 'xyz' 3626 del c1 3627 # trigger deallocation attempt of c1 3628 c2.getprevious() 3629 # make sure it wasn't deallocated 3630 self.assertEqual('child1', c2.getprevious().tag) 3631 self.assertEqual('abc', c2.getprevious().tail)
3632 3633 # helper methods 3634
3635 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3636 """Write out element for comparison. 3637 """ 3638 ElementTree = self.etree.ElementTree 3639 f = BytesIO() 3640 tree = ElementTree(element=element) 3641 tree.write(f, encoding=encoding, compression=compression) 3642 data = f.getvalue() 3643 if compression: 3644 data = zlib.decompress(data) 3645 return canonicalize(data)
3646 3647
3648 -class _XIncludeTestCase(HelperTestCase):
3649 - def test_xinclude_text(self):
3650 filename = fileInTestDir('test_broken.xml') 3651 root = etree.XML(_bytes('''\ 3652 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 3653 <xi:include href="%s" parse="text"/> 3654 </doc> 3655 ''' % path2url(filename))) 3656 old_text = root.text 3657 content = read_file(filename) 3658 old_tail = root[0].tail 3659 3660 self.include( etree.ElementTree(root) ) 3661 self.assertEqual(old_text + content + old_tail, 3662 root.text)
3663
3664 - def test_xinclude(self):
3665 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 3666 self.assertNotEqual( 3667 'a', 3668 tree.getroot()[1].tag) 3669 # process xincludes 3670 self.include( tree ) 3671 # check whether we find it replaced with included data 3672 self.assertEqual( 3673 'a', 3674 tree.getroot()[1].tag)
3675
3676 - def test_xinclude_resolver(self):
3677 class res(etree.Resolver): 3678 include_text = read_file(fileInTestDir('test.xml')) 3679 called = {} 3680 def resolve(self, url, id, context): 3681 if url.endswith(".dtd"): 3682 self.called["dtd"] = True 3683 return self.resolve_filename( 3684 fileInTestDir('test.dtd'), context) 3685 elif url.endswith("test_xinclude.xml"): 3686 self.called["input"] = True 3687 return None # delegate to default resolver 3688 else: 3689 self.called["include"] = True 3690 return self.resolve_string(self.include_text, context)
3691 3692 res_instance = res() 3693 parser = etree.XMLParser(load_dtd = True) 3694 parser.resolvers.add(res_instance) 3695 3696 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 3697 parser = parser) 3698 3699 self.include(tree) 3700 3701 called = list(res_instance.called.items()) 3702 called.sort() 3703 self.assertEqual( 3704 [("dtd", True), ("include", True), ("input", True)], 3705 called) 3706 3707
3708 -class ETreeXIncludeTestCase(_XIncludeTestCase):
3709 - def include(self, tree):
3710 tree.xinclude()
3711 3712
3713 -class ElementIncludeTestCase(_XIncludeTestCase):
3714 from lxml import ElementInclude
3715 - def include(self, tree):
3716 self.ElementInclude.include(tree.getroot())
3717 3718
3719 -class ETreeC14NTestCase(HelperTestCase):
3720 - def test_c14n(self):
3721 tree = self.parse(_bytes('<a><b/></a>')) 3722 f = BytesIO() 3723 tree.write_c14n(f) 3724 s = f.getvalue() 3725 self.assertEqual(_bytes('<a><b></b></a>'), 3726 s)
3727
3728 - def test_c14n_gzip(self):
3729 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3730 f = BytesIO() 3731 tree.write_c14n(f, compression=9) 3732 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue())) 3733 try: 3734 s = gzfile.read() 3735 finally: 3736 gzfile.close() 3737 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 3738 s)
3739
3740 - def test_c14n_file(self):
3741 tree = self.parse(_bytes('<a><b/></a>')) 3742 handle, filename = tempfile.mkstemp() 3743 try: 3744 tree.write_c14n(filename) 3745 data = read_file(filename, 'rb') 3746 finally: 3747 os.close(handle) 3748 os.remove(filename) 3749 self.assertEqual(_bytes('<a><b></b></a>'), 3750 data)
3751
3752 - def test_c14n_file_gzip(self):
3753 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3754 handle, filename = tempfile.mkstemp() 3755 try: 3756 tree.write_c14n(filename, compression=9) 3757 f = gzip.open(filename, 'rb') 3758 try: 3759 data = f.read() 3760 finally: 3761 f.close() 3762 finally: 3763 os.close(handle) 3764 os.remove(filename) 3765 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 3766 data)
3767
3768 - def test_c14n_with_comments(self):
3769 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3770 f = BytesIO() 3771 tree.write_c14n(f) 3772 s = f.getvalue() 3773 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3774 s) 3775 f = BytesIO() 3776 tree.write_c14n(f, with_comments=True) 3777 s = f.getvalue() 3778 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3779 s) 3780 f = BytesIO() 3781 tree.write_c14n(f, with_comments=False) 3782 s = f.getvalue() 3783 self.assertEqual(_bytes('<a><b></b></a>'), 3784 s)
3785
3787 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3788 s = etree.tostring(tree, method='c14n') 3789 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3790 s) 3791 s = etree.tostring(tree, method='c14n', with_comments=True) 3792 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3793 s) 3794 s = etree.tostring(tree, method='c14n', with_comments=False) 3795 self.assertEqual(_bytes('<a><b></b></a>'), 3796 s)
3797
3799 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3800 s = etree.tostring(tree.getroot(), method='c14n') 3801 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 3802 s) 3803 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True) 3804 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 3805 s) 3806 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False) 3807 self.assertEqual(_bytes('<a><b></b></a>'), 3808 s)
3809
3810 - def test_c14n_exclusive(self):
3811 tree = self.parse(_bytes( 3812 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3813 f = BytesIO() 3814 tree.write_c14n(f) 3815 s = f.getvalue() 3816 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3817 s) 3818 f = BytesIO() 3819 tree.write_c14n(f, exclusive=False) 3820 s = f.getvalue() 3821 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3822 s) 3823 f = BytesIO() 3824 tree.write_c14n(f, exclusive=True) 3825 s = f.getvalue() 3826 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 3827 s) 3828 3829 f = BytesIO() 3830 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z']) 3831 s = f.getvalue() 3832 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'), 3833 s)
3834
3836 tree = self.parse(_bytes( 3837 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3838 s = etree.tostring(tree, method='c14n') 3839 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3840 s) 3841 s = etree.tostring(tree, method='c14n', exclusive=False) 3842 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3843 s) 3844 s = etree.tostring(tree, method='c14n', exclusive=True) 3845 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 3846 s) 3847 3848 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 3849 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'), 3850 s)
3851
3853 tree = self.parse(_bytes( 3854 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3855 s = etree.tostring(tree.getroot(), method='c14n') 3856 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3857 s) 3858 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False) 3859 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3860 s) 3861 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True) 3862 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 3863 s) 3864 3865 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False) 3866 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 3867 s) 3868 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True) 3869 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'), 3870 s) 3871 3872 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 3873 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 3874 s)
3875
3877 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)""" 3878 tree = self.parse(_bytes( 3879 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3880 3881 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z']) 3882 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3883 s)
3884 3885
3886 -class ETreeWriteTestCase(HelperTestCase):
3887 - def test_write(self):
3888 tree = self.parse(_bytes('<a><b/></a>')) 3889 f = BytesIO() 3890 tree.write(f) 3891 s = f.getvalue() 3892 self.assertEqual(_bytes('<a><b/></a>'), 3893 s)
3894
3895 - def test_write_gzip(self):
3896 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3897 f = BytesIO() 3898 tree.write(f, compression=9) 3899 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue())) 3900 try: 3901 s = gzfile.read() 3902 finally: 3903 gzfile.close() 3904 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3905 s)
3906
3907 - def test_write_gzip_level(self):
3908 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3909 f = BytesIO() 3910 tree.write(f, compression=0) 3911 s0 = f.getvalue() 3912 3913 f = BytesIO() 3914 tree.write(f) 3915 self.assertEqual(f.getvalue(), s0) 3916 3917 f = BytesIO() 3918 tree.write(f, compression=1) 3919 s = f.getvalue() 3920 self.assertTrue(len(s) <= len(s0)) 3921 gzfile = gzip.GzipFile(fileobj=BytesIO(s)) 3922 try: 3923 s1 = gzfile.read() 3924 finally: 3925 gzfile.close() 3926 3927 f = BytesIO() 3928 tree.write(f, compression=9) 3929 s = f.getvalue() 3930 self.assertTrue(len(s) <= len(s0)) 3931 gzfile = gzip.GzipFile(fileobj=BytesIO(s)) 3932 try: 3933 s9 = gzfile.read() 3934 finally: 3935 gzfile.close() 3936 3937 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3938 s0) 3939 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3940 s1) 3941 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3942 s9)
3943
3944 - def test_write_file(self):
3945 tree = self.parse(_bytes('<a><b/></a>')) 3946 handle, filename = tempfile.mkstemp() 3947 try: 3948 tree.write(filename) 3949 data = read_file(filename, 'rb') 3950 finally: 3951 os.close(handle) 3952 os.remove(filename) 3953 self.assertEqual(_bytes('<a><b/></a>'), 3954 data)
3955
3956 - def test_write_file_gzip(self):
3957 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3958 handle, filename = tempfile.mkstemp() 3959 try: 3960 tree.write(filename, compression=9) 3961 f = gzip.open(filename, 'rb') 3962 try: 3963 data = f.read() 3964 finally: 3965 f.close() 3966 finally: 3967 os.close(handle) 3968 os.remove(filename) 3969 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3970 data)
3971
3972 - def test_write_file_gzip_parse(self):
3973 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3974 handle, filename = tempfile.mkstemp() 3975 try: 3976 tree.write(filename, compression=9) 3977 data = etree.tostring(etree.parse(filename)) 3978 finally: 3979 os.close(handle) 3980 os.remove(filename) 3981 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3982 data)
3983
3985 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3986 handle, filename = tempfile.mkstemp() 3987 try: 3988 tree.write(filename, compression=9) 3989 data = etree.tostring(etree.parse( 3990 gzip.GzipFile(filename))) 3991 finally: 3992 os.close(handle) 3993 os.remove(filename) 3994 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 3995 data)
3996
3997 -class ETreeErrorLogTest(HelperTestCase):
3998 etree = etree 3999
4000 - def test_parse_error_logging(self):
4001 parse = self.etree.parse 4002 f = BytesIO('<a><b></c></b></a>') 4003 self.etree.clear_error_log() 4004 try: 4005 parse(f) 4006 logs = None 4007 except SyntaxError: 4008 e = sys.exc_info()[1] 4009 logs = e.error_log 4010 f.close() 4011 self.assertTrue([ log for log in logs 4012 if 'mismatch' in log.message ]) 4013 self.assertTrue([ log for log in logs 4014 if 'PARSER' in log.domain_name]) 4015 self.assertTrue([ log for log in logs 4016 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ]) 4017 self.assertTrue([ log for log in logs 4018 if 1 == log.line ]) 4019 self.assertTrue([ log for log in logs 4020 if 15 == log.column ])
4021
4022 - def _test_python_error_logging(self):
4023 """This can't really be tested as long as there isn't a way to 4024 reset the logging setup ... 4025 """ 4026 parse = self.etree.parse 4027 4028 messages = [] 4029 class Logger(self.etree.PyErrorLog): 4030 def log(self, entry, message, *args): 4031 messages.append(message)
4032 4033 self.etree.use_global_python_log(Logger()) 4034 f = BytesIO('<a><b></c></b></a>') 4035 try: 4036 parse(f) 4037 except SyntaxError: 4038 pass 4039 f.close() 4040 4041 self.assertTrue([ message for message in messages 4042 if 'mismatch' in message ]) 4043 self.assertTrue([ message for message in messages 4044 if ':PARSER:' in message]) 4045 self.assertTrue([ message for message in messages 4046 if ':ERR_TAG_NAME_MISMATCH:' in message ]) 4047 self.assertTrue([ message for message in messages 4048 if ':1:15:' in message ]) 4049 4050
4051 -class XMLPullParserTest(unittest.TestCase):
4052 etree = etree 4053
4054 - def assert_event_tags(self, events, expected):
4055 self.assertEqual([(action, elem.tag) for action, elem in events], 4056 expected)
4057
4059 class Target(object): 4060 def start(self, tag, attrib): 4061 return 'start(%s)' % tag
4062 def end(self, tag): 4063 return 'end(%s)' % tag
4064 def close(self): 4065 return 'close()' 4066 4067 parser = self.etree.XMLPullParser(target=Target()) 4068 events = parser.read_events() 4069 4070 parser.feed('<root><element>') 4071 self.assertFalse(list(events)) 4072 self.assertFalse(list(events)) 4073 parser.feed('</element><child>') 4074 self.assertEqual([('end', 'end(element)')], list(events)) 4075 parser.feed('</child>') 4076 self.assertEqual([('end', 'end(child)')], list(events)) 4077 parser.feed('</root>') 4078 self.assertEqual([('end', 'end(root)')], list(events)) 4079 self.assertFalse(list(events)) 4080 self.assertEqual('close()', parser.close()) 4081
4082 - def test_pull_from_simple_target_start_end(self):
4083 class Target(object): 4084 def start(self, tag, attrib): 4085 return 'start(%s)' % tag
4086 def end(self, tag): 4087 return 'end(%s)' % tag 4088 def close(self): 4089 return 'close()' 4090 4091 parser = self.etree.XMLPullParser( 4092 ['start', 'end'], target=Target()) 4093 events = parser.read_events() 4094 4095 parser.feed('<root><element>') 4096 self.assertEqual( 4097 [('start', 'start(root)'), ('start', 'start(element)')], 4098 list(events)) 4099 self.assertFalse(list(events)) 4100 parser.feed('</element><child>') 4101 self.assertEqual( 4102 [('end', 'end(element)'), ('start', 'start(child)')], 4103 list(events)) 4104 parser.feed('</child>') 4105 self.assertEqual( 4106 [('end', 'end(child)')], 4107 list(events)) 4108 parser.feed('</root>') 4109 self.assertEqual( 4110 [('end', 'end(root)')], 4111 list(events)) 4112 self.assertFalse(list(events)) 4113 self.assertEqual('close()', parser.close()) 4114
4115 - def test_pull_from_tree_builder(self):
4116 parser = self.etree.XMLPullParser( 4117 ['start', 'end'], target=etree.TreeBuilder()) 4118 events = parser.read_events() 4119 4120 parser.feed('<root><element>') 4121 self.assert_event_tags( 4122 events, [('start', 'root'), ('start', 'element')]) 4123 self.assertFalse(list(events)) 4124 parser.feed('</element><child>') 4125 self.assert_event_tags( 4126 events, [('end', 'element'), ('start', 'child')]) 4127 parser.feed('</child>') 4128 self.assert_event_tags( 4129 events, [('end', 'child')]) 4130 parser.feed('</root>') 4131 self.assert_event_tags( 4132 events, [('end', 'root')]) 4133 self.assertFalse(list(events)) 4134 root = parser.close() 4135 self.assertEqual('root', root.tag)
4136
4137 - def test_pull_from_tree_builder_subclass(self):
4138 class Target(etree.TreeBuilder): 4139 def end(self, tag): 4140 el = super(Target, self).end(tag) 4141 el.tag += '-huhu' 4142 return el
4143 4144 parser = self.etree.XMLPullParser( 4145 ['start', 'end'], target=Target()) 4146 events = parser.read_events() 4147 4148 parser.feed('<root><element>') 4149 self.assert_event_tags( 4150 events, [('start', 'root'), ('start', 'element')]) 4151 self.assertFalse(list(events)) 4152 parser.feed('</element><child>') 4153 self.assert_event_tags( 4154 events, [('end', 'element-huhu'), ('start', 'child')]) 4155 parser.feed('</child>') 4156 self.assert_event_tags( 4157 events, [('end', 'child-huhu')]) 4158 parser.feed('</root>') 4159 self.assert_event_tags( 4160 events, [('end', 'root-huhu')]) 4161 self.assertFalse(list(events)) 4162 root = parser.close() 4163 self.assertEqual('root-huhu', root.tag) 4164 4165
4166 -def test_suite():
4167 suite = unittest.TestSuite() 4168 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 4169 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 4170 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 4171 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 4172 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)]) 4173 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)]) 4174 suite.addTests([unittest.makeSuite(XMLPullParserTest)]) 4175 suite.addTests(doctest.DocTestSuite(etree)) 4176 suite.addTests( 4177 [make_doctest('../../../doc/tutorial.txt')]) 4178 if sys.version_info >= (2,6): 4179 # now requires the 'with' statement 4180 suite.addTests( 4181 [make_doctest('../../../doc/api.txt')]) 4182 suite.addTests( 4183 [make_doctest('../../../doc/FAQ.txt')]) 4184 suite.addTests( 4185 [make_doctest('../../../doc/parsing.txt')]) 4186 suite.addTests( 4187 [make_doctest('../../../doc/resolvers.txt')]) 4188 return suite
4189 4190 if __name__ == '__main__': 4191 print('to test use test.py %s' % __file__) 4192