Package lxml :: Package tests :: Module test_etree
[hide private]
[frames] | no frames]

Source Code for Module lxml.tests.test_etree

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