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

Source Code for Module lxml.tests.test_xslt

   1  # -*- coding: utf-8 -*- 
   2   
   3  """ 
   4  Test cases related to XSLT processing 
   5  """ 
   6   
   7  import unittest, copy, sys, os.path 
   8   
   9  this_dir = os.path.dirname(__file__) 
  10  if this_dir not in sys.path: 
  11      sys.path.insert(0, this_dir) # needed for Py3 
  12   
  13  is_python3 = sys.version_info[0] >= 3 
  14   
  15  try: 
  16      unicode 
  17  except NameError: # Python 3 
  18      unicode = str 
  19   
  20  try: 
  21      basestring 
  22  except NameError: # Python 3 
  23      basestring = str 
  24   
  25  from common_imports import etree, BytesIO, HelperTestCase, fileInTestDir 
  26  from common_imports import doctest, _bytes, _str, make_doctest, skipif 
  27   
28 -class ETreeXSLTTestCase(HelperTestCase):
29 """XSLT tests etree""" 30
31 - def test_xslt(self):
32 tree = self.parse('<a><b>B</b><c>C</c></a>') 33 style = self.parse('''\ 34 <xsl:stylesheet version="1.0" 35 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 36 <xsl:template match="*" /> 37 <xsl:template match="/"> 38 <foo><xsl:value-of select="/a/b/text()" /></foo> 39 </xsl:template> 40 </xsl:stylesheet>''') 41 42 st = etree.XSLT(style) 43 res = st(tree) 44 self.assertEqual('''\ 45 <?xml version="1.0"?> 46 <foo>B</foo> 47 ''', 48 str(res))
49
51 self.assertRaises(ValueError, etree.XSLT, etree.ElementTree())
52
53 - def test_xslt_input_none(self):
54 self.assertRaises(TypeError, etree.XSLT, None)
55 56 if False and etree.LIBXSLT_VERSION >= (1,1,15): 57 # earlier versions generate no error 58 if etree.LIBXSLT_VERSION > (1,1,17):
60 style = self.parse('''\ 61 <xsl:stylesheet version="1.0" 62 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 63 <xsl:stylesheet /> 64 </xsl:stylesheet>''') 65 66 self.assertRaises( 67 etree.XSLTParseError, etree.XSLT, style)
68
69 - def test_xslt_copy(self):
70 tree = self.parse('<a><b>B</b><c>C</c></a>') 71 style = self.parse('''\ 72 <xsl:stylesheet version="1.0" 73 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 74 <xsl:template match="*" /> 75 <xsl:template match="/"> 76 <foo><xsl:value-of select="/a/b/text()" /></foo> 77 </xsl:template> 78 </xsl:stylesheet>''') 79 80 transform = etree.XSLT(style) 81 res = transform(tree) 82 self.assertEqual('''\ 83 <?xml version="1.0"?> 84 <foo>B</foo> 85 ''', 86 str(res)) 87 88 transform_copy = copy.deepcopy(transform) 89 res = transform_copy(tree) 90 self.assertEqual('''\ 91 <?xml version="1.0"?> 92 <foo>B</foo> 93 ''', 94 str(res)) 95 96 transform = etree.XSLT(style) 97 res = transform(tree) 98 self.assertEqual('''\ 99 <?xml version="1.0"?> 100 <foo>B</foo> 101 ''', 102 str(res))
103
104 - def test_xslt_utf8(self):
105 tree = self.parse(_bytes('<a><b>\\uF8D2</b><c>\\uF8D2</c></a>' 106 ).decode("unicode_escape")) 107 style = self.parse('''\ 108 <xsl:stylesheet version="1.0" 109 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 110 <xsl:output encoding="UTF-8"/> 111 <xsl:template match="/"> 112 <foo><xsl:value-of select="/a/b/text()" /></foo> 113 </xsl:template> 114 </xsl:stylesheet>''') 115 116 st = etree.XSLT(style) 117 res = st(tree) 118 expected = _bytes('''\ 119 <?xml version="1.0" encoding="UTF-8"?> 120 <foo>\\uF8D2</foo> 121 ''').decode("unicode_escape") 122 if is_python3: 123 self.assertEqual(expected, 124 str(bytes(res), 'UTF-8')) 125 else: 126 self.assertEqual(expected, 127 unicode(str(res), 'UTF-8'))
128
129 - def test_xslt_encoding(self):
130 tree = self.parse(_bytes('<a><b>\\uF8D2</b><c>\\uF8D2</c></a>' 131 ).decode("unicode_escape")) 132 style = self.parse('''\ 133 <xsl:stylesheet version="1.0" 134 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 135 <xsl:output encoding="UTF-16"/> 136 <xsl:template match="/"> 137 <foo><xsl:value-of select="/a/b/text()" /></foo> 138 </xsl:template> 139 </xsl:stylesheet>''') 140 141 st = etree.XSLT(style) 142 res = st(tree) 143 expected = _bytes('''\ 144 <?xml version="1.0" encoding="UTF-16"?> 145 <foo>\\uF8D2</foo> 146 ''').decode("unicode_escape") 147 if is_python3: 148 self.assertEqual(expected, 149 str(bytes(res), 'UTF-16')) 150 else: 151 self.assertEqual(expected, 152 unicode(str(res), 'UTF-16'))
153
155 tree = self.parse(_bytes('<a><b>\\uF8D2</b><c>\\uF8D2</c></a>' 156 ).decode("unicode_escape")) 157 style = self.parse('''\ 158 <xsl:stylesheet version="1.0" 159 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 160 <xsl:output encoding="UTF-8"/> 161 <xsl:template match="/"> 162 <foo><xsl:value-of select="/a/b/text()" /></foo> 163 </xsl:template> 164 </xsl:stylesheet>''') 165 166 st = etree.XSLT(style) 167 res = st(tree) 168 expected = _bytes("""\ 169 <?xml version='1.0' encoding='UTF-16'?>\ 170 <foo>\\uF8D2</foo>""").decode("unicode_escape") 171 172 f = BytesIO() 173 res.write(f, encoding='UTF-16') 174 if is_python3: 175 result = str(f.getvalue(), 'UTF-16').replace('\n', '') 176 else: 177 result = unicode(str(f.getvalue()), 'UTF-16').replace('\n', '') 178 self.assertEqual(expected, result)
179
180 - def test_xslt_unicode(self):
181 tree = self.parse(_bytes('<a><b>\\uF8D2</b><c>\\uF8D2</c></a>' 182 ).decode("unicode_escape")) 183 style = self.parse('''\ 184 <xsl:stylesheet version="1.0" 185 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 186 <xsl:output encoding="UTF-16"/> 187 <xsl:template match="/"> 188 <foo><xsl:value-of select="/a/b/text()" /></foo> 189 </xsl:template> 190 </xsl:stylesheet>''') 191 192 st = etree.XSLT(style) 193 res = st(tree) 194 expected = _bytes('''\ 195 <?xml version="1.0"?> 196 <foo>\\uF8D2</foo> 197 ''').decode("unicode_escape") 198 self.assertEqual(expected, 199 unicode(res))
200
202 tree = self.parse(_bytes('<a><b>\\uF8D2</b><c>\\uF8D2</c></a>' 203 ).decode("unicode_escape")) 204 style = self.parse('''\ 205 <xsl:stylesheet version="1.0" 206 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 207 <xsl:output encoding="UTF-16" standalone="no"/> 208 <xsl:template match="/"> 209 <foo><xsl:value-of select="/a/b/text()" /></foo> 210 </xsl:template> 211 </xsl:stylesheet>''') 212 213 st = etree.XSLT(style) 214 res = st(tree) 215 expected = _bytes('''\ 216 <?xml version="1.0" standalone="no"?> 217 <foo>\\uF8D2</foo> 218 ''').decode("unicode_escape") 219 self.assertEqual(expected, 220 unicode(res))
221
222 - def test_xslt_input(self):
223 style = self.parse('''\ 224 <xsl:stylesheet version="1.0" 225 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 226 <xsl:template match="*" /> 227 <xsl:template match="/"> 228 <foo><xsl:value-of select="/a/b/text()" /></foo> 229 </xsl:template> 230 </xsl:stylesheet>''') 231 232 st = etree.XSLT(style) 233 st = etree.XSLT(style.getroot())
234
236 style = self.parse('''\ 237 <otherroot> 238 <xsl:stylesheet version="1.0" 239 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 240 <xsl:template match="*" /> 241 <xsl:template match="/"> 242 <foo><xsl:value-of select="/a/b/text()" /></foo> 243 </xsl:template> 244 </xsl:stylesheet> 245 </otherroot>''') 246 247 self.assertRaises(etree.XSLTParseError, etree.XSLT, style) 248 root_node = style.getroot() 249 self.assertRaises(etree.XSLTParseError, etree.XSLT, root_node) 250 st = etree.XSLT(root_node[0])
251
252 - def test_xslt_broken(self):
253 tree = self.parse('<a/>') 254 style = self.parse('''\ 255 <xsl:stylesheet version="1.0" 256 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 257 <xsl:foo /> 258 </xsl:stylesheet>''') 259 self.assertRaises(etree.XSLTParseError, 260 etree.XSLT, style)
261
262 - def test_xslt_parameters(self):
263 tree = self.parse('<a><b>B</b><c>C</c></a>') 264 style = self.parse('''\ 265 <xsl:stylesheet version="1.0" 266 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 267 <xsl:template match="/"> 268 <foo><xsl:value-of select="$bar" /></foo> 269 </xsl:template> 270 </xsl:stylesheet>''') 271 272 st = etree.XSLT(style) 273 res = st(tree, bar="'Bar'") 274 self.assertEqual('''\ 275 <?xml version="1.0"?> 276 <foo>Bar</foo> 277 ''', 278 str(res))
279
281 tree = self.parse('<a><b>B</b><c>C</c></a>') 282 style = self.parse('''\ 283 <xsl:stylesheet version="1.0" 284 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 285 <xsl:template match="/"> 286 <foo><xsl:value-of select="$bar" /></foo> 287 </xsl:template> 288 </xsl:stylesheet>''') 289 290 st = etree.XSLT(style) 291 res = st(tree, bar=etree.XSLT.strparam('''it's me, "Bar"''')) 292 self.assertEqual('''\ 293 <?xml version="1.0"?> 294 <foo>it's me, "Bar"</foo> 295 ''', 296 str(res))
297
299 tree = self.parse('<a><b>B</b><c>C</c></a>') 300 style = self.parse('''\ 301 <xsl:stylesheet version="1.0" 302 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 303 <xsl:param name="bar"/> 304 <xsl:template match="/"> 305 <foo><xsl:value-of select="$bar" /></foo> 306 </xsl:template> 307 </xsl:stylesheet>''') 308 309 st = etree.XSLT(style) 310 res = self.assertRaises(etree.XSLTApplyError, 311 st, tree, bar="<test/>") 312 res = self.assertRaises(etree.XSLTApplyError, 313 st, tree, bar="....")
314 315 if etree.LIBXSLT_VERSION < (1,1,18): 316 # later versions produce no error
318 # apply() without needed parameter will lead to XSLTApplyError 319 tree = self.parse('<a><b>B</b><c>C</c></a>') 320 style = self.parse('''\ 321 <xsl:stylesheet version="1.0" 322 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 323 <xsl:template match="/"> 324 <foo><xsl:value-of select="$bar" /></foo> 325 </xsl:template> 326 </xsl:stylesheet>''') 327 328 st = etree.XSLT(style) 329 self.assertRaises(etree.XSLTApplyError, 330 st.apply, tree)
331
333 tree = self.parse('<a><b>B</b><c>C</c></a>') 334 style = self.parse('''\ 335 <xsl:stylesheet version="1.0" 336 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 337 <xsl:template match="*" /> 338 <xsl:template match="/"> 339 <foo><xsl:value-of select="$bar" /></foo> 340 <foo><xsl:value-of select="$baz" /></foo> 341 </xsl:template> 342 </xsl:stylesheet>''') 343 344 st = etree.XSLT(style) 345 res = st(tree, bar="'Bar'", baz="'Baz'") 346 self.assertEqual('''\ 347 <?xml version="1.0"?> 348 <foo>Bar</foo><foo>Baz</foo> 349 ''', 350 str(res))
351
352 - def test_xslt_parameter_xpath(self):
353 tree = self.parse('<a><b>B</b><c>C</c></a>') 354 style = self.parse('''\ 355 <xsl:stylesheet version="1.0" 356 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 357 <xsl:template match="*" /> 358 <xsl:template match="/"> 359 <foo><xsl:value-of select="$bar" /></foo> 360 </xsl:template> 361 </xsl:stylesheet>''') 362 363 st = etree.XSLT(style) 364 res = st(tree, bar="/a/b/text()") 365 self.assertEqual('''\ 366 <?xml version="1.0"?> 367 <foo>B</foo> 368 ''', 369 str(res))
370
372 tree = self.parse('<a><b>B</b><c>C</c></a>') 373 style = self.parse('''\ 374 <xsl:stylesheet version="1.0" 375 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 376 <xsl:template match="*" /> 377 <xsl:template match="/"> 378 <foo><xsl:value-of select="$bar" /></foo> 379 </xsl:template> 380 </xsl:stylesheet>''') 381 382 st = etree.XSLT(style) 383 res = st(tree, bar=etree.XPath("/a/b/text()")) 384 self.assertEqual('''\ 385 <?xml version="1.0"?> 386 <foo>B</foo> 387 ''', 388 str(res))
389
391 tree = self.parse('<a><b>B</b><c>C</c></a>') 392 style = self.parse('''\ 393 <xsl:stylesheet version="1.0" 394 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 395 <xsl:param name="bar" select="'Default'" /> 396 <xsl:template match="*" /> 397 <xsl:template match="/"> 398 <foo><xsl:value-of select="$bar" /></foo> 399 </xsl:template> 400 </xsl:stylesheet>''') 401 402 st = etree.XSLT(style) 403 res = st(tree, bar="'Bar'") 404 self.assertEqual('''\ 405 <?xml version="1.0"?> 406 <foo>Bar</foo> 407 ''', 408 str(res)) 409 res = st(tree) 410 self.assertEqual('''\ 411 <?xml version="1.0"?> 412 <foo>Default</foo> 413 ''', 414 str(res))
415
416 - def test_xslt_html_output(self):
417 tree = self.parse('<a><b>B</b><c>C</c></a>') 418 style = self.parse('''\ 419 <xsl:stylesheet version="1.0" 420 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 421 <xsl:output method="html"/> 422 <xsl:strip-space elements="*"/> 423 <xsl:template match="/"> 424 <html><body><xsl:value-of select="/a/b/text()" /></body></html> 425 </xsl:template> 426 </xsl:stylesheet>''') 427 428 st = etree.XSLT(style) 429 res = st(tree) 430 self.assertEqual('<html><body>B</body></html>', 431 str(res).strip())
432
433 - def test_xslt_include(self):
434 tree = etree.parse(fileInTestDir('test1.xslt')) 435 st = etree.XSLT(tree)
436
438 f = open(fileInTestDir('test1.xslt'), 'rb') 439 tree = etree.parse(f) 440 f.close() 441 st = etree.XSLT(tree)
442
444 xml = '<a/>' 445 xslt = '''\ 446 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 447 <xsl:template match="/"> 448 <response>Some text</response> 449 </xsl:template> 450 </xsl:stylesheet> 451 ''' 452 source = self.parse(xml) 453 styledoc = self.parse(xslt) 454 style = etree.XSLT(styledoc) 455 result = style(source) 456 457 etree.tostring(result.getroot()) 458 459 source = self.parse(xml) 460 styledoc = self.parse(xslt) 461 style = etree.XSLT(styledoc) 462 result = style(source) 463 464 etree.tostring(result.getroot())
465
466 - def test_xslt_repeat_transform(self):
467 xml = '<a/>' 468 xslt = '''\ 469 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 470 <xsl:template match="/"> 471 <response>Some text</response> 472 </xsl:template> 473 </xsl:stylesheet> 474 ''' 475 source = self.parse(xml) 476 styledoc = self.parse(xslt) 477 transform = etree.XSLT(styledoc) 478 result = transform(source) 479 result = transform(source) 480 etree.tostring(result.getroot()) 481 result = transform(source) 482 etree.tostring(result.getroot()) 483 str(result) 484 485 result1 = transform(source) 486 result2 = transform(source) 487 self.assertEqual(str(result1), str(result2)) 488 result = transform(source) 489 str(result)
490
491 - def test_xslt_empty(self):
492 # could segfault if result contains "empty document" 493 xml = '<blah/>' 494 xslt = ''' 495 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 496 <xsl:template match="/" /> 497 </xsl:stylesheet> 498 ''' 499 500 source = self.parse(xml) 501 styledoc = self.parse(xslt) 502 style = etree.XSLT(styledoc) 503 result = style(source) 504 self.assertEqual('', str(result))
505
506 - def test_xslt_message(self):
507 xml = '<blah/>' 508 xslt = ''' 509 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 510 <xsl:template match="/"> 511 <xsl:message>TEST TEST TEST</xsl:message> 512 </xsl:template> 513 </xsl:stylesheet> 514 ''' 515 516 source = self.parse(xml) 517 styledoc = self.parse(xslt) 518 style = etree.XSLT(styledoc) 519 result = style(source) 520 self.assertEqual('', str(result)) 521 self.assertTrue("TEST TEST TEST" in [entry.message 522 for entry in style.error_log])
523
525 xml = '<blah/>' 526 xslt = ''' 527 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 528 <xsl:template match="/"> 529 <xsl:message terminate="yes">TEST TEST TEST</xsl:message> 530 </xsl:template> 531 </xsl:stylesheet> 532 ''' 533 534 source = self.parse(xml) 535 styledoc = self.parse(xslt) 536 style = etree.XSLT(styledoc) 537 538 self.assertRaises(etree.XSLTApplyError, style, source) 539 self.assertTrue("TEST TEST TEST" in [entry.message 540 for entry in style.error_log])
541
542 - def test_xslt_shortcut(self):
543 tree = self.parse('<a><b>B</b><c>C</c></a>') 544 style = self.parse('''\ 545 <xsl:stylesheet version="1.0" 546 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 547 <xsl:template match="*" /> 548 <xsl:template match="/"> 549 <doc> 550 <foo><xsl:value-of select="$bar" /></foo> 551 <foo><xsl:value-of select="$baz" /></foo> 552 </doc> 553 </xsl:template> 554 </xsl:stylesheet>''') 555 556 result = tree.xslt(style, bar="'Bar'", baz="'Baz'") 557 self.assertEqual( 558 _bytes('<doc><foo>Bar</foo><foo>Baz</foo></doc>'), 559 etree.tostring(result.getroot()))
560
561 - def test_multiple_elementrees(self):
562 tree = self.parse('<a><b>B</b><c>C</c></a>') 563 style = self.parse('''\ 564 <xsl:stylesheet version="1.0" 565 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 566 <xsl:template match="a"><A><xsl:apply-templates/></A></xsl:template> 567 <xsl:template match="b"><B><xsl:apply-templates/></B></xsl:template> 568 <xsl:template match="c"><C><xsl:apply-templates/></C></xsl:template> 569 </xsl:stylesheet>''') 570 571 self.assertEqual(self._rootstring(tree), 572 _bytes('<a><b>B</b><c>C</c></a>')) 573 result = tree.xslt(style) 574 self.assertEqual(self._rootstring(tree), 575 _bytes('<a><b>B</b><c>C</c></a>')) 576 self.assertEqual(self._rootstring(result), 577 _bytes('<A><B>B</B><C>C</C></A>')) 578 579 b_tree = etree.ElementTree(tree.getroot()[0]) 580 self.assertEqual(self._rootstring(b_tree), 581 _bytes('<b>B</b>')) 582 result = b_tree.xslt(style) 583 self.assertEqual(self._rootstring(tree), 584 _bytes('<a><b>B</b><c>C</c></a>')) 585 self.assertEqual(self._rootstring(result), 586 _bytes('<B>B</B>')) 587 588 c_tree = etree.ElementTree(tree.getroot()[1]) 589 self.assertEqual(self._rootstring(c_tree), 590 _bytes('<c>C</c>')) 591 result = c_tree.xslt(style) 592 self.assertEqual(self._rootstring(tree), 593 _bytes('<a><b>B</b><c>C</c></a>')) 594 self.assertEqual(self._rootstring(result), 595 _bytes('<C>C</C>'))
596
597 - def test_xslt_document_XML(self):
598 # make sure document('') works from parsed strings 599 xslt = etree.XSLT(etree.XML("""\ 600 <xsl:stylesheet version="1.0" 601 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 602 <xsl:template match="/"> 603 <test>TEXT<xsl:copy-of select="document('')//test"/></test> 604 </xsl:template> 605 </xsl:stylesheet> 606 """)) 607 result = xslt(etree.XML('<a/>')) 608 root = result.getroot() 609 self.assertEqual(root.tag, 610 'test') 611 self.assertEqual(root[0].tag, 612 'test') 613 self.assertEqual(root[0].text, 614 'TEXT') 615 self.assertEqual(root[0][0].tag, 616 '{http://www.w3.org/1999/XSL/Transform}copy-of')
617
618 - def test_xslt_document_parse(self):
619 # make sure document('') works from loaded files 620 xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt"))) 621 result = xslt(etree.XML('<a/>')) 622 root = result.getroot() 623 self.assertEqual(root.tag, 624 'test') 625 self.assertEqual(root[0].tag, 626 '{http://www.w3.org/1999/XSL/Transform}stylesheet')
627
629 # make sure document('') works from loaded files 630 xslt = etree.XSLT(etree.ElementTree(file=fileInTestDir("test-document.xslt"))) 631 result = xslt(etree.XML('<a/>')) 632 root = result.getroot() 633 self.assertEqual(root.tag, 634 'test') 635 self.assertEqual(root[0].tag, 636 '{http://www.w3.org/1999/XSL/Transform}stylesheet')
637
638 - def test_xslt_document_error(self):
639 xslt = etree.XSLT(etree.XML("""\ 640 <xsl:stylesheet version="1.0" 641 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 642 <xsl:template match="/"> 643 <test>TEXT<xsl:copy-of select="document('uri:__junkfood__is__evil__')//test"/></test> 644 </xsl:template> 645 </xsl:stylesheet> 646 """)) 647 self.assertRaises(etree.XSLTApplyError, xslt, etree.XML('<a/>'))
648
650 # make sure document('') works when custom resolvers are in use 651 assertEqual = self.assertEqual 652 called = {'count' : 0} 653 class TestResolver(etree.Resolver): 654 def resolve(self, url, id, context): 655 assertEqual(url, 'file://ANYTHING') 656 called['count'] += 1 657 return self.resolve_string('<CALLED/>', context)
658 659 parser = etree.XMLParser() 660 parser.resolvers.add(TestResolver()) 661 662 xslt = etree.XSLT(etree.XML(_bytes("""\ 663 <xsl:stylesheet version="1.0" 664 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 665 xmlns:l="local"> 666 <xsl:template match="/"> 667 <test> 668 <xsl:for-each select="document('')//l:data/l:entry"> 669 <xsl:copy-of select="document('file://ANYTHING')"/> 670 <xsl:copy> 671 <xsl:attribute name="value"> 672 <xsl:value-of select="."/> 673 </xsl:attribute> 674 </xsl:copy> 675 </xsl:for-each> 676 </test> 677 </xsl:template> 678 <l:data> 679 <l:entry>A</l:entry> 680 <l:entry>B</l:entry> 681 </l:data> 682 </xsl:stylesheet> 683 """), parser)) 684 685 self.assertEqual(called['count'], 0) 686 result = xslt(etree.XML('<a/>')) 687 self.assertEqual(called['count'], 1) 688 689 root = result.getroot() 690 self.assertEqual(root.tag, 691 'test') 692 self.assertEqual(len(root), 4) 693 694 self.assertEqual(root[0].tag, 695 'CALLED') 696 self.assertEqual(root[1].tag, 697 '{local}entry') 698 self.assertEqual(root[1].text, 699 None) 700 self.assertEqual(root[1].get("value"), 701 'A') 702 self.assertEqual(root[2].tag, 703 'CALLED') 704 self.assertEqual(root[3].tag, 705 '{local}entry') 706 self.assertEqual(root[3].text, 707 None) 708 self.assertEqual(root[3].get("value"), 709 'B') 710
711 - def test_xslt_resolver_url_building(self):
712 assertEqual = self.assertEqual 713 called = {'count' : 0} 714 expected_url = None 715 class TestResolver(etree.Resolver): 716 def resolve(self, url, id, context): 717 assertEqual(url, expected_url) 718 called['count'] += 1 719 return self.resolve_string('<CALLED/>', context)
720 721 stylesheet_xml = _bytes("""\ 722 <xsl:stylesheet version="1.0" 723 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 724 xmlns:l="local"> 725 <xsl:template match="/"> 726 <xsl:copy-of select="document('test.xml')"/> 727 </xsl:template> 728 </xsl:stylesheet> 729 """) 730 731 parser = etree.XMLParser() 732 parser.resolvers.add(TestResolver()) 733 734 # test without base_url => relative path only 735 expected_url = 'test.xml' 736 xslt = etree.XSLT(etree.XML(stylesheet_xml, parser)) 737 738 self.assertEqual(called['count'], 0) 739 result = xslt(etree.XML('<a/>')) 740 self.assertEqual(called['count'], 1) 741 742 # now the same thing with a stylesheet base URL on the filesystem 743 called['count'] = 0 744 expected_url = 'MY/BASE/test.xml' # seems to be the same on Windows 745 xslt = etree.XSLT(etree.XML( 746 stylesheet_xml, parser, 747 base_url=os.path.join('MY', 'BASE', 'FILE'))) 748 749 self.assertEqual(called['count'], 0) 750 result = xslt(etree.XML('<a/>')) 751 self.assertEqual(called['count'], 1) 752 753 # now the same thing with a stylesheet base URL 754 called['count'] = 0 755 expected_url = 'http://server.com/BASE/DIR/test.xml' 756 xslt = etree.XSLT(etree.XML( 757 stylesheet_xml, parser, 758 base_url='http://server.com/BASE/DIR/FILE')) 759 760 self.assertEqual(called['count'], 0) 761 result = xslt(etree.XML('<a/>')) 762 self.assertEqual(called['count'], 1) 763 764 # now the same thing with a stylesheet base file:// URL 765 called['count'] = 0 766 expected_url = 'file://BASE/DIR/test.xml' 767 xslt = etree.XSLT(etree.XML( 768 stylesheet_xml, parser, 769 base_url='file://BASE/DIR/FILE')) 770 771 self.assertEqual(called['count'], 0) 772 result = xslt(etree.XML('<a/>')) 773 self.assertEqual(called['count'], 1) 774
775 - def test_xslt_document_parse_allow(self):
776 access_control = etree.XSLTAccessControl(read_file=True) 777 xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt")), 778 access_control=access_control) 779 result = xslt(etree.XML('<a/>')) 780 root = result.getroot() 781 self.assertEqual(root.tag, 782 'test') 783 self.assertEqual(root[0].tag, 784 '{http://www.w3.org/1999/XSL/Transform}stylesheet')
785
786 - def test_xslt_document_parse_deny(self):
787 access_control = etree.XSLTAccessControl(read_file=False) 788 xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt")), 789 access_control=access_control) 790 self.assertRaises(etree.XSLTApplyError, xslt, etree.XML('<a/>'))
791
792 - def test_xslt_document_parse_deny_all(self):
793 access_control = etree.XSLTAccessControl.DENY_ALL 794 xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt")), 795 access_control=access_control) 796 self.assertRaises(etree.XSLTApplyError, xslt, etree.XML('<a/>'))
797
798 - def test_xslt_access_control_repr(self):
799 access_control = etree.XSLTAccessControl.DENY_ALL 800 self.assertTrue(repr(access_control).startswith(type(access_control).__name__)) 801 self.assertEqual(repr(access_control), repr(access_control)) 802 self.assertNotEqual(repr(etree.XSLTAccessControl.DENY_ALL), 803 repr(etree.XSLTAccessControl.DENY_WRITE)) 804 self.assertNotEqual(repr(etree.XSLTAccessControl.DENY_ALL), 805 repr(etree.XSLTAccessControl()))
806
807 - def test_xslt_move_result(self):
808 root = etree.XML(_bytes('''\ 809 <transform> 810 <widget displayType="fieldset"/> 811 </transform>''')) 812 813 xslt = etree.XSLT(etree.XML(_bytes('''\ 814 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 815 <xsl:output method="html" indent="no"/> 816 <xsl:template match="/"> 817 <html> 818 <xsl:apply-templates/> 819 </html> 820 </xsl:template> 821 822 <xsl:template match="widget"> 823 <xsl:element name="{@displayType}"/> 824 </xsl:template> 825 826 </xsl:stylesheet>'''))) 827 828 result = xslt(root[0]) 829 root[:] = result.getroot()[:] 830 del root # segfaulted before
831
832 - def test_xslt_pi(self):
833 tree = self.parse('''\ 834 <?xml version="1.0"?> 835 <?xml-stylesheet type="text/xsl" href="%s"?> 836 <a> 837 <b>B</b> 838 <c>C</c> 839 </a>''' % fileInTestDir("test1.xslt")) 840 841 style_root = tree.getroot().getprevious().parseXSL().getroot() 842 self.assertEqual("{http://www.w3.org/1999/XSL/Transform}stylesheet", 843 style_root.tag)
844
845 - def test_xslt_pi_embedded_xmlid(self):
846 # test xml:id dictionary lookup mechanism 847 tree = self.parse('''\ 848 <?xml version="1.0"?> 849 <?xml-stylesheet type="text/xsl" href="#style"?> 850 <a> 851 <b>B</b> 852 <c>C</c> 853 <xsl:stylesheet version="1.0" xml:id="style" 854 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 855 <xsl:template match="*" /> 856 <xsl:template match="/"> 857 <foo><xsl:value-of select="/a/b/text()" /></foo> 858 </xsl:template> 859 </xsl:stylesheet> 860 </a>''') 861 862 style_root = tree.getroot().getprevious().parseXSL().getroot() 863 self.assertEqual("{http://www.w3.org/1999/XSL/Transform}stylesheet", 864 style_root.tag) 865 866 st = etree.XSLT(style_root) 867 res = st(tree) 868 self.assertEqual('''\ 869 <?xml version="1.0"?> 870 <foo>B</foo> 871 ''', 872 str(res))
873
874 - def test_xslt_pi_embedded_id(self):
875 # test XPath lookup mechanism 876 tree = self.parse('''\ 877 <?xml version="1.0"?> 878 <?xml-stylesheet type="text/xsl" href="#style"?> 879 <a> 880 <b>B</b> 881 <c>C</c> 882 </a>''') 883 884 style = self.parse('''\ 885 <xsl:stylesheet version="1.0" xml:id="style" 886 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 887 <xsl:template match="*" /> 888 <xsl:template match="/"> 889 <foo><xsl:value-of select="/a/b/text()" /></foo> 890 </xsl:template> 891 </xsl:stylesheet> 892 ''') 893 894 tree.getroot().append(style.getroot()) 895 896 style_root = tree.getroot().getprevious().parseXSL().getroot() 897 self.assertEqual("{http://www.w3.org/1999/XSL/Transform}stylesheet", 898 style_root.tag) 899 900 st = etree.XSLT(style_root) 901 res = st(tree) 902 self.assertEqual('''\ 903 <?xml version="1.0"?> 904 <foo>B</foo> 905 ''', 906 str(res))
907
908 - def test_xslt_pi_get(self):
909 tree = self.parse('''\ 910 <?xml version="1.0"?> 911 <?xml-stylesheet type="text/xsl" href="TEST"?> 912 <a> 913 <b>B</b> 914 <c>C</c> 915 </a>''') 916 917 pi = tree.getroot().getprevious() 918 self.assertEqual("TEST", pi.get("href"))
919
920 - def test_xslt_pi_get_all(self):
921 tree = self.parse('''\ 922 <?xml version="1.0"?> 923 <?xml-stylesheet type="text/xsl" href="TEST"?> 924 <a> 925 <b>B</b> 926 <c>C</c> 927 </a>''') 928 929 pi = tree.getroot().getprevious() 930 self.assertEqual("TEST", pi.get("href")) 931 self.assertEqual("text/xsl", pi.get("type")) 932 self.assertEqual(None, pi.get("motz"))
933
934 - def test_xslt_pi_get_all_reversed(self):
935 tree = self.parse('''\ 936 <?xml version="1.0"?> 937 <?xml-stylesheet href="TEST" type="text/xsl"?> 938 <a> 939 <b>B</b> 940 <c>C</c> 941 </a>''') 942 943 pi = tree.getroot().getprevious() 944 self.assertEqual("TEST", pi.get("href")) 945 self.assertEqual("text/xsl", pi.get("type")) 946 self.assertEqual(None, pi.get("motz"))
947
948 - def test_xslt_pi_get_unknown(self):
949 tree = self.parse('''\ 950 <?xml version="1.0"?> 951 <?xml-stylesheet type="text/xsl" href="TEST"?> 952 <a> 953 <b>B</b> 954 <c>C</c> 955 </a>''') 956 957 pi = tree.getroot().getprevious() 958 self.assertEqual(None, pi.get("unknownattribute"))
959
960 - def test_xslt_pi_set_replace(self):
961 tree = self.parse('''\ 962 <?xml version="1.0"?> 963 <?xml-stylesheet type="text/xsl" href="TEST"?> 964 <a> 965 <b>B</b> 966 <c>C</c> 967 </a>''') 968 969 pi = tree.getroot().getprevious() 970 self.assertEqual("TEST", pi.get("href")) 971 972 pi.set("href", "TEST123") 973 self.assertEqual("TEST123", pi.get("href"))
974
975 - def test_xslt_pi_set_new(self):
976 tree = self.parse('''\ 977 <?xml version="1.0"?> 978 <?xml-stylesheet type="text/xsl"?> 979 <a> 980 <b>B</b> 981 <c>C</c> 982 </a>''') 983 984 pi = tree.getroot().getprevious() 985 self.assertEqual(None, pi.get("href")) 986 987 pi.set("href", "TEST") 988 self.assertEqual("TEST", pi.get("href"))
989
990 -class ETreeEXSLTTestCase(HelperTestCase):
991 """EXSLT tests""" 992
993 - def test_exslt_str(self):
994 tree = self.parse('<a><b>B</b><c>C</c></a>') 995 style = self.parse('''\ 996 <xsl:stylesheet version="1.0" 997 xmlns:str="http://exslt.org/strings" 998 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 999 exclude-result-prefixes="str xsl"> 1000 <xsl:template match="text()"> 1001 <xsl:value-of select="str:align(string(.), '***', 'center')" /> 1002 </xsl:template> 1003 <xsl:template match="*"> 1004 <xsl:copy> 1005 <xsl:apply-templates/> 1006 </xsl:copy> 1007 </xsl:template> 1008 </xsl:stylesheet>''') 1009 1010 st = etree.XSLT(style) 1011 res = st(tree) 1012 self.assertEqual('''\ 1013 <?xml version="1.0"?> 1014 <a><b>*B*</b><c>*C*</c></a> 1015 ''', 1016 str(res))
1017 1018 if etree.LIBXSLT_VERSION >= (1,1,21):
1020 tree = self.parse('<a><b>B</b><c>C</c></a>') 1021 style = self.parse('''\ 1022 <xsl:stylesheet version = "1.0" 1023 xmlns:xsl='http://www.w3.org/1999/XSL/Transform' 1024 xmlns:str="http://exslt.org/strings" 1025 extension-element-prefixes="str"> 1026 1027 <xsl:template match="/"> 1028 <h1 class="{str:replace('abc', 'b', 'x')}">test</h1> 1029 </xsl:template> 1030 1031 </xsl:stylesheet>''') 1032 1033 st = etree.XSLT(style) 1034 res = st(tree) 1035 self.assertEqual('''\ 1036 <?xml version="1.0"?> 1037 <h1 class="axc">test</h1> 1038 ''', 1039 str(res))
1040
1041 - def test_exslt_math(self):
1042 tree = self.parse('<a><b>B</b><c>C</c></a>') 1043 style = self.parse('''\ 1044 <xsl:stylesheet version="1.0" 1045 xmlns:math="http://exslt.org/math" 1046 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1047 exclude-result-prefixes="math xsl"> 1048 <xsl:template match="*"> 1049 <xsl:copy> 1050 <xsl:attribute name="pi"> 1051 <xsl:value-of select="math:constant('PI', count(*)+2)"/> 1052 </xsl:attribute> 1053 <xsl:apply-templates/> 1054 </xsl:copy> 1055 </xsl:template> 1056 </xsl:stylesheet>''') 1057 1058 st = etree.XSLT(style) 1059 res = st(tree) 1060 self.assertEqual('''\ 1061 <?xml version="1.0"?> 1062 <a pi="3.14"><b pi="3">B</b><c pi="3">C</c></a> 1063 ''', 1064 str(res))
1065
1066 - def test_exslt_regexp_test(self):
1067 xslt = etree.XSLT(etree.XML(_bytes("""\ 1068 <xsl:stylesheet version="1.0" 1069 xmlns:regexp="http://exslt.org/regular-expressions" 1070 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1071 <xsl:template match="*"> 1072 <test><xsl:copy-of select="*[regexp:test(string(.), '8.')]"/></test> 1073 </xsl:template> 1074 </xsl:stylesheet> 1075 """))) 1076 result = xslt(etree.XML(_bytes('<a><b>123</b><b>098</b><b>987</b></a>'))) 1077 root = result.getroot() 1078 self.assertEqual(root.tag, 1079 'test') 1080 self.assertEqual(len(root), 1) 1081 self.assertEqual(root[0].tag, 1082 'b') 1083 self.assertEqual(root[0].text, 1084 '987')
1085
1086 - def test_exslt_regexp_replace(self):
1087 xslt = etree.XSLT(etree.XML("""\ 1088 <xsl:stylesheet version="1.0" 1089 xmlns:regexp="http://exslt.org/regular-expressions" 1090 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1091 <xsl:template match="*"> 1092 <test> 1093 <xsl:copy-of select="regexp:replace(string(.), 'd.', '', 'XX')"/> 1094 <xsl:text>-</xsl:text> 1095 <xsl:copy-of select="regexp:replace(string(.), 'd.', 'gi', 'XX')"/> 1096 </test> 1097 </xsl:template> 1098 </xsl:stylesheet> 1099 """)) 1100 result = xslt(etree.XML(_bytes('<a>abdCdEeDed</a>'))) 1101 root = result.getroot() 1102 self.assertEqual(root.tag, 1103 'test') 1104 self.assertEqual(len(root), 0) 1105 self.assertEqual(root.text, 'abXXdEeDed-abXXXXeXXd')
1106
1107 - def test_exslt_regexp_match(self):
1108 xslt = etree.XSLT(etree.XML("""\ 1109 <xsl:stylesheet version="1.0" 1110 xmlns:regexp="http://exslt.org/regular-expressions" 1111 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1112 <xsl:template match="*"> 1113 <test> 1114 <test1><xsl:copy-of select="regexp:match(string(.), 'd.')"/></test1> 1115 <test2><xsl:copy-of select="regexp:match(string(.), 'd.', 'g')"/></test2> 1116 <test2i><xsl:copy-of select="regexp:match(string(.), 'd.', 'gi')"/></test2i> 1117 </test> 1118 </xsl:template> 1119 </xsl:stylesheet> 1120 """)) 1121 result = xslt(etree.XML(_bytes('<a>abdCdEeDed</a>'))) 1122 root = result.getroot() 1123 self.assertEqual(root.tag, 'test') 1124 self.assertEqual(len(root), 3) 1125 1126 self.assertEqual(len(root[0]), 1) 1127 self.assertEqual(root[0][0].tag, 'match') 1128 self.assertEqual(root[0][0].text, 'dC') 1129 1130 self.assertEqual(len(root[1]), 2) 1131 self.assertEqual(root[1][0].tag, 'match') 1132 self.assertEqual(root[1][0].text, 'dC') 1133 self.assertEqual(root[1][1].tag, 'match') 1134 self.assertEqual(root[1][1].text, 'dE') 1135 1136 self.assertEqual(len(root[2]), 3) 1137 self.assertEqual(root[2][0].tag, 'match') 1138 self.assertEqual(root[2][0].text, 'dC') 1139 self.assertEqual(root[2][1].tag, 'match') 1140 self.assertEqual(root[2][1].text, 'dE') 1141 self.assertEqual(root[2][2].tag, 'match') 1142 self.assertEqual(root[2][2].text, 'De')
1143
1145 xslt = etree.XSLT(etree.XML(_bytes("""\ 1146 <xsl:stylesheet version="1.0" 1147 xmlns:regexp="http://exslt.org/regular-expressions" 1148 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1149 <xsl:template match="/"> 1150 <test> 1151 <xsl:for-each select="regexp:match( 1152 '123abc567', '([0-9]+)([a-z]+)([0-9]+)' )"> 1153 <test1><xsl:value-of select="."/></test1> 1154 </xsl:for-each> 1155 </test> 1156 </xsl:template> 1157 </xsl:stylesheet> 1158 """))) 1159 result = xslt(etree.XML(_bytes('<a/>'))) 1160 root = result.getroot() 1161 self.assertEqual(root.tag, 'test') 1162 self.assertEqual(len(root), 4) 1163 1164 self.assertEqual(root[0].text, "123abc567") 1165 self.assertEqual(root[1].text, "123") 1166 self.assertEqual(root[2].text, "abc") 1167 self.assertEqual(root[3].text, "567")
1168
1169 - def test_exslt_regexp_match1(self):
1170 # taken from http://www.exslt.org/regexp/functions/match/index.html 1171 xslt = etree.XSLT(etree.XML(_bytes("""\ 1172 <xsl:stylesheet version="1.0" 1173 xmlns:regexp="http://exslt.org/regular-expressions" 1174 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1175 <xsl:template match="/"> 1176 <test> 1177 <xsl:for-each select="regexp:match( 1178 'http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml', 1179 '(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)')"> 1180 <test1><xsl:value-of select="."/></test1> 1181 </xsl:for-each> 1182 </test> 1183 </xsl:template> 1184 </xsl:stylesheet> 1185 """))) 1186 result = xslt(etree.XML(_bytes('<a/>'))) 1187 root = result.getroot() 1188 self.assertEqual(root.tag, 'test') 1189 self.assertEqual(len(root), 5) 1190 1191 self.assertEqual( 1192 root[0].text, 1193 "http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml") 1194 self.assertEqual( 1195 root[1].text, 1196 "http") 1197 self.assertEqual( 1198 root[2].text, 1199 "www.bayes.co.uk") 1200 self.assertFalse(root[3].text) 1201 self.assertEqual( 1202 root[4].text, 1203 "/xml/index.xml?/xml/utils/rechecker.xml")
1204
1205 - def test_exslt_regexp_match2(self):
1206 # taken from http://www.exslt.org/regexp/functions/match/index.html 1207 xslt = etree.XSLT(self.parse("""\ 1208 <xsl:stylesheet version="1.0" 1209 xmlns:regexp="http://exslt.org/regular-expressions" 1210 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1211 <xsl:template match="/"> 1212 <test> 1213 <xsl:for-each select="regexp:match( 1214 'This is a test string', '(\w+)', 'g')"> 1215 <test1><xsl:value-of select="."/></test1> 1216 </xsl:for-each> 1217 </test> 1218 </xsl:template> 1219 </xsl:stylesheet> 1220 """)) 1221 result = xslt(etree.XML(_bytes('<a/>'))) 1222 root = result.getroot() 1223 self.assertEqual(root.tag, 'test') 1224 self.assertEqual(len(root), 5) 1225 1226 self.assertEqual(root[0].text, "This") 1227 self.assertEqual(root[1].text, "is") 1228 self.assertEqual(root[2].text, "a") 1229 self.assertEqual(root[3].text, "test") 1230 self.assertEqual(root[4].text, "string")
1231
1232 - def _test_exslt_regexp_match3(self):
1233 # taken from http://www.exslt.org/regexp/functions/match/index.html 1234 # THIS IS NOT SUPPORTED! 1235 xslt = etree.XSLT(etree.XML(_bytes("""\ 1236 <xsl:stylesheet version="1.0" 1237 xmlns:regexp="http://exslt.org/regular-expressions" 1238 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1239 <xsl:template match="/"> 1240 <test> 1241 <xsl:for-each select="regexp:match( 1242 'This is a test string', '([a-z])+ ', 'g')"> 1243 <test1><xsl:value-of select="."/></test1> 1244 </xsl:for-each> 1245 </test> 1246 </xsl:template> 1247 </xsl:stylesheet> 1248 """))) 1249 result = xslt(etree.XML(_bytes('<a/>'))) 1250 root = result.getroot() 1251 self.assertEqual(root.tag, 'test') 1252 self.assertEqual(len(root), 4) 1253 1254 self.assertEqual(root[0].text, "his") 1255 self.assertEqual(root[1].text, "is") 1256 self.assertEqual(root[2].text, "a") 1257 self.assertEqual(root[3].text, "test")
1258
1259 - def _test_exslt_regexp_match4(self):
1260 # taken from http://www.exslt.org/regexp/functions/match/index.html 1261 # THIS IS NOT SUPPORTED! 1262 xslt = etree.XSLT(etree.XML(_bytes("""\ 1263 <xsl:stylesheet version="1.0" 1264 xmlns:regexp="http://exslt.org/regular-expressions" 1265 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1266 <xsl:template match="/"> 1267 <test> 1268 <xsl:for-each select="regexp:match( 1269 'This is a test string', '([a-z])+ ', 'gi')"> 1270 <test1><xsl:value-of select="."/></test1> 1271 </xsl:for-each> 1272 </test> 1273 </xsl:template> 1274 </xsl:stylesheet> 1275 """))) 1276 result = xslt(etree.XML(_bytes('<a/>'))) 1277 root = result.getroot() 1278 self.assertEqual(root.tag, 'test') 1279 self.assertEqual(len(root), 4) 1280 1281 self.assertEqual(root[0].text, "This") 1282 self.assertEqual(root[1].text, "is") 1283 self.assertEqual(root[2].text, "a") 1284 self.assertEqual(root[3].text, "test")
1285 1286
1287 -class ETreeXSLTExtFuncTestCase(HelperTestCase):
1288 """Tests for XPath extension functions in XSLT.""" 1289
1290 - def test_extensions1(self):
1291 tree = self.parse('<a><b>B</b></a>') 1292 style = self.parse('''\ 1293 <xsl:stylesheet version="1.0" 1294 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1295 xmlns:myns="testns" 1296 exclude-result-prefixes="myns"> 1297 <xsl:template match="a"><A><xsl:value-of select="myns:mytext(b)"/></A></xsl:template> 1298 </xsl:stylesheet>''') 1299 1300 def mytext(ctxt, values): 1301 return 'X' * len(values)
1302 1303 result = tree.xslt(style, {('testns', 'mytext') : mytext}) 1304 self.assertEqual(self._rootstring(result), 1305 _bytes('<A>X</A>'))
1306
1307 - def test_extensions2(self):
1308 tree = self.parse('<a><b>B</b></a>') 1309 style = self.parse('''\ 1310 <xsl:stylesheet version="1.0" 1311 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1312 xmlns:myns="testns" 1313 exclude-result-prefixes="myns"> 1314 <xsl:template match="a"><A><xsl:value-of select="myns:mytext(b)"/></A></xsl:template> 1315 </xsl:stylesheet>''') 1316 1317 def mytext(ctxt, values): 1318 return 'X' * len(values)
1319 1320 namespace = etree.FunctionNamespace('testns') 1321 namespace['mytext'] = mytext 1322 1323 result = tree.xslt(style) 1324 self.assertEqual(self._rootstring(result), 1325 _bytes('<A>X</A>')) 1326
1327 - def test_variable_result_tree_fragment(self):
1328 tree = self.parse('<a><b>B</b><b/></a>') 1329 style = self.parse('''\ 1330 <xsl:stylesheet version="1.0" 1331 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1332 xmlns:myns="testns" 1333 exclude-result-prefixes="myns"> 1334 <xsl:template match="a"> 1335 <xsl:variable name="content"> 1336 <xsl:apply-templates/> 1337 </xsl:variable> 1338 <A><xsl:value-of select="myns:mytext($content)"/></A> 1339 </xsl:template> 1340 <xsl:template match="b"><xsl:copy>BBB</xsl:copy></xsl:template> 1341 </xsl:stylesheet>''') 1342 1343 def mytext(ctxt, values): 1344 for value in values: 1345 self.assertTrue(hasattr(value, 'tag'), 1346 "%s is not an Element" % type(value)) 1347 self.assertEqual(value.tag, 'b') 1348 self.assertEqual(value.text, 'BBB') 1349 return 'X'.join([el.tag for el in values])
1350 1351 namespace = etree.FunctionNamespace('testns') 1352 namespace['mytext'] = mytext 1353 1354 result = tree.xslt(style) 1355 self.assertEqual(self._rootstring(result), 1356 _bytes('<A>bXb</A>')) 1357
1358 - def test_xpath_on_context_node(self):
1359 tree = self.parse('<a><b>B<c/>C</b><b/></a>') 1360 style = self.parse('''\ 1361 <xsl:stylesheet version="1.0" 1362 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1363 xmlns:myns="testns" 1364 exclude-result-prefixes="myns"> 1365 <xsl:template match="b"> 1366 <A><xsl:value-of select="myns:myext()"/></A> 1367 </xsl:template> 1368 </xsl:stylesheet>''') 1369 1370 def extfunc(ctxt): 1371 text_content = ctxt.context_node.xpath('text()') 1372 return 'x'.join(text_content)
1373 1374 namespace = etree.FunctionNamespace('testns') 1375 namespace['myext'] = extfunc 1376 1377 result = tree.xslt(style) 1378 self.assertEqual(self._rootstring(result), 1379 _bytes('<A>BxC</A>')) 1380
1381 - def test_xpath_on_foreign_context_node(self):
1382 # LP ticket 1354652 1383 class Resolver(etree.Resolver): 1384 def resolve(self, system_url, public_id, context): 1385 assert system_url == 'extdoc.xml' 1386 return self.resolve_string(b'<a><b>B<c/>C</b><b/></a>', context)
1387 1388 parser = etree.XMLParser() 1389 parser.resolvers.add(Resolver()) 1390 1391 tree = self.parse(b'<a><b/><b/></a>') 1392 transform = etree.XSLT(self.parse(b'''\ 1393 <xsl:stylesheet version="1.0" 1394 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1395 xmlns:mypre="testns" 1396 exclude-result-prefixes="mypre"> 1397 <xsl:template match="b"> 1398 <B><xsl:value-of select="mypre:myext()"/></B> 1399 </xsl:template> 1400 <xsl:template match="a"> 1401 <A><xsl:apply-templates select="document('extdoc.xml')//b" /></A> 1402 </xsl:template> 1403 </xsl:stylesheet>''', parser=parser)) 1404 1405 def extfunc(ctxt): 1406 text_content = ctxt.context_node.xpath('text()') 1407 return 'x'.join(text_content) 1408 1409 namespace = etree.FunctionNamespace('testns') 1410 namespace['myext'] = extfunc 1411 1412 result = transform(tree) 1413 self.assertEqual(self._rootstring(result), 1414 _bytes('<A><B>BxC</B><B/></A>')) 1415 1416
1417 -class ETreeXSLTExtElementTestCase(HelperTestCase):
1418 """Tests for extension elements in XSLT.""" 1419
1420 - def test_extension_element(self):
1421 tree = self.parse('<a><b>B</b></a>') 1422 style = self.parse('''\ 1423 <xsl:stylesheet version="1.0" 1424 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1425 xmlns:myns="testns" 1426 extension-element-prefixes="myns" 1427 exclude-result-prefixes="myns"> 1428 <xsl:template match="a"> 1429 <A><myns:myext>b</myns:myext></A> 1430 </xsl:template> 1431 </xsl:stylesheet>''') 1432 1433 class MyExt(etree.XSLTExtension): 1434 def execute(self, context, self_node, input_node, output_parent): 1435 child = etree.Element(self_node.text) 1436 child.text = 'X' 1437 output_parent.append(child)
1438 1439 extensions = { ('testns', 'myext') : MyExt() } 1440 1441 result = tree.xslt(style, extensions=extensions) 1442 self.assertEqual(self._rootstring(result), 1443 _bytes('<A><b>X</b></A>')) 1444
1445 - def test_extension_element_doc_context(self):
1446 tree = self.parse('<a><b>B</b></a>') 1447 style = self.parse('''\ 1448 <xsl:stylesheet version="1.0" 1449 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1450 xmlns:myns="testns" 1451 extension-element-prefixes="myns" 1452 exclude-result-prefixes="myns"> 1453 <xsl:template match="/"> 1454 <A><myns:myext>b</myns:myext></A> 1455 </xsl:template> 1456 </xsl:stylesheet>''') 1457 1458 tags = [] 1459 1460 class MyExt(etree.XSLTExtension): 1461 def execute(self, context, self_node, input_node, output_parent): 1462 tags.append(input_node.tag)
1463 1464 extensions = { ('testns', 'myext') : MyExt() } 1465 1466 result = tree.xslt(style, extensions=extensions) 1467 self.assertEqual(tags, ['a']) 1468
1469 - def test_extension_element_comment_pi_context(self):
1470 tree = self.parse('<?test toast?><a><!--a comment--><?another pi?></a>') 1471 style = self.parse('''\ 1472 <xsl:stylesheet version="1.0" 1473 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1474 xmlns:myns="testns" 1475 extension-element-prefixes="myns" 1476 exclude-result-prefixes="myns"> 1477 <xsl:template match="/"> 1478 <ROOT><xsl:apply-templates /></ROOT> 1479 </xsl:template> 1480 <xsl:template match="comment()"> 1481 <A><myns:myext>b</myns:myext></A> 1482 </xsl:template> 1483 <xsl:template match="processing-instruction()"> 1484 <A><myns:myext>b</myns:myext></A> 1485 </xsl:template> 1486 </xsl:stylesheet>''') 1487 1488 text = [] 1489 1490 class MyExt(etree.XSLTExtension): 1491 def execute(self, context, self_node, input_node, output_parent): 1492 text.append(input_node.text)
1493 1494 extensions = { ('testns', 'myext') : MyExt() } 1495 1496 result = tree.xslt(style, extensions=extensions) 1497 self.assertEqual(text, ['toast', 'a comment', 'pi']) 1498
1499 - def _test_extension_element_attribute_context(self):
1500 # currently not supported 1501 tree = self.parse('<a test="A"><b attr="B"/></a>') 1502 style = self.parse('''\ 1503 <xsl:stylesheet version="1.0" 1504 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1505 xmlns:myns="testns" 1506 extension-element-prefixes="myns" 1507 exclude-result-prefixes="myns"> 1508 <xsl:template match="@test"> 1509 <A><myns:myext>b</myns:myext></A> 1510 </xsl:template> 1511 <xsl:template match="@attr"> 1512 <A><myns:myext>b</myns:myext></A> 1513 </xsl:template> 1514 </xsl:stylesheet>''') 1515 1516 text = [] 1517 1518 class MyExt(etree.XSLTExtension): 1519 def execute(self, context, self_node, attr_value, output_parent): 1520 text.append(attr_value)
1521 1522 extensions = { ('testns', 'myext') : MyExt() } 1523 1524 result = tree.xslt(style, extensions=extensions) 1525 self.assertEqual(text, ['A', 'B']) 1526
1527 - def test_extension_element_content(self):
1528 tree = self.parse('<a><b>B</b></a>') 1529 style = self.parse('''\ 1530 <xsl:stylesheet version="1.0" 1531 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1532 xmlns:myns="testns" 1533 extension-element-prefixes="myns"> 1534 <xsl:template match="a"> 1535 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A> 1536 </xsl:template> 1537 </xsl:stylesheet>''') 1538 1539 class MyExt(etree.XSLTExtension): 1540 def execute(self, context, self_node, input_node, output_parent): 1541 output_parent.extend(list(self_node)[1:])
1542 1543 extensions = { ('testns', 'myext') : MyExt() } 1544 1545 result = tree.xslt(style, extensions=extensions) 1546 self.assertEqual(self._rootstring(result), 1547 _bytes('<A><y>Y</y><z/></A>')) 1548
1549 - def test_extension_element_apply_templates(self):
1550 tree = self.parse('<a><b>B</b></a>') 1551 style = self.parse('''\ 1552 <xsl:stylesheet version="1.0" 1553 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1554 xmlns:myns="testns" 1555 extension-element-prefixes="myns"> 1556 <xsl:template match="a"> 1557 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A> 1558 </xsl:template> 1559 <xsl:template match="x" /> 1560 <xsl:template match="z">XYZ</xsl:template> 1561 </xsl:stylesheet>''') 1562 1563 class MyExt(etree.XSLTExtension): 1564 def execute(self, context, self_node, input_node, output_parent): 1565 for child in self_node: 1566 for result in self.apply_templates(context, child): 1567 if isinstance(result, basestring): 1568 el = etree.Element("T") 1569 el.text = result 1570 else: 1571 el = result 1572 output_parent.append(el)
1573 1574 extensions = { ('testns', 'myext') : MyExt() } 1575 1576 result = tree.xslt(style, extensions=extensions) 1577 self.assertEqual(self._rootstring(result), 1578 _bytes('<A><T>Y</T><T>XYZ</T></A>')) 1579
1580 - def test_extension_element_apply_templates_elements_only(self):
1581 tree = self.parse('<a><b>B</b></a>') 1582 style = self.parse('''\ 1583 <xsl:stylesheet version="1.0" 1584 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1585 xmlns:myns="testns" 1586 extension-element-prefixes="myns"> 1587 <xsl:template match="a"> 1588 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A> 1589 </xsl:template> 1590 <xsl:template match="x"><X/></xsl:template> 1591 <xsl:template match="z">XYZ</xsl:template> 1592 </xsl:stylesheet>''') 1593 1594 class MyExt(etree.XSLTExtension): 1595 def execute(self, context, self_node, input_node, output_parent): 1596 for child in self_node: 1597 for result in self.apply_templates(context, child, 1598 elements_only=True): 1599 assert not isinstance(result, basestring) 1600 output_parent.append(result)
1601 1602 extensions = { ('testns', 'myext') : MyExt() } 1603 1604 result = tree.xslt(style, extensions=extensions) 1605 self.assertEqual(self._rootstring(result), 1606 _bytes('<A><X/></A>')) 1607
1608 - def test_extension_element_apply_templates_remove_blank_text(self):
1609 tree = self.parse('<a><b>B</b></a>') 1610 style = self.parse('''\ 1611 <xsl:stylesheet version="1.0" 1612 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1613 xmlns:myns="testns" 1614 extension-element-prefixes="myns"> 1615 <xsl:template match="a"> 1616 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A> 1617 </xsl:template> 1618 <xsl:template match="x"><X/></xsl:template> 1619 <xsl:template match="y"><xsl:text> </xsl:text></xsl:template> 1620 <xsl:template match="z">XYZ</xsl:template> 1621 </xsl:stylesheet>''') 1622 1623 class MyExt(etree.XSLTExtension): 1624 def execute(self, context, self_node, input_node, output_parent): 1625 for child in self_node: 1626 for result in self.apply_templates(context, child, 1627 remove_blank_text=True): 1628 if isinstance(result, basestring): 1629 assert result.strip() 1630 el = etree.Element("T") 1631 el.text = result 1632 else: 1633 el = result 1634 output_parent.append(el)
1635 1636 extensions = { ('testns', 'myext') : MyExt() } 1637 1638 result = tree.xslt(style, extensions=extensions) 1639 self.assertEqual(self._rootstring(result), 1640 _bytes('<A><X/><T>XYZ</T></A>')) 1641
1642 - def test_extension_element_apply_templates_target_node(self):
1643 tree = self.parse('<a><b>B</b></a>') 1644 style = self.parse('''\ 1645 <xsl:stylesheet version="1.0" 1646 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1647 xmlns:myns="testns" 1648 extension-element-prefixes="myns"> 1649 <xsl:template match="a"> 1650 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A> 1651 </xsl:template> 1652 <xsl:template match="x" /> 1653 <xsl:template match="z">XYZ</xsl:template> 1654 </xsl:stylesheet>''') 1655 1656 class MyExt(etree.XSLTExtension): 1657 def execute(self, context, self_node, input_node, output_parent): 1658 for child in self_node: 1659 self.apply_templates(context, child, output_parent)
1660 1661 extensions = { ('testns', 'myext') : MyExt() } 1662 1663 result = tree.xslt(style, extensions=extensions) 1664 self.assertEqual(self._rootstring(result), 1665 _bytes('<A>YXYZ</A>')) 1666
1667 - def test_extension_element_apply_templates_target_node_doc(self):
1668 tree = self.parse('<a><b>B</b></a>') 1669 style = self.parse('''\ 1670 <xsl:stylesheet version="1.0" 1671 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1672 xmlns:myns="testns" 1673 extension-element-prefixes="myns"> 1674 <xsl:template match="a"> 1675 <myns:myext><x>X</x><y>Y</y><z/></myns:myext> 1676 </xsl:template> 1677 <xsl:template match="x"><xsl:processing-instruction name="test">TEST</xsl:processing-instruction></xsl:template> 1678 <xsl:template match="y"><Y>XYZ</Y></xsl:template> 1679 <xsl:template match="z"><xsl:comment>TEST</xsl:comment></xsl:template> 1680 </xsl:stylesheet>''') 1681 1682 class MyExt(etree.XSLTExtension): 1683 def execute(self, context, self_node, input_node, output_parent): 1684 for child in self_node: 1685 self.apply_templates(context, child, output_parent)
1686 1687 extensions = { ('testns', 'myext') : MyExt() } 1688 1689 result = tree.xslt(style, extensions=extensions) 1690 self.assertEqual(etree.tostring(result), 1691 _bytes('<?test TEST?><Y>XYZ</Y><!--TEST-->')) 1692
1693 - def test_extension_element_process_children(self):
1694 tree = self.parse('<a><b>E</b></a>') 1695 style = self.parse('''\ 1696 <xsl:stylesheet version="1.0" 1697 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1698 xmlns:myns="testns" 1699 extension-element-prefixes="myns"> 1700 <xsl:template match="a"> 1701 <xsl:variable name="testvar">yo</xsl:variable> 1702 <A> 1703 <myns:myext> 1704 <xsl:attribute name="attr"> 1705 <xsl:value-of select="$testvar" /> 1706 </xsl:attribute> 1707 <B> 1708 <xsl:choose> 1709 <xsl:when test="1 = 2"><C/></xsl:when> 1710 <xsl:otherwise><D><xsl:value-of select="b/text()" /></D></xsl:otherwise> 1711 </xsl:choose> 1712 </B> 1713 </myns:myext> 1714 </A> 1715 </xsl:template> 1716 </xsl:stylesheet>''') 1717 1718 class MyExt(etree.XSLTExtension): 1719 def execute(self, context, self_node, input_node, output_parent): 1720 el = etree.Element('MY') 1721 self.process_children(context, el) 1722 output_parent.append(el)
1723 1724 extensions = { ('testns', 'myext') : MyExt() } 1725 1726 result = tree.xslt(style, extensions=extensions) 1727 self.assertEqual(self._rootstring(result), 1728 _bytes('<A><MYattr="yo"><B><D>E</D></B></MY></A>')) 1729
1730 - def test_extension_element_process_children_to_append_only(self):
1731 tree = self.parse('<a/>') 1732 style = self.parse('''\ 1733 <xsl:stylesheet version="1.0" 1734 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1735 xmlns:myns="testns" 1736 extension-element-prefixes="myns"> 1737 <xsl:template match="a"> 1738 <myns:myext> 1739 <A/> 1740 </myns:myext> 1741 </xsl:template> 1742 </xsl:stylesheet>''') 1743 1744 class MyExt(etree.XSLTExtension): 1745 def execute(self, context, self_node, input_node, output_parent): 1746 self.process_children(context, output_parent)
1747 1748 extensions = { ('testns', 'myext') : MyExt() } 1749 1750 result = tree.xslt(style, extensions=extensions) 1751 self.assertEqual(self._rootstring(result), 1752 _bytes('<A/>')) 1753
1754 - def test_extension_element_process_children_to_read_only_raise(self):
1755 tree = self.parse('<a/>') 1756 style = self.parse('''\ 1757 <xsl:stylesheet version="1.0" 1758 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1759 xmlns:myns="testns" 1760 extension-element-prefixes="myns"> 1761 <xsl:template match="a"> 1762 <myns:myext> 1763 <A/> 1764 </myns:myext> 1765 </xsl:template> 1766 </xsl:stylesheet>''') 1767 1768 class MyExt(etree.XSLTExtension): 1769 def execute(self, context, self_node, input_node, output_parent): 1770 self.process_children(context, self_node)
1771 1772 extensions = { ('testns', 'myext') : MyExt() } 1773 1774 self.assertRaises(TypeError, tree.xslt, style, extensions=extensions) 1775
1776 - def test_extension_element_process_children_with_subextension_element(self):
1777 tree = self.parse('<a/>') 1778 style = self.parse('''\ 1779 <xsl:stylesheet version="1.0" 1780 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1781 xmlns:myns="testns" 1782 extension-element-prefixes="myns"> 1783 <xsl:template match="a"> 1784 <myns:myext> 1785 <A><myns:myext><B/></myns:myext></A> 1786 </myns:myext> 1787 </xsl:template> 1788 </xsl:stylesheet>''') 1789 1790 class MyExt(etree.XSLTExtension): 1791 callback_call_counter = 0 1792 def execute(self, context, self_node, input_node, output_parent): 1793 self.callback_call_counter += 1 1794 el = etree.Element('MY', n=str(self.callback_call_counter)) 1795 self.process_children(context, el) 1796 output_parent.append(el)
1797 1798 extensions = { ('testns', 'myext') : MyExt() } 1799 1800 result = tree.xslt(style, extensions=extensions) 1801 self.assertEqual(self._rootstring(result), 1802 _bytes('<MYn="1"><A><MYn="2"><B/></MY></A></MY>')) 1803
1804 - def test_extension_element_raise(self):
1805 tree = self.parse('<a><b>B</b></a>') 1806 style = self.parse('''\ 1807 <xsl:stylesheet version="1.0" 1808 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1809 xmlns:myns="testns" 1810 extension-element-prefixes="myns" 1811 exclude-result-prefixes="myns"> 1812 <xsl:template match="a"> 1813 <A><myns:myext>b</myns:myext></A> 1814 </xsl:template> 1815 </xsl:stylesheet>''') 1816 1817 class MyError(Exception): 1818 pass
1819 1820 class MyExt(etree.XSLTExtension): 1821 def execute(self, context, self_node, input_node, output_parent): 1822 raise MyError("expected!") 1823 1824 extensions = { ('testns', 'myext') : MyExt() } 1825 self.assertRaises(MyError, tree.xslt, style, extensions=extensions) 1826 1827
1828 -class Py3XSLTTestCase(HelperTestCase):
1829 """XSLT tests for etree under Python 3""" 1830 1831 pytestmark = skipif('sys.version_info < (3,0)') 1832
1833 - def test_xslt_result_bytes(self):
1834 tree = self.parse('<a><b>B</b><c>C</c></a>') 1835 style = self.parse('''\ 1836 <xsl:stylesheet version="1.0" 1837 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1838 <xsl:template match="*" /> 1839 <xsl:template match="/"> 1840 <foo><xsl:value-of select="/a/b/text()" /></foo> 1841 </xsl:template> 1842 </xsl:stylesheet>''') 1843 1844 st = etree.XSLT(style) 1845 res = st(tree) 1846 self.assertEqual(_bytes('''\ 1847 <?xml version="1.0"?> 1848 <foo>B</foo> 1849 '''), 1850 bytes(res))
1851
1852 - def test_xslt_result_bytearray(self):
1853 tree = self.parse('<a><b>B</b><c>C</c></a>') 1854 style = self.parse('''\ 1855 <xsl:stylesheet version="1.0" 1856 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1857 <xsl:template match="*" /> 1858 <xsl:template match="/"> 1859 <foo><xsl:value-of select="/a/b/text()" /></foo> 1860 </xsl:template> 1861 </xsl:stylesheet>''') 1862 1863 st = etree.XSLT(style) 1864 res = st(tree) 1865 self.assertEqual(_bytes('''\ 1866 <?xml version="1.0"?> 1867 <foo>B</foo> 1868 '''), 1869 bytearray(res))
1870
1872 tree = self.parse('<a><b>B</b><c>C</c></a>') 1873 style = self.parse('''\ 1874 <xsl:stylesheet version="1.0" 1875 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1876 <xsl:template match="*" /> 1877 <xsl:template match="/"> 1878 <foo><xsl:value-of select="/a/b/text()" /></foo> 1879 </xsl:template> 1880 </xsl:stylesheet>''') 1881 1882 st = etree.XSLT(style) 1883 res = st(tree) 1884 self.assertEqual(_bytes('''\ 1885 <?xml version="1.0"?> 1886 <foo>B</foo> 1887 '''), 1888 bytes(memoryview(res)))
1889 1890
1891 -def test_suite():
1892 suite = unittest.TestSuite() 1893 suite.addTests([unittest.makeSuite(ETreeXSLTTestCase)]) 1894 suite.addTests([unittest.makeSuite(ETreeEXSLTTestCase)]) 1895 suite.addTests([unittest.makeSuite(ETreeXSLTExtFuncTestCase)]) 1896 suite.addTests([unittest.makeSuite(ETreeXSLTExtElementTestCase)]) 1897 if is_python3: 1898 suite.addTests([unittest.makeSuite(Py3XSLTTestCase)]) 1899 suite.addTests( 1900 [make_doctest('../../../doc/extensions.txt')]) 1901 suite.addTests( 1902 [make_doctest('../../../doc/xpathxslt.txt')]) 1903 return suite
1904 1905 if __name__ == '__main__': 1906 print('to test use test.py %s' % __file__) 1907