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

Source Code for Module lxml.tests.test_etree

   1  # -*- coding: utf-8 -*- 
   2   
   3  """ 
   4  Tests specific to the extended etree API 
   5   
   6  Tests that apply to the general ElementTree API should go into 
   7  test_elementtree 
   8  """ 
   9   
  10  import os.path 
  11  import unittest 
  12  import copy 
  13  import sys 
  14  import re 
  15  import gc 
  16  import operator 
  17  import tempfile 
  18  import gzip 
  19   
  20  this_dir = os.path.dirname(__file__) 
  21  if this_dir not in sys.path: 
  22      sys.path.insert(0, this_dir) # needed for Py3 
  23   
  24  from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir, read_file 
  25  from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest 
  26  from common_imports import canonicalize, sorted, _str, _bytes 
  27   
  28  print("") 
  29  print("TESTED VERSION: %s" % etree.__version__) 
  30  print("    Python:           " + repr(sys.version_info)) 
  31  print("    lxml.etree:       " + repr(etree.LXML_VERSION)) 
  32  print("    libxml used:      " + repr(etree.LIBXML_VERSION)) 
  33  print("    libxml compiled:  " + repr(etree.LIBXML_COMPILED_VERSION)) 
  34  print("    libxslt used:     " + repr(etree.LIBXSLT_VERSION)) 
  35  print("    libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION)) 
  36  print("") 
  37   
  38  try: 
  39      _unicode = unicode 
  40  except NameError: 
  41      # Python 3 
  42      _unicode = str 
  43   
44 -class ETreeOnlyTestCase(HelperTestCase):
45 """Tests only for etree, not ElementTree""" 46 etree = etree 47
48 - def test_version(self):
49 self.assertTrue(isinstance(etree.__version__, _unicode)) 50 self.assertTrue(isinstance(etree.LXML_VERSION, tuple)) 51 self.assertEqual(len(etree.LXML_VERSION), 4) 52 self.assertTrue(isinstance(etree.LXML_VERSION[0], int)) 53 self.assertTrue(isinstance(etree.LXML_VERSION[1], int)) 54 self.assertTrue(isinstance(etree.LXML_VERSION[2], int)) 55 self.assertTrue(isinstance(etree.LXML_VERSION[3], int)) 56 self.assertTrue(etree.__version__.startswith( 57 str(etree.LXML_VERSION[0])))
58
59 - def test_c_api(self):
60 if hasattr(self.etree, '__pyx_capi__'): 61 # newer Pyrex compatible C-API 62 self.assertTrue(isinstance(self.etree.__pyx_capi__, dict)) 63 self.assertTrue(len(self.etree.__pyx_capi__) > 0) 64 else: 65 # older C-API mechanism 66 self.assertTrue(hasattr(self.etree, '_import_c_api'))
67
68 - def test_element_names(self):
69 Element = self.etree.Element 70 el = Element('name') 71 self.assertEqual(el.tag, 'name') 72 el = Element('{}name') 73 self.assertEqual(el.tag, 'name')
74
75 - def test_element_name_empty(self):
76 Element = self.etree.Element 77 el = Element('name') 78 self.assertRaises(ValueError, Element, '{}') 79 self.assertRaises(ValueError, setattr, el, 'tag', '{}') 80 81 self.assertRaises(ValueError, Element, '{test}') 82 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
83
84 - def test_element_name_colon(self):
85 Element = self.etree.Element 86 self.assertRaises(ValueError, Element, 'p:name') 87 self.assertRaises(ValueError, Element, '{test}p:name') 88 89 el = Element('name') 90 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
91
92 - def test_element_name_quote(self):
93 Element = self.etree.Element 94 self.assertRaises(ValueError, Element, "p'name") 95 self.assertRaises(ValueError, Element, 'p"name') 96 97 self.assertRaises(ValueError, Element, "{test}p'name") 98 self.assertRaises(ValueError, Element, '{test}p"name') 99 100 el = Element('name') 101 self.assertRaises(ValueError, setattr, el, 'tag', "p'name") 102 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
103
104 - def test_element_name_space(self):
105 Element = self.etree.Element 106 self.assertRaises(ValueError, Element, ' name ') 107 self.assertRaises(ValueError, Element, 'na me') 108 self.assertRaises(ValueError, Element, '{test} name') 109 110 el = Element('name') 111 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
112
113 - def test_subelement_name_empty(self):
114 Element = self.etree.Element 115 SubElement = self.etree.SubElement 116 117 el = Element('name') 118 self.assertRaises(ValueError, SubElement, el, '{}') 119 self.assertRaises(ValueError, SubElement, el, '{test}')
120
121 - def test_subelement_name_colon(self):
122 Element = self.etree.Element 123 SubElement = self.etree.SubElement 124 125 el = Element('name') 126 self.assertRaises(ValueError, SubElement, el, 'p:name') 127 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
128
129 - def test_subelement_name_quote(self):
130 Element = self.etree.Element 131 SubElement = self.etree.SubElement 132 133 el = Element('name') 134 self.assertRaises(ValueError, SubElement, el, "p'name") 135 self.assertRaises(ValueError, SubElement, el, "{test}p'name") 136 137 self.assertRaises(ValueError, SubElement, el, 'p"name') 138 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
139
140 - def test_subelement_name_space(self):
141 Element = self.etree.Element 142 SubElement = self.etree.SubElement 143 144 el = Element('name') 145 self.assertRaises(ValueError, SubElement, el, ' name ') 146 self.assertRaises(ValueError, SubElement, el, 'na me') 147 self.assertRaises(ValueError, SubElement, el, '{test} name')
148
150 Element = self.etree.Element 151 SubElement = self.etree.SubElement 152 153 el = Element('name') 154 self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'}) 155 self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'}) 156 self.assertEqual(0, len(el))
157
158 - def test_qname_empty(self):
159 QName = self.etree.QName 160 self.assertRaises(ValueError, QName, '') 161 self.assertRaises(ValueError, QName, 'test', '')
162
163 - def test_qname_colon(self):
164 QName = self.etree.QName 165 self.assertRaises(ValueError, QName, 'p:name') 166 self.assertRaises(ValueError, QName, 'test', 'p:name')
167
168 - def test_qname_space(self):
169 QName = self.etree.QName 170 self.assertRaises(ValueError, QName, ' name ') 171 self.assertRaises(ValueError, QName, 'na me') 172 self.assertRaises(ValueError, QName, 'test', ' name')
173
175 # ET doesn't have namespace/localname properties on QNames 176 QName = self.etree.QName 177 namespace, localname = 'http://myns', 'a' 178 qname = QName(namespace, localname) 179 self.assertEqual(namespace, qname.namespace) 180 self.assertEqual(localname, qname.localname)
181
182 - def test_qname_element(self):
183 # ET doesn't have namespace/localname properties on QNames 184 QName = self.etree.QName 185 qname1 = QName('http://myns', 'a') 186 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'}) 187 188 qname2 = QName(a) 189 self.assertEqual(a.tag, qname1.text) 190 self.assertEqual(qname1.text, qname2.text) 191 self.assertEqual(qname1, qname2)
192
193 - def test_qname_text_resolve(self):
194 # ET doesn't resove QNames as text values 195 etree = self.etree 196 qname = etree.QName('http://myns', 'a') 197 a = etree.Element(qname, nsmap={'p' : 'http://myns'}) 198 a.text = qname 199 200 self.assertEqual("p:a", a.text)
201
202 - def test_nsmap_prefix_invalid(self):
203 etree = self.etree 204 self.assertRaises(ValueError, 205 etree.Element, "root", nsmap={'"' : 'testns'}) 206 self.assertRaises(ValueError, 207 etree.Element, "root", nsmap={'&' : 'testns'}) 208 self.assertRaises(ValueError, 209 etree.Element, "root", nsmap={'a:b' : 'testns'})
210
211 - def test_attribute_has_key(self):
212 # ET in Py 3.x has no "attrib.has_key()" method 213 XML = self.etree.XML 214 215 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />')) 216 self.assertEqual( 217 True, root.attrib.has_key('bar')) 218 self.assertEqual( 219 False, root.attrib.has_key('baz')) 220 self.assertEqual( 221 False, root.attrib.has_key('hah')) 222 self.assertEqual( 223 True, 224 root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
225
226 - def test_attribute_set(self):
227 Element = self.etree.Element 228 root = Element("root") 229 root.set("attr", "TEST") 230 self.assertEqual("TEST", root.get("attr"))
231
232 - def test_attribute_set_invalid(self):
233 # ElementTree accepts arbitrary attribute values 234 # lxml.etree allows only strings 235 Element = self.etree.Element 236 root = Element("root") 237 self.assertRaises(TypeError, root.set, "newattr", 5) 238 self.assertRaises(TypeError, root.set, "newattr", None)
239
240 - def test_strip_attributes(self):
241 XML = self.etree.XML 242 xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>') 243 244 root = XML(xml) 245 self.etree.strip_attributes(root, 'a') 246 self.assertEqual(_bytes('<test b="10" c="20"><x b="2"></x></test>'), 247 self._writeElement(root)) 248 249 root = XML(xml) 250 self.etree.strip_attributes(root, 'b', 'c') 251 self.assertEqual(_bytes('<test a="5"><x a="4"></x></test>'), 252 self._writeElement(root))
253
254 - def test_strip_attributes_ns(self):
255 XML = self.etree.XML 256 xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>') 257 258 root = XML(xml) 259 self.etree.strip_attributes(root, 'a') 260 self.assertEqual( 261 _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'), 262 self._writeElement(root)) 263 264 root = XML(xml) 265 self.etree.strip_attributes(root, '{http://test/ns}a', 'c') 266 self.assertEqual( 267 _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'), 268 self._writeElement(root)) 269 270 root = XML(xml) 271 self.etree.strip_attributes(root, '{http://test/ns}*') 272 self.assertEqual( 273 _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'), 274 self._writeElement(root))
275
276 - def test_strip_elements(self):
277 XML = self.etree.XML 278 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>') 279 280 root = XML(xml) 281 self.etree.strip_elements(root, 'a') 282 self.assertEqual(_bytes('<test><x></x></test>'), 283 self._writeElement(root)) 284 285 root = XML(xml) 286 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z') 287 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'), 288 self._writeElement(root)) 289 290 root = XML(xml) 291 self.etree.strip_elements(root, 'c') 292 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'), 293 self._writeElement(root))
294
295 - def test_strip_elements_ns(self):
296 XML = self.etree.XML 297 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>') 298 299 root = XML(xml) 300 self.etree.strip_elements(root, 'a') 301 self.assertEqual(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X</x>XT</test>'), 302 self._writeElement(root)) 303 304 root = XML(xml) 305 self.etree.strip_elements(root, '{urn:a}b', 'c') 306 self.assertEqual(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 307 self._writeElement(root)) 308 309 root = XML(xml) 310 self.etree.strip_elements(root, '{urn:a}*', 'c') 311 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 312 self._writeElement(root)) 313 314 root = XML(xml) 315 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False) 316 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 317 self._writeElement(root))
318
319 - def test_strip_tags(self):
320 XML = self.etree.XML 321 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>') 322 323 root = XML(xml) 324 self.etree.strip_tags(root, 'a') 325 self.assertEqual(_bytes('<test>TESTA<b>B<c></c>CT</b>BTAT<x>XA<b></b>BT<c></c>CTAT</x>XT</test>'), 326 self._writeElement(root)) 327 328 root = XML(xml) 329 self.etree.strip_tags(root, 'b', 'c', 'X', 'Y', 'Z') 330 self.assertEqual(_bytes('<test>TEST<a>ABCTBT</a>AT<x>X<a>ABTCT</a>AT</x>XT</test>'), 331 self._writeElement(root)) 332 333 root = XML(xml) 334 self.etree.strip_tags(root, 'c') 335 self.assertEqual(_bytes('<test>TEST<a>A<b>BCT</b>BT</a>AT<x>X<a>A<b></b>BTCT</a>AT</x>XT</test>'), 336 self._writeElement(root))
337
338 - def test_strip_tags_pi_comment(self):
339 XML = self.etree.XML 340 PI = self.etree.ProcessingInstruction 341 Comment = self.etree.Comment 342 xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>') 343 344 root = XML(xml) 345 self.etree.strip_tags(root, PI) 346 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->\n<?PI1?>'), 347 self._writeElement(root)) 348 349 root = XML(xml) 350 self.etree.strip_tags(root, Comment) 351 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT<?PI2?></test>\n<!--comment3-->\n<?PI1?>'), 352 self._writeElement(root)) 353 354 root = XML(xml) 355 self.etree.strip_tags(root, PI, Comment) 356 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'), 357 self._writeElement(root)) 358 359 root = XML(xml) 360 self.etree.strip_tags(root, Comment, PI) 361 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'), 362 self._writeElement(root))
363
365 XML = self.etree.XML 366 ElementTree = self.etree.ElementTree 367 PI = self.etree.ProcessingInstruction 368 Comment = self.etree.Comment 369 xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>') 370 371 root = XML(xml) 372 self.etree.strip_tags(ElementTree(root), PI) 373 self.assertEqual(_bytes('<!--comment1-->\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->'), 374 self._writeElement(root)) 375 376 root = XML(xml) 377 self.etree.strip_tags(ElementTree(root), Comment) 378 self.assertEqual(_bytes('<?PI1?>\n<test>TESTXT<?PI2?></test>\n<?PI1?>'), 379 self._writeElement(root)) 380 381 root = XML(xml) 382 self.etree.strip_tags(ElementTree(root), PI, Comment) 383 self.assertEqual(_bytes('<test>TESTXT</test>'), 384 self._writeElement(root)) 385 386 root = XML(xml) 387 self.etree.strip_tags(ElementTree(root), Comment, PI) 388 self.assertEqual(_bytes('<test>TESTXT</test>'), 389 self._writeElement(root))
390
391 - def test_strip_tags_doc_style(self):
392 XML = self.etree.XML 393 xml = _bytes(''' 394 <div> 395 <div> 396 I like <strong>sheep</strong>. 397 <br/> 398 I like lots of <strong>sheep</strong>. 399 <br/> 400 Click <a href="http://www.sheep.com">here</a> for <a href="http://www.sheep.com">those</a> sheep. 401 <br/> 402 </div> 403 </div> 404 '''.strip()) 405 406 root = XML(xml) 407 self.etree.strip_tags(root, 'a') 408 self.assertEqual(re.sub(_bytes('</?a[^>]*>'), _bytes(''), xml).replace(_bytes('<br/>'), _bytes('<br></br>')), 409 self._writeElement(root)) 410 411 root = XML(xml) 412 self.etree.strip_tags(root, 'a', 'br') 413 self.assertEqual(re.sub(_bytes('</?a[^>]*>'), _bytes(''), 414 re.sub(_bytes('<br[^>]*>'), _bytes(''), xml)), 415 self._writeElement(root))
416
417 - def test_strip_tags_ns(self):
418 XML = self.etree.XML 419 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>') 420 421 root = XML(xml) 422 self.etree.strip_tags(root, 'a') 423 self.assertEqual(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>XA<b xmlns="urn:a"></b>BT<c xmlns="urn:x"></c>CTAT</x>XT</test>'), 424 self._writeElement(root)) 425 426 root = XML(xml) 427 self.etree.strip_tags(root, '{urn:a}b', 'c') 428 self.assertEqual(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 429 self._writeElement(root)) 430 431 root = XML(xml) 432 self.etree.strip_tags(root, '{urn:a}*', 'c') 433 self.assertEqual(_bytes('<test>TESTA<b>B<c xmlns="urn:c"></c>CT</b>BTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 434 self._writeElement(root))
435
436 - def test_strip_tags_and_remove(self):
437 # previously crashed 438 HTML = self.etree.HTML 439 root = HTML(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'))[0][0] 440 self.assertEqual(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'), 441 self.etree.tostring(root)) 442 self.etree.strip_tags(root, 'b') 443 self.assertEqual(_bytes('<div><h1>title</h1> foo <p>boo</p></div>'), 444 self.etree.tostring(root)) 445 root.remove(root[0]) 446 self.assertEqual(_bytes('<div><p>boo</p></div>'), 447 self.etree.tostring(root))
448
449 - def test_pi(self):
450 # lxml.etree separates target and text 451 Element = self.etree.Element 452 SubElement = self.etree.SubElement 453 ProcessingInstruction = self.etree.ProcessingInstruction 454 455 a = Element('a') 456 a.append(ProcessingInstruction('foo', 'some more text')) 457 self.assertEqual(a[0].target, 'foo') 458 self.assertEqual(a[0].text, 'some more text')
459
460 - def test_pi_parse(self):
461 XML = self.etree.XML 462 root = XML(_bytes("<test><?mypi my test ?></test>")) 463 self.assertEqual(root[0].target, "mypi") 464 self.assertEqual(root[0].text, "my test ")
465
467 XML = self.etree.XML 468 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>")) 469 self.assertEqual(root[0].target, "mypi") 470 self.assertEqual(root[0].get('my'), "1") 471 self.assertEqual(root[0].get('test'), " abc ") 472 self.assertEqual(root[0].get('quotes'), "' '") 473 self.assertEqual(root[0].get('only'), None) 474 self.assertEqual(root[0].get('names'), None) 475 self.assertEqual(root[0].get('nope'), None)
476
478 XML = self.etree.XML 479 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>")) 480 self.assertEqual(root[0].target, "mypi") 481 self.assertEqual(root[0].attrib['my'], "1") 482 self.assertEqual(root[0].attrib['test'], " abc ") 483 self.assertEqual(root[0].attrib['quotes'], "' '") 484 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only') 485 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names') 486 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
487
488 - def test_deepcopy_pi(self):
489 # previously caused a crash 490 ProcessingInstruction = self.etree.ProcessingInstruction 491 492 a = ProcessingInstruction("PI", "ONE") 493 b = copy.deepcopy(a) 494 b.text = "ANOTHER" 495 496 self.assertEqual('ONE', a.text) 497 self.assertEqual('ANOTHER', b.text)
498
500 XML = self.etree.XML 501 tostring = self.etree.tostring 502 root = XML(_bytes("<?mypi my test ?><test/><!--comment -->")) 503 tree1 = self.etree.ElementTree(root) 504 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"), 505 tostring(tree1)) 506 507 tree2 = copy.deepcopy(tree1) 508 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"), 509 tostring(tree2)) 510 511 root2 = copy.deepcopy(tree1.getroot()) 512 self.assertEqual(_bytes("<test/>"), 513 tostring(root2))
514
516 XML = self.etree.XML 517 tostring = self.etree.tostring 518 xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') 519 root = XML(xml) 520 tree1 = self.etree.ElementTree(root) 521 self.assertEqual(xml, tostring(tree1)) 522 523 tree2 = copy.deepcopy(tree1) 524 self.assertEqual(xml, tostring(tree2)) 525 526 root2 = copy.deepcopy(tree1.getroot()) 527 self.assertEqual(_bytes("<test/>"), 528 tostring(root2))
529
530 - def test_attribute_set(self):
531 # ElementTree accepts arbitrary attribute values 532 # lxml.etree allows only strings 533 Element = self.etree.Element 534 535 root = Element("root") 536 root.set("attr", "TEST") 537 self.assertEqual("TEST", root.get("attr")) 538 self.assertRaises(TypeError, root.set, "newattr", 5)
539
540 - def test_parse_remove_comments(self):
541 fromstring = self.etree.fromstring 542 tostring = self.etree.tostring 543 XMLParser = self.etree.XMLParser 544 545 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 546 parser = XMLParser(remove_comments=True) 547 root = fromstring(xml, parser) 548 self.assertEqual( 549 _bytes('<a><b><c/></b></a>'), 550 tostring(root))
551
552 - def test_parse_remove_pis(self):
553 parse = self.etree.parse 554 tostring = self.etree.tostring 555 XMLParser = self.etree.XMLParser 556 557 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>') 558 559 f = BytesIO(xml) 560 tree = parse(f) 561 self.assertEqual( 562 xml, 563 tostring(tree)) 564 565 parser = XMLParser(remove_pis=True) 566 tree = parse(f, parser) 567 self.assertEqual( 568 _bytes('<a><b><c/></b></a>'), 569 tostring(tree))
570
572 # ET raises IOError only 573 parse = self.etree.parse 574 self.assertRaises(TypeError, parse, 'notthere.xml', object())
575
577 # ET removes comments 578 iterparse = self.etree.iterparse 579 tostring = self.etree.tostring 580 581 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 582 events = list(iterparse(f)) 583 root = events[-1][1] 584 self.assertEqual(3, len(events)) 585 self.assertEqual( 586 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 587 tostring(root))
588
589 - def test_iterparse_comments(self):
590 # ET removes comments 591 iterparse = self.etree.iterparse 592 tostring = self.etree.tostring 593 594 def name(event, el): 595 if event == 'comment': 596 return el.text 597 else: 598 return el.tag
599 600 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 601 events = list(iterparse(f, events=('end', 'comment'))) 602 root = events[-1][1] 603 self.assertEqual(6, len(events)) 604 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'], 605 [ name(*item) for item in events ]) 606 self.assertEqual( 607 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 608 tostring(root))
609
610 - def test_iterparse_pis(self):
611 # ET removes pis 612 iterparse = self.etree.iterparse 613 tostring = self.etree.tostring 614 ElementTree = self.etree.ElementTree 615 616 def name(event, el): 617 if event == 'pi': 618 return (el.target, el.text) 619 else: 620 return el.tag
621 622 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>') 623 events = list(iterparse(f, events=('end', 'pi'))) 624 root = events[-2][1] 625 self.assertEqual(8, len(events)) 626 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b', 627 ('pid','d'), 'a', ('pie','e')], 628 [ name(*item) for item in events ]) 629 self.assertEqual( 630 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'), 631 tostring(ElementTree(root))) 632
633 - def test_iterparse_remove_comments(self):
634 iterparse = self.etree.iterparse 635 tostring = self.etree.tostring 636 637 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 638 events = list(iterparse(f, remove_comments=True, 639 events=('end', 'comment'))) 640 root = events[-1][1] 641 self.assertEqual(3, len(events)) 642 self.assertEqual(['c', 'b', 'a'], 643 [ el.tag for (event, el) in events ]) 644 self.assertEqual( 645 _bytes('<a><b><c/></b></a>'), 646 tostring(root))
647
648 - def test_iterparse_broken(self):
649 iterparse = self.etree.iterparse 650 f = BytesIO('<a><b><c/></a>') 651 # ET raises ExpatError, lxml raises XMLSyntaxError 652 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
653
654 - def test_iterparse_strip(self):
655 iterparse = self.etree.iterparse 656 f = BytesIO(""" 657 <a> \n \n <b> b test </b> \n 658 659 \n\t <c> \n </c> </a> \n """) 660 iterator = iterparse(f, remove_blank_text=True) 661 text = [ (element.text, element.tail) 662 for event, element in iterator ] 663 self.assertEqual( 664 [(" b test ", None), (" \n ", None), (None, None)], 665 text)
666
667 - def test_iterparse_tag(self):
668 iterparse = self.etree.iterparse 669 f = BytesIO('<a><b><d/></b><c/></a>') 670 671 iterator = iterparse(f, tag="b", events=('start', 'end')) 672 events = list(iterator) 673 root = iterator.root 674 self.assertEqual( 675 [('start', root[0]), ('end', root[0])], 676 events)
677
678 - def test_iterparse_tag_all(self):
679 iterparse = self.etree.iterparse 680 f = BytesIO('<a><b><d/></b><c/></a>') 681 682 iterator = iterparse(f, tag="*", events=('start', 'end')) 683 events = list(iterator) 684 self.assertEqual( 685 8, 686 len(events))
687
688 - def test_iterparse_tag_ns(self):
689 iterparse = self.etree.iterparse 690 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 691 692 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end')) 693 events = list(iterator) 694 root = iterator.root 695 self.assertEqual( 696 [('start', root[0]), ('end', root[0])], 697 events)
698
699 - def test_iterparse_tag_ns_empty(self):
700 iterparse = self.etree.iterparse 701 f = BytesIO('<a><b><d/></b><c/></a>') 702 iterator = iterparse(f, tag="{}b", events=('start', 'end')) 703 events = list(iterator) 704 root = iterator.root 705 self.assertEqual( 706 [('start', root[0]), ('end', root[0])], 707 events) 708 709 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 710 iterator = iterparse(f, tag="{}b", events=('start', 'end')) 711 events = list(iterator) 712 root = iterator.root 713 self.assertEqual([], events)
714
715 - def test_iterparse_tag_ns_all(self):
716 iterparse = self.etree.iterparse 717 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 718 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end')) 719 events = list(iterator) 720 self.assertEqual(8, len(events))
721
722 - def test_iterparse_tag_ns_empty_all(self):
723 iterparse = self.etree.iterparse 724 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 725 iterator = iterparse(f, tag="{}*", events=('start', 'end')) 726 events = list(iterator) 727 self.assertEqual([], events) 728 729 f = BytesIO('<a><b><d/></b><c/></a>') 730 iterator = iterparse(f, tag="{}*", events=('start', 'end')) 731 events = list(iterator) 732 self.assertEqual(8, len(events))
733
734 - def test_iterparse_encoding_error(self):
735 text = _str('Søk på nettet') 736 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 737 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 738 ).encode('iso-8859-1') 739 740 self.assertRaises(self.etree.ParseError, 741 list, self.etree.iterparse(BytesIO(xml_latin1)))
742
743 - def test_iterparse_encoding_8bit_override(self):
744 text = _str('Søk på nettet', encoding="UTF-8") 745 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 746 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 747 ).encode('iso-8859-1') 748 749 iterator = self.etree.iterparse(BytesIO(xml_latin1), 750 encoding="iso-8859-1") 751 self.assertEqual(1, len(list(iterator))) 752 753 a = iterator.root 754 self.assertEqual(a.text, text)
755
756 - def test_iterparse_keep_cdata(self):
757 tostring = self.etree.tostring 758 f = BytesIO('<root><![CDATA[test]]></root>') 759 context = self.etree.iterparse(f, strip_cdata=False) 760 content = [ el.text for event,el in context ] 761 762 self.assertEqual(['test'], content) 763 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 764 tostring(context.root))
765
766 - def test_parser_encoding_unknown(self):
767 self.assertRaises( 768 LookupError, self.etree.XMLParser, encoding="hopefully unknown")
769
770 - def test_parser_encoding(self):
771 self.etree.XMLParser(encoding="ascii") 772 self.etree.XMLParser(encoding="utf-8") 773 self.etree.XMLParser(encoding="iso-8859-1")
774
775 - def test_feed_parser_recover(self):
776 parser = self.etree.XMLParser(recover=True) 777 778 parser.feed('<?xml version=') 779 parser.feed('"1.0"?><ro') 780 parser.feed('ot><') 781 parser.feed('a test="works"') 782 parser.feed('><othertag/></root') # <a> not closed! 783 parser.feed('>') 784 785 root = parser.close() 786 787 self.assertEqual(root.tag, "root") 788 self.assertEqual(len(root), 1) 789 self.assertEqual(root[0].tag, "a") 790 self.assertEqual(root[0].get("test"), "works") 791 self.assertEqual(len(root[0]), 1) 792 self.assertEqual(root[0][0].tag, "othertag")
793 # FIXME: would be nice to get some errors logged ... 794 #self.assertTrue(len(parser.error_log) > 0, "error log is empty") 795
796 - def test_elementtree_parser_target_type_error(self):
797 assertEqual = self.assertEqual 798 assertFalse = self.assertFalse 799 800 events = [] 801 class Target(object): 802 def start(self, tag, attrib): 803 events.append("start") 804 assertFalse(attrib) 805 assertEqual("TAG", tag)
806 def end(self, tag): 807 events.append("end") 808 assertEqual("TAG", tag) 809 def close(self): 810 return "DONE" # no Element! 811 812 parser = self.etree.XMLParser(target=Target()) 813 tree = self.etree.ElementTree() 814 815 self.assertRaises(TypeError, 816 tree.parse, BytesIO("<TAG/>"), parser=parser) 817 self.assertEqual(["start", "end"], events) 818
819 - def test_parser_target_feed_exception(self):
820 # ET doesn't call .close() on errors 821 events = [] 822 class Target(object): 823 def start(self, tag, attrib): 824 events.append("start-" + tag)
825 def end(self, tag): 826 events.append("end-" + tag) 827 if tag == 'a': 828 raise ValueError("dead and gone") 829 def data(self, data): 830 events.append("data-" + data) 831 def close(self): 832 events.append("close") 833 return "DONE" 834 835 parser = self.etree.XMLParser(target=Target()) 836 837 try: 838 parser.feed(_bytes('<root>A<a>ca</a>B</root>')) 839 done = parser.close() 840 self.fail("error expected, but parsing succeeded") 841 except ValueError: 842 done = 'value error received as expected' 843 844 self.assertEqual(["start-root", "data-A", "start-a", 845 "data-ca", "end-a", "close"], 846 events) 847
848 - def test_parser_target_fromstring_exception(self):
849 # ET doesn't call .close() on errors 850 events = [] 851 class Target(object): 852 def start(self, tag, attrib): 853 events.append("start-" + tag)
854 def end(self, tag): 855 events.append("end-" + tag) 856 if tag == 'a': 857 raise ValueError("dead and gone") 858 def data(self, data): 859 events.append("data-" + data) 860 def close(self): 861 events.append("close") 862 return "DONE" 863 864 parser = self.etree.XMLParser(target=Target()) 865 866 try: 867 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'), 868 parser=parser) 869 self.fail("error expected, but parsing succeeded") 870 except ValueError: 871 done = 'value error received as expected' 872 873 self.assertEqual(["start-root", "data-A", "start-a", 874 "data-ca", "end-a", "close"], 875 events) 876
877 - def test_parser_target_comment(self):
878 events = [] 879 class Target(object): 880 def start(self, tag, attrib): 881 events.append("start-" + tag)
882 def end(self, tag): 883 events.append("end-" + tag) 884 def data(self, data): 885 events.append("data-" + data) 886 def comment(self, text): 887 events.append("comment-" + text) 888 def close(self): 889 return "DONE" 890 891 parser = self.etree.XMLParser(target=Target()) 892 893 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')) 894 done = parser.close() 895 896 self.assertEqual("DONE", done) 897 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b", 898 "start-sub", "end-sub", "comment-c", "data-B", 899 "end-root", "comment-d"], 900 events) 901
902 - def test_parser_target_pi(self):
903 events = [] 904 class Target(object): 905 def start(self, tag, attrib): 906 events.append("start-" + tag)
907 def end(self, tag): 908 events.append("end-" + tag) 909 def data(self, data): 910 events.append("data-" + data) 911 def pi(self, target, data): 912 events.append("pi-" + target + "-" + data) 913 def close(self): 914 return "DONE" 915 916 parser = self.etree.XMLParser(target=Target()) 917 918 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>')) 919 done = parser.close() 920 921 self.assertEqual("DONE", done) 922 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b", 923 "data-B", "end-root", "pi-test-c"], 924 events) 925
926 - def test_parser_target_cdata(self):
927 events = [] 928 class Target(object): 929 def start(self, tag, attrib): 930 events.append("start-" + tag)
931 def end(self, tag): 932 events.append("end-" + tag) 933 def data(self, data): 934 events.append("data-" + data) 935 def close(self): 936 return "DONE" 937 938 parser = self.etree.XMLParser(target=Target(), 939 strip_cdata=False) 940 941 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>')) 942 done = parser.close() 943 944 self.assertEqual("DONE", done) 945 self.assertEqual(["start-root", "data-A", "start-a", 946 "data-ca", "end-a", "data-B", "end-root"], 947 events) 948
949 - def test_parser_target_recover(self):
950 events = [] 951 class Target(object): 952 def start(self, tag, attrib): 953 events.append("start-" + tag)
954 def end(self, tag): 955 events.append("end-" + tag) 956 def data(self, data): 957 events.append("data-" + data) 958 def close(self): 959 events.append("close") 960 return "DONE" 961 962 parser = self.etree.XMLParser(target=Target(), 963 recover=True) 964 965 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>')) 966 done = parser.close() 967 968 self.assertEqual("DONE", done) 969 self.assertEqual(["start-root", "data-A", "start-a", 970 "data-ca", "end-a", "data-B", 971 "end-root", "close"], 972 events) 973
974 - def test_iterwalk_tag(self):
975 iterwalk = self.etree.iterwalk 976 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 977 978 iterator = iterwalk(root, tag="b", events=('start', 'end')) 979 events = list(iterator) 980 self.assertEqual( 981 [('start', root[0]), ('end', root[0])], 982 events)
983
984 - def test_iterwalk_tag_all(self):
985 iterwalk = self.etree.iterwalk 986 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 987 988 iterator = iterwalk(root, tag="*", events=('start', 'end')) 989 events = list(iterator) 990 self.assertEqual( 991 8, 992 len(events))
993
994 - def test_iterwalk(self):
995 iterwalk = self.etree.iterwalk 996 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 997 998 events = list(iterwalk(root)) 999 self.assertEqual( 1000 [('end', root[0]), ('end', root[1]), ('end', root)], 1001 events)
1002
1003 - def test_iterwalk_start(self):
1004 iterwalk = self.etree.iterwalk 1005 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1006 1007 iterator = iterwalk(root, events=('start',)) 1008 events = list(iterator) 1009 self.assertEqual( 1010 [('start', root), ('start', root[0]), ('start', root[1])], 1011 events)
1012
1013 - def test_iterwalk_start_end(self):
1014 iterwalk = self.etree.iterwalk 1015 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1016 1017 iterator = iterwalk(root, events=('start','end')) 1018 events = list(iterator) 1019 self.assertEqual( 1020 [('start', root), ('start', root[0]), ('end', root[0]), 1021 ('start', root[1]), ('end', root[1]), ('end', root)], 1022 events)
1023
1024 - def test_iterwalk_clear(self):
1025 iterwalk = self.etree.iterwalk 1026 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1027 1028 iterator = iterwalk(root) 1029 for event, elem in iterator: 1030 elem.clear() 1031 1032 self.assertEqual(0, 1033 len(root))
1034
1035 - def test_iterwalk_attrib_ns(self):
1036 iterwalk = self.etree.iterwalk 1037 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')) 1038 1039 attr_name = '{testns}bla' 1040 events = [] 1041 iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 1042 for event, elem in iterator: 1043 events.append(event) 1044 if event == 'start': 1045 if elem.tag != '{ns1}a': 1046 elem.set(attr_name, 'value') 1047 1048 self.assertEqual( 1049 ['start-ns', 'start', 'start', 'start-ns', 'start', 1050 'end', 'end-ns', 'end', 'end', 'end-ns'], 1051 events) 1052 1053 self.assertEqual( 1054 None, 1055 root.get(attr_name)) 1056 self.assertEqual( 1057 'value', 1058 root[0].get(attr_name))
1059
1060 - def test_iterwalk_getiterator(self):
1061 iterwalk = self.etree.iterwalk 1062 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 1063 1064 counts = [] 1065 for event, elem in iterwalk(root): 1066 counts.append(len(list(elem.getiterator()))) 1067 self.assertEqual( 1068 [1,2,1,4], 1069 counts)
1070
1071 - def test_resolve_string_dtd(self):
1072 parse = self.etree.parse 1073 parser = self.etree.XMLParser(dtd_validation=True) 1074 assertEqual = self.assertEqual 1075 test_url = _str("__nosuch.dtd") 1076 1077 class MyResolver(self.etree.Resolver): 1078 def resolve(self, url, id, context): 1079 assertEqual(url, test_url) 1080 return self.resolve_string( 1081 _str('''<!ENTITY myentity "%s"> 1082 <!ELEMENT doc ANY>''') % url, context)
1083 1084 parser.resolvers.add(MyResolver()) 1085 1086 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1087 tree = parse(StringIO(xml), parser) 1088 root = tree.getroot() 1089 self.assertEqual(root.text, test_url) 1090
1091 - def test_resolve_bytes_dtd(self):
1092 parse = self.etree.parse 1093 parser = self.etree.XMLParser(dtd_validation=True) 1094 assertEqual = self.assertEqual 1095 test_url = _str("__nosuch.dtd") 1096 1097 class MyResolver(self.etree.Resolver): 1098 def resolve(self, url, id, context): 1099 assertEqual(url, test_url) 1100 return self.resolve_string( 1101 (_str('''<!ENTITY myentity "%s"> 1102 <!ELEMENT doc ANY>''') % url).encode('utf-8'), 1103 context)
1104 1105 parser.resolvers.add(MyResolver()) 1106 1107 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1108 tree = parse(StringIO(xml), parser) 1109 root = tree.getroot() 1110 self.assertEqual(root.text, test_url) 1111
1112 - def test_resolve_filelike_dtd(self):
1113 parse = self.etree.parse 1114 parser = self.etree.XMLParser(dtd_validation=True) 1115 assertEqual = self.assertEqual 1116 test_url = _str("__nosuch.dtd") 1117 1118 class MyResolver(self.etree.Resolver): 1119 def resolve(self, url, id, context): 1120 assertEqual(url, test_url) 1121 return self.resolve_file( 1122 SillyFileLike( 1123 _str('''<!ENTITY myentity "%s"> 1124 <!ELEMENT doc ANY>''') % url), context)
1125 1126 parser.resolvers.add(MyResolver()) 1127 1128 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1129 tree = parse(StringIO(xml), parser) 1130 root = tree.getroot() 1131 self.assertEqual(root.text, test_url) 1132
1133 - def test_resolve_filename_dtd(self):
1134 parse = self.etree.parse 1135 parser = self.etree.XMLParser(attribute_defaults=True) 1136 assertEqual = self.assertEqual 1137 test_url = _str("__nosuch.dtd") 1138 1139 class MyResolver(self.etree.Resolver): 1140 def resolve(self, url, id, context): 1141 assertEqual(url, test_url) 1142 return self.resolve_filename( 1143 fileInTestDir('test.dtd'), context)
1144 1145 parser.resolvers.add(MyResolver()) 1146 1147 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1148 tree = parse(StringIO(xml), parser) 1149 root = tree.getroot() 1150 self.assertEqual( 1151 root.attrib, {'default': 'valueA'}) 1152 self.assertEqual( 1153 root[0].attrib, {'default': 'valueB'}) 1154
1155 - def test_resolve_filename_dtd_relative(self):
1156 parse = self.etree.parse 1157 parser = self.etree.XMLParser(attribute_defaults=True) 1158 assertEqual = self.assertEqual 1159 test_url = _str("__nosuch.dtd") 1160 1161 class MyResolver(self.etree.Resolver): 1162 def resolve(self, url, id, context): 1163 assertEqual(url, fileInTestDir(test_url)) 1164 return self.resolve_filename( 1165 fileInTestDir('test.dtd'), context)
1166 1167 parser.resolvers.add(MyResolver()) 1168 1169 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1170 tree = parse(StringIO(xml), parser, 1171 base_url=fileInTestDir('__test.xml')) 1172 root = tree.getroot() 1173 self.assertEqual( 1174 root.attrib, {'default': 'valueA'}) 1175 self.assertEqual( 1176 root[0].attrib, {'default': 'valueB'}) 1177
1178 - def test_resolve_file_dtd(self):
1179 parse = self.etree.parse 1180 parser = self.etree.XMLParser(attribute_defaults=True) 1181 assertEqual = self.assertEqual 1182 test_url = _str("__nosuch.dtd") 1183 1184 class MyResolver(self.etree.Resolver): 1185 def resolve(self, url, id, context): 1186 assertEqual(url, test_url) 1187 return self.resolve_file( 1188 open(fileInTestDir('test.dtd'), 'rb'), context)
1189 1190 parser.resolvers.add(MyResolver()) 1191 1192 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1193 tree = parse(StringIO(xml), parser) 1194 root = tree.getroot() 1195 self.assertEqual( 1196 root.attrib, {'default': 'valueA'}) 1197 self.assertEqual( 1198 root[0].attrib, {'default': 'valueB'}) 1199
1200 - def test_resolve_empty(self):
1201 parse = self.etree.parse 1202 parser = self.etree.XMLParser(load_dtd=True) 1203 assertEqual = self.assertEqual 1204 test_url = _str("__nosuch.dtd") 1205 1206 class check(object): 1207 resolved = False
1208 1209 class MyResolver(self.etree.Resolver): 1210 def resolve(self, url, id, context): 1211 assertEqual(url, test_url) 1212 check.resolved = True 1213 return self.resolve_empty(context) 1214 1215 parser.resolvers.add(MyResolver()) 1216 1217 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1218 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 1219 self.assertTrue(check.resolved) 1220
1221 - def test_resolve_error(self):
1222 parse = self.etree.parse 1223 parser = self.etree.XMLParser(dtd_validation=True) 1224 1225 class _LocalException(Exception): 1226 pass
1227 1228 class MyResolver(self.etree.Resolver): 1229 def resolve(self, url, id, context): 1230 raise _LocalException 1231 1232 parser.resolvers.add(MyResolver()) 1233 1234 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 1235 self.assertRaises(_LocalException, parse, BytesIO(xml), parser) 1236 1237 if etree.LIBXML_VERSION > (2,6,20):
1238 - def test_entity_parse(self):
1239 parse = self.etree.parse 1240 tostring = self.etree.tostring 1241 parser = self.etree.XMLParser(resolve_entities=False) 1242 Entity = self.etree.Entity 1243 1244 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>') 1245 tree = parse(BytesIO(xml), parser) 1246 root = tree.getroot() 1247 self.assertEqual(root[0].tag, Entity) 1248 self.assertEqual(root[0].text, "&myentity;") 1249 self.assertEqual(root[0].tail, None) 1250 self.assertEqual(root[0].name, "myentity") 1251 1252 self.assertEqual(_bytes('<doc>&myentity;</doc>'), 1253 tostring(root))
1254
1255 - def test_entity_restructure(self):
1256 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp "&#160;"> ]> 1257 <root> 1258 <child1/> 1259 <child2/> 1260 <child3>&nbsp;</child3> 1261 </root>''') 1262 1263 parser = self.etree.XMLParser(resolve_entities=False) 1264 root = etree.fromstring(xml, parser) 1265 self.assertEqual([ el.tag for el in root ], 1266 ['child1', 'child2', 'child3']) 1267 1268 root[0] = root[-1] 1269 self.assertEqual([ el.tag for el in root ], 1270 ['child3', 'child2']) 1271 self.assertEqual(root[0][0].text, '&nbsp;') 1272 self.assertEqual(root[0][0].name, 'nbsp')
1273
1274 - def test_entity_append(self):
1275 Entity = self.etree.Entity 1276 Element = self.etree.Element 1277 tostring = self.etree.tostring 1278 1279 root = Element("root") 1280 root.append( Entity("test") ) 1281 1282 self.assertEqual(root[0].tag, Entity) 1283 self.assertEqual(root[0].text, "&test;") 1284 self.assertEqual(root[0].tail, None) 1285 self.assertEqual(root[0].name, "test") 1286 1287 self.assertEqual(_bytes('<root>&test;</root>'), 1288 tostring(root))
1289
1290 - def test_entity_values(self):
1291 Entity = self.etree.Entity 1292 self.assertEqual(Entity("test").text, '&test;') 1293 self.assertEqual(Entity("#17683").text, '&#17683;') 1294 self.assertEqual(Entity("#x1768").text, '&#x1768;') 1295 self.assertEqual(Entity("#x98AF").text, '&#x98AF;')
1296
1297 - def test_entity_error(self):
1298 Entity = self.etree.Entity 1299 self.assertRaises(ValueError, Entity, 'a b c') 1300 self.assertRaises(ValueError, Entity, 'a,b') 1301 self.assertRaises(ValueError, Entity, 'a\0b') 1302 self.assertRaises(ValueError, Entity, '#abc') 1303 self.assertRaises(ValueError, Entity, '#xxyz')
1304
1305 - def test_cdata(self):
1306 CDATA = self.etree.CDATA 1307 Element = self.etree.Element 1308 tostring = self.etree.tostring 1309 1310 root = Element("root") 1311 root.text = CDATA('test') 1312 1313 self.assertEqual('test', 1314 root.text) 1315 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1316 tostring(root))
1317
1318 - def test_cdata_type(self):
1319 CDATA = self.etree.CDATA 1320 Element = self.etree.Element 1321 root = Element("root") 1322 1323 root.text = CDATA("test") 1324 self.assertEqual('test', root.text) 1325 1326 root.text = CDATA(_str("test")) 1327 self.assertEqual('test', root.text) 1328 1329 self.assertRaises(TypeError, CDATA, 1)
1330
1331 - def test_cdata_errors(self):
1332 CDATA = self.etree.CDATA 1333 Element = self.etree.Element 1334 1335 root = Element("root") 1336 cdata = CDATA('test') 1337 1338 self.assertRaises(TypeError, 1339 setattr, root, 'tail', cdata) 1340 self.assertRaises(TypeError, 1341 root.set, 'attr', cdata) 1342 self.assertRaises(TypeError, 1343 operator.setitem, root.attrib, 'attr', cdata)
1344
1345 - def test_cdata_parser(self):
1346 tostring = self.etree.tostring 1347 parser = self.etree.XMLParser(strip_cdata=False) 1348 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1349 1350 self.assertEqual('test', root.text) 1351 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1352 tostring(root))
1353
1354 - def test_cdata_xpath(self):
1355 tostring = self.etree.tostring 1356 parser = self.etree.XMLParser(strip_cdata=False) 1357 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1358 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1359 tostring(root)) 1360 1361 self.assertEqual(['test'], root.xpath('//text()'))
1362 1363 # TypeError in etree, AssertionError in ElementTree;
1364 - def test_setitem_assert(self):
1365 Element = self.etree.Element 1366 SubElement = self.etree.SubElement 1367 1368 a = Element('a') 1369 b = SubElement(a, 'b') 1370 1371 self.assertRaises(TypeError, 1372 a.__setitem__, 0, 'foo')
1373
1374 - def test_append_error(self):
1375 Element = self.etree.Element 1376 root = Element('root') 1377 # raises AssertionError in ElementTree 1378 self.assertRaises(TypeError, root.append, None) 1379 self.assertRaises(TypeError, root.extend, [None]) 1380 self.assertRaises(TypeError, root.extend, [Element('one'), None]) 1381 self.assertEqual('one', root[0].tag)
1382
1383 - def test_addnext(self):
1384 Element = self.etree.Element 1385 SubElement = self.etree.SubElement 1386 root = Element('root') 1387 SubElement(root, 'a') 1388 SubElement(root, 'b') 1389 1390 self.assertEqual(['a', 'b'], 1391 [c.tag for c in root]) 1392 root[1].addnext(root[0]) 1393 self.assertEqual(['b', 'a'], 1394 [c.tag for c in root])
1395
1396 - def test_addprevious(self):
1397 Element = self.etree.Element 1398 SubElement = self.etree.SubElement 1399 root = Element('root') 1400 SubElement(root, 'a') 1401 SubElement(root, 'b') 1402 1403 self.assertEqual(['a', 'b'], 1404 [c.tag for c in root]) 1405 root[0].addprevious(root[1]) 1406 self.assertEqual(['b', 'a'], 1407 [c.tag for c in root])
1408
1409 - def test_addnext_root(self):
1410 Element = self.etree.Element 1411 a = Element('a') 1412 b = Element('b') 1413 self.assertRaises(TypeError, a.addnext, b)
1414
1415 - def test_addnext_root(self):
1416 Element = self.etree.Element 1417 a = Element('a') 1418 b = Element('b') 1419 self.assertRaises(TypeError, a.addnext, b)
1420
1421 - def test_addprevious_pi(self):
1422 Element = self.etree.Element 1423 SubElement = self.etree.SubElement 1424 PI = self.etree.PI 1425 root = Element('root') 1426 SubElement(root, 'a') 1427 pi = PI('TARGET', 'TEXT') 1428 pi.tail = "TAIL" 1429 1430 self.assertEqual(_bytes('<root><a></a></root>'), 1431 self._writeElement(root)) 1432 root[0].addprevious(pi) 1433 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 1434 self._writeElement(root))
1435
1436 - def test_addprevious_root_pi(self):
1437 Element = self.etree.Element 1438 PI = self.etree.PI 1439 root = Element('root') 1440 pi = PI('TARGET', 'TEXT') 1441 pi.tail = "TAIL" 1442 1443 self.assertEqual(_bytes('<root></root>'), 1444 self._writeElement(root)) 1445 root.addprevious(pi) 1446 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'), 1447 self._writeElement(root))
1448
1449 - def test_addnext_pi(self):
1450 Element = self.etree.Element 1451 SubElement = self.etree.SubElement 1452 PI = self.etree.PI 1453 root = Element('root') 1454 SubElement(root, 'a') 1455 pi = PI('TARGET', 'TEXT') 1456 pi.tail = "TAIL" 1457 1458 self.assertEqual(_bytes('<root><a></a></root>'), 1459 self._writeElement(root)) 1460 root[0].addnext(pi) 1461 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 1462 self._writeElement(root))
1463
1464 - def test_addnext_root_pi(self):
1465 Element = self.etree.Element 1466 PI = self.etree.PI 1467 root = Element('root') 1468 pi = PI('TARGET', 'TEXT') 1469 pi.tail = "TAIL" 1470 1471 self.assertEqual(_bytes('<root></root>'), 1472 self._writeElement(root)) 1473 root.addnext(pi) 1474 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'), 1475 self._writeElement(root))
1476
1477 - def test_addnext_comment(self):
1478 Element = self.etree.Element 1479 SubElement = self.etree.SubElement 1480 Comment = self.etree.Comment 1481 root = Element('root') 1482 SubElement(root, 'a') 1483 comment = Comment('TEXT ') 1484 comment.tail = "TAIL" 1485 1486 self.assertEqual(_bytes('<root><a></a></root>'), 1487 self._writeElement(root)) 1488 root[0].addnext(comment) 1489 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 1490 self._writeElement(root))
1491
1492 - def test_addnext_root_comment(self):
1493 Element = self.etree.Element 1494 Comment = self.etree.Comment 1495 root = Element('root') 1496 comment = Comment('TEXT ') 1497 comment.tail = "TAIL" 1498 1499 self.assertEqual(_bytes('<root></root>'), 1500 self._writeElement(root)) 1501 root.addnext(comment) 1502 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'), 1503 self._writeElement(root))
1504
1505 - def test_addprevious_comment(self):
1506 Element = self.etree.Element 1507 SubElement = self.etree.SubElement 1508 Comment = self.etree.Comment 1509 root = Element('root') 1510 SubElement(root, 'a') 1511 comment = Comment('TEXT ') 1512 comment.tail = "TAIL" 1513 1514 self.assertEqual(_bytes('<root><a></a></root>'), 1515 self._writeElement(root)) 1516 root[0].addprevious(comment) 1517 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 1518 self._writeElement(root))
1519
1520 - def test_addprevious_root_comment(self):
1521 Element = self.etree.Element 1522 Comment = self.etree.Comment 1523 root = Element('root') 1524 comment = Comment('TEXT ') 1525 comment.tail = "TAIL" 1526 1527 self.assertEqual(_bytes('<root></root>'), 1528 self._writeElement(root)) 1529 root.addprevious(comment) 1530 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'), 1531 self._writeElement(root))
1532 1533 # ET's Elements have items() and key(), but not values()
1534 - def test_attribute_values(self):
1535 XML = self.etree.XML 1536 1537 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 1538 values = root.values() 1539 values.sort() 1540 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1541 1542 # gives error in ElementTree
1543 - def test_comment_empty(self):
1544 Element = self.etree.Element 1545 Comment = self.etree.Comment 1546 1547 a = Element('a') 1548 a.append(Comment()) 1549 self.assertEqual( 1550 _bytes('<a><!----></a>'), 1551 self._writeElement(a))
1552 1553 # ElementTree ignores comments
1554 - def test_comment_parse_empty(self):
1555 ElementTree = self.etree.ElementTree 1556 tostring = self.etree.tostring 1557 1558 xml = _bytes('<a><b/><!----><c/></a>') 1559 f = BytesIO(xml) 1560 doc = ElementTree(file=f) 1561 a = doc.getroot() 1562 self.assertEqual( 1563 '', 1564 a[1].text) 1565 self.assertEqual( 1566 xml, 1567 tostring(a))
1568 1569 # ElementTree ignores comments
1570 - def test_comment_no_proxy_yet(self):
1571 ElementTree = self.etree.ElementTree 1572 1573 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 1574 doc = ElementTree(file=f) 1575 a = doc.getroot() 1576 self.assertEqual( 1577 ' hoi ', 1578 a[1].text)
1579 1580 # does not raise an exception in ElementTree
1581 - def test_comment_immutable(self):
1582 Element = self.etree.Element 1583 Comment = self.etree.Comment 1584 1585 c = Comment() 1586 el = Element('myel') 1587 1588 self.assertRaises(TypeError, c.append, el) 1589 self.assertRaises(TypeError, c.insert, 0, el) 1590 self.assertRaises(TypeError, c.set, "myattr", "test")
1591 1592 # test passing 'None' to dump
1593 - def test_dump_none(self):
1594 self.assertRaises(TypeError, self.etree.dump, None)
1595
1596 - def test_prefix(self):
1597 ElementTree = self.etree.ElementTree 1598 1599 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 1600 doc = ElementTree(file=f) 1601 a = doc.getroot() 1602 self.assertEqual( 1603 None, 1604 a.prefix) 1605 self.assertEqual( 1606 'foo', 1607 a[0].prefix)
1608
1609 - def test_prefix_default_ns(self):
1610 ElementTree = self.etree.ElementTree 1611 1612 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 1613 doc = ElementTree(file=f) 1614 a = doc.getroot() 1615 self.assertEqual( 1616 None, 1617 a.prefix) 1618 self.assertEqual( 1619 None, 1620 a[0].prefix)
1621
1622 - def test_getparent(self):
1623 Element = self.etree.Element 1624 SubElement = self.etree.SubElement 1625 1626 a = Element('a') 1627 b = SubElement(a, 'b') 1628 c = SubElement(a, 'c') 1629 d = SubElement(b, 'd') 1630 self.assertEqual( 1631 None, 1632 a.getparent()) 1633 self.assertEqual( 1634 a, 1635 b.getparent()) 1636 self.assertEqual( 1637 b.getparent(), 1638 c.getparent()) 1639 self.assertEqual( 1640 b, 1641 d.getparent())
1642
1643 - def test_iterchildren(self):
1644 XML = self.etree.XML 1645 1646 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1647 result = [] 1648 for el in root.iterchildren(): 1649 result.append(el.tag) 1650 self.assertEqual(['one', 'two', 'three'], result)
1651
1652 - def test_iterchildren_reversed(self):
1653 XML = self.etree.XML 1654 1655 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1656 result = [] 1657 for el in root.iterchildren(reversed=True): 1658 result.append(el.tag) 1659 self.assertEqual(['three', 'two', 'one'], result)
1660
1661 - def test_iterchildren_tag(self):
1662 XML = self.etree.XML 1663 1664 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1665 result = [] 1666 for el in root.iterchildren(tag='two'): 1667 result.append(el.text) 1668 self.assertEqual(['Two', 'Bla'], result)
1669
1670 - def test_iterchildren_tag_reversed(self):
1671 XML = self.etree.XML 1672 1673 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1674 result = [] 1675 for el in root.iterchildren(reversed=True, tag='two'): 1676 result.append(el.text) 1677 self.assertEqual(['Bla', 'Two'], result)
1678
1679 - def test_iterchildren_tag_multiple(self):
1680 XML = self.etree.XML 1681 1682 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1683 result = [] 1684 for el in root.iterchildren(tag=['two', 'three']): 1685 result.append(el.text) 1686 self.assertEqual(['Two', 'Bla', None], result)
1687
1688 - def test_iterchildren_tag_multiple_reversed(self):
1689 XML = self.etree.XML 1690 1691 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1692 result = [] 1693 for el in root.iterchildren(reversed=True, tag=['two', 'three']): 1694 result.append(el.text) 1695 self.assertEqual([None, 'Bla', 'Two'], result)
1696
1697 - def test_iterancestors(self):
1698 Element = self.etree.Element 1699 SubElement = self.etree.SubElement 1700 1701 a = Element('a') 1702 b = SubElement(a, 'b') 1703 c = SubElement(a, 'c') 1704 d = SubElement(b, 'd') 1705 self.assertEqual( 1706 [], 1707 list(a.iterancestors())) 1708 self.assertEqual( 1709 [a], 1710 list(b.iterancestors())) 1711 self.assertEqual( 1712 [a], 1713 list(c.iterancestors())) 1714 self.assertEqual( 1715 [b, a], 1716 list(d.iterancestors()))
1717
1718 - def test_iterancestors_tag(self):
1719 Element = self.etree.Element 1720 SubElement = self.etree.SubElement 1721 1722 a = Element('a') 1723 b = SubElement(a, 'b') 1724 c = SubElement(a, 'c') 1725 d = SubElement(b, 'd') 1726 self.assertEqual( 1727 [a], 1728 list(d.iterancestors(tag='a'))) 1729 self.assertEqual( 1730 [b, a], 1731 list(d.iterancestors(tag='*')))
1732
1733 - def test_iterancestors_tag_multiple(self):
1734 Element = self.etree.Element 1735 SubElement = self.etree.SubElement 1736 1737 a = Element('a') 1738 b = SubElement(a, 'b') 1739 c = SubElement(a, 'c') 1740 d = SubElement(b, 'd') 1741 self.assertEqual( 1742 [b, a], 1743 list(d.iterancestors(tag=('a', 'b')))) 1744 self.assertEqual( 1745 [], 1746 list(d.iterancestors(tag=('w', 'x', 'y', 'z')))) 1747 self.assertEqual( 1748 [], 1749 list(d.iterancestors(tag=('d', 'x')))) 1750 self.assertEqual( 1751 [b, a], 1752 list(d.iterancestors(tag=('b', '*')))) 1753 self.assertEqual( 1754 [b], 1755 list(d.iterancestors(tag=('b', 'c'))))
1756
1757 - def test_iterdescendants(self):
1758 Element = self.etree.Element 1759 SubElement = self.etree.SubElement 1760 1761 a = Element('a') 1762 b = SubElement(a, 'b') 1763 c = SubElement(a, 'c') 1764 d = SubElement(b, 'd') 1765 e = SubElement(c, 'e') 1766 1767 self.assertEqual( 1768 [b, d, c, e], 1769 list(a.iterdescendants())) 1770 self.assertEqual( 1771 [], 1772 list(d.iterdescendants()))
1773
1774 - def test_iterdescendants_tag(self):
1775 Element = self.etree.Element 1776 SubElement = self.etree.SubElement 1777 1778 a = Element('a') 1779 b = SubElement(a, 'b') 1780 c = SubElement(a, 'c') 1781 d = SubElement(b, 'd') 1782 e = SubElement(c, 'e') 1783 1784 self.assertEqual( 1785 [], 1786 list(a.iterdescendants('a'))) 1787 a2 = SubElement(e, 'a') 1788 self.assertEqual( 1789 [a2], 1790 list(a.iterdescendants('a'))) 1791 self.assertEqual( 1792 [a2], 1793 list(c.iterdescendants('a')))
1794
1795 - def test_iterdescendants_tag_multiple(self):
1796 Element = self.etree.Element 1797 SubElement = self.etree.SubElement 1798 1799 a = Element('a') 1800 b = SubElement(a, 'b') 1801 c = SubElement(a, 'c') 1802 d = SubElement(b, 'd') 1803 e = SubElement(c, 'e') 1804 1805 self.assertEqual( 1806 [b, e], 1807 list(a.iterdescendants(tag=('a', 'b', 'e')))) 1808 a2 = SubElement(e, 'a') 1809 self.assertEqual( 1810 [b, a2], 1811 list(a.iterdescendants(tag=('a', 'b')))) 1812 self.assertEqual( 1813 [], 1814 list(c.iterdescendants(tag=('x', 'y', 'z')))) 1815 self.assertEqual( 1816 [b, d, c, e, a2], 1817 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
1818
1819 - def test_getroottree(self):
1820 Element = self.etree.Element 1821 SubElement = self.etree.SubElement 1822 1823 a = Element('a') 1824 b = SubElement(a, 'b') 1825 c = SubElement(a, 'c') 1826 d = SubElement(b, 'd') 1827 self.assertEqual( 1828 a, 1829 a.getroottree().getroot()) 1830 self.assertEqual( 1831 a, 1832 b.getroottree().getroot()) 1833 self.assertEqual( 1834 a, 1835 d.getroottree().getroot())
1836
1837 - def test_getnext(self):
1838 Element = self.etree.Element 1839 SubElement = self.etree.SubElement 1840 1841 a = Element('a') 1842 b = SubElement(a, 'b') 1843 c = SubElement(a, 'c') 1844 self.assertEqual( 1845 None, 1846 a.getnext()) 1847 self.assertEqual( 1848 c, 1849 b.getnext()) 1850 self.assertEqual( 1851 None, 1852 c.getnext())
1853
1854 - def test_getprevious(self):
1855 Element = self.etree.Element 1856 SubElement = self.etree.SubElement 1857 1858 a = Element('a') 1859 b = SubElement(a, 'b') 1860 c = SubElement(a, 'c') 1861 d = SubElement(b, 'd') 1862 self.assertEqual( 1863 None, 1864 a.getprevious()) 1865 self.assertEqual( 1866 b, 1867 c.getprevious()) 1868 self.assertEqual( 1869 None, 1870 b.getprevious())
1871
1872 - def test_itersiblings(self):
1873 Element = self.etree.Element 1874 SubElement = self.etree.SubElement 1875 1876 a = Element('a') 1877 b = SubElement(a, 'b') 1878 c = SubElement(a, 'c') 1879 d = SubElement(b, 'd') 1880 self.assertEqual( 1881 [], 1882 list(a.itersiblings())) 1883 self.assertEqual( 1884 [c], 1885 list(b.itersiblings())) 1886 self.assertEqual( 1887 [], 1888 list(c.itersiblings())) 1889 self.assertEqual( 1890 [b], 1891 list(c.itersiblings(preceding=True))) 1892 self.assertEqual( 1893 [], 1894 list(b.itersiblings(preceding=True)))
1895
1896 - def test_itersiblings_tag(self):
1897 Element = self.etree.Element 1898 SubElement = self.etree.SubElement 1899 1900 a = Element('a') 1901 b = SubElement(a, 'b') 1902 c = SubElement(a, 'c') 1903 d = SubElement(b, 'd') 1904 self.assertEqual( 1905 [], 1906 list(a.itersiblings(tag='XXX'))) 1907 self.assertEqual( 1908 [c], 1909 list(b.itersiblings(tag='c'))) 1910 self.assertEqual( 1911 [c], 1912 list(b.itersiblings(tag='*'))) 1913 self.assertEqual( 1914 [b], 1915 list(c.itersiblings(preceding=True, tag='b'))) 1916 self.assertEqual( 1917 [], 1918 list(c.itersiblings(preceding=True, tag='c')))
1919
1920 - def test_itersiblings_tag_multiple(self):
1921 Element = self.etree.Element 1922 SubElement = self.etree.SubElement 1923 1924 a = Element('a') 1925 b = SubElement(a, 'b') 1926 c = SubElement(a, 'c') 1927 d = SubElement(b, 'd') 1928 e = SubElement(a, 'e') 1929 self.assertEqual( 1930 [], 1931 list(a.itersiblings(tag=('XXX', 'YYY')))) 1932 self.assertEqual( 1933 [c, e], 1934 list(b.itersiblings(tag=('c', 'd', 'e')))) 1935 self.assertEqual( 1936 [b], 1937 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd')))) 1938 self.assertEqual( 1939 [c, b], 1940 list(e.itersiblings(preceding=True, tag=('c', '*'))))
1941
1942 - def test_parseid(self):
1943 parseid = self.etree.parseid 1944 XML = self.etree.XML 1945 xml_text = _bytes(''' 1946 <!DOCTYPE document [ 1947 <!ELEMENT document (h1,p)*> 1948 <!ELEMENT h1 (#PCDATA)> 1949 <!ATTLIST h1 myid ID #REQUIRED> 1950 <!ELEMENT p (#PCDATA)> 1951 <!ATTLIST p someid ID #REQUIRED> 1952 ]> 1953 <document> 1954 <h1 myid="chapter1">...</h1> 1955 <p id="note1" class="note">...</p> 1956 <p>Regular paragraph.</p> 1957 <p xml:id="xmlid">XML:ID paragraph.</p> 1958 <p someid="warn1" class="warning">...</p> 1959 </document> 1960 ''') 1961 1962 tree, dic = parseid(BytesIO(xml_text)) 1963 root = tree.getroot() 1964 root2 = XML(xml_text) 1965 self.assertEqual(self._writeElement(root), 1966 self._writeElement(root2)) 1967 expected = { 1968 "chapter1" :