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