Package lxml :: Package tests :: Module test_xslt
[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 
   8   
   9  from common_imports import etree, StringIO, HelperTestCase, fileInTestDir 
  10  from common_imports import doctest 
  11   
12 -class ETreeXSLTTestCase(HelperTestCase):
13 """XPath tests etree""" 14
15 - def test_xslt(self):
16 tree = self.parse('<a><b>B</b><c>C</c></a>') 17 style = self.parse('''\ 18 <xsl:stylesheet version="1.0" 19 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 20 <xsl:template match="*" /> 21 <xsl:template match="/"> 22 <foo><xsl:value-of select="/a/b/text()" /></foo> 23 </xsl:template> 24 </xsl:stylesheet>''') 25 26 st = etree.XSLT(style) 27 res = st(tree) 28 self.assertEquals('''\ 29 <?xml version="1.0"?> 30 <foo>B</foo> 31 ''', 32 str(res))
33
35 self.assertRaises(ValueError, etree.XSLT, etree.ElementTree())
36
37 - def test_xslt_input_none(self):
38 self.assertRaises(TypeError, etree.XSLT, None)
39 40 if False and etree.LIBXSLT_VERSION >= (1,1,15): 41 # earlier versions generate no error 42 if etree.LIBXSLT_VERSION > (1,1,17):
44 style = self.parse('''\ 45 <xsl:stylesheet version="1.0" 46 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 47 <xsl:stylesheet /> 48 </xsl:stylesheet>''') 49 50 self.assertRaises( 51 etree.XSLTParseError, etree.XSLT, style)
52
53 - def test_xslt_copy(self):
54 tree = self.parse('<a><b>B</b><c>C</c></a>') 55 style = self.parse('''\ 56 <xsl:stylesheet version="1.0" 57 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 58 <xsl:template match="*" /> 59 <xsl:template match="/"> 60 <foo><xsl:value-of select="/a/b/text()" /></foo> 61 </xsl:template> 62 </xsl:stylesheet>''') 63 64 transform = etree.XSLT(style) 65 res = transform(tree) 66 self.assertEquals('''\ 67 <?xml version="1.0"?> 68 <foo>B</foo> 69 ''', 70 str(res)) 71 72 transform_copy = copy.deepcopy(transform) 73 res = transform_copy(tree) 74 self.assertEquals('''\ 75 <?xml version="1.0"?> 76 <foo>B</foo> 77 ''', 78 str(res)) 79 80 transform = etree.XSLT(style) 81 res = transform(tree) 82 self.assertEquals('''\ 83 <?xml version="1.0"?> 84 <foo>B</foo> 85 ''', 86 str(res))
87
88 - def test_xslt_utf8(self):
89 tree = self.parse(u'<a><b>\uF8D2</b><c>\uF8D2</c></a>') 90 style = self.parse('''\ 91 <xsl:stylesheet version="1.0" 92 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 93 <xsl:output encoding="UTF-8"/> 94 <xsl:template match="/"> 95 <foo><xsl:value-of select="/a/b/text()" /></foo> 96 </xsl:template> 97 </xsl:stylesheet>''') 98 99 st = etree.XSLT(style) 100 res = st(tree) 101 expected = u'''\ 102 <?xml version="1.0" encoding="UTF-8"?> 103 <foo>\uF8D2</foo> 104 ''' 105 self.assertEquals(expected, 106 unicode(str(res), 'UTF-8'))
107
108 - def test_xslt_encoding(self):
109 tree = self.parse(u'<a><b>\uF8D2</b><c>\uF8D2</c></a>') 110 style = self.parse('''\ 111 <xsl:stylesheet version="1.0" 112 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 113 <xsl:output encoding="UTF-16"/> 114 <xsl:template match="/"> 115 <foo><xsl:value-of select="/a/b/text()" /></foo> 116 </xsl:template> 117 </xsl:stylesheet>''') 118 119 st = etree.XSLT(style) 120 res = st(tree) 121 expected = u'''\ 122 <?xml version="1.0" encoding="UTF-16"?> 123 <foo>\uF8D2</foo> 124 ''' 125 self.assertEquals(expected, 126 unicode(str(res), 'UTF-16'))
127
129 tree = self.parse(u'<a><b>\uF8D2</b><c>\uF8D2</c></a>') 130 style = self.parse('''\ 131 <xsl:stylesheet version="1.0" 132 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 133 <xsl:output encoding="UTF-8"/> 134 <xsl:template match="/"> 135 <foo><xsl:value-of select="/a/b/text()" /></foo> 136 </xsl:template> 137 </xsl:stylesheet>''') 138 139 st = etree.XSLT(style) 140 res = st(tree) 141 expected = u"""\ 142 <?xml version='1.0' encoding='UTF-16'?>\ 143 <foo>\uF8D2</foo>""" 144 145 f = StringIO() 146 res.write(f, encoding='UTF-16') 147 result = unicode(f.getvalue(), 'UTF-16').replace('\n', '') 148 self.assertEquals(expected, 149 result)
150
151 - def test_xslt_unicode(self):
152 tree = self.parse(u'<a><b>\uF8D2</b><c>\uF8D2</c></a>') 153 style = self.parse('''\ 154 <xsl:stylesheet version="1.0" 155 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 156 <xsl:output encoding="UTF-16"/> 157 <xsl:template match="/"> 158 <foo><xsl:value-of select="/a/b/text()" /></foo> 159 </xsl:template> 160 </xsl:stylesheet>''') 161 162 st = etree.XSLT(style) 163 res = st(tree) 164 expected = u'''\ 165 <?xml version="1.0"?> 166 <foo>\uF8D2</foo> 167 ''' 168 self.assertEquals(expected, 169 unicode(res))
170
171 - def test_exslt_str(self):
172 tree = self.parse('<a><b>B</b><c>C</c></a>') 173 style = self.parse('''\ 174 <xsl:stylesheet version="1.0" 175 xmlns:str="http://exslt.org/strings" 176 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 177 exclude-result-prefixes="str xsl"> 178 <xsl:template match="text()"> 179 <xsl:value-of select="str:align(string(.), '***', 'center')" /> 180 </xsl:template> 181 <xsl:template match="*"> 182 <xsl:copy> 183 <xsl:apply-templates/> 184 </xsl:copy> 185 </xsl:template> 186 </xsl:stylesheet>''') 187 188 st = etree.XSLT(style) 189 res = st(tree) 190 self.assertEquals('''\ 191 <?xml version="1.0"?> 192 <a><b>*B*</b><c>*C*</c></a> 193 ''', 194 str(res))
195 196 if etree.LIBXSLT_VERSION >= (1,1,21):
198 tree = self.parse('<a><b>B</b><c>C</c></a>') 199 style = self.parse('''\ 200 <xsl:stylesheet version = "1.0" 201 xmlns:xsl='http://www.w3.org/1999/XSL/Transform' 202 xmlns:str="http://exslt.org/strings" 203 extension-element-prefixes="str"> 204 205 <xsl:template match="/"> 206 <h1 class="{str:replace('abc', 'b', 'x')}">test</h1> 207 </xsl:template> 208 209 </xsl:stylesheet>''') 210 211 st = etree.XSLT(style) 212 res = st(tree) 213 self.assertEquals('''\ 214 <?xml version="1.0"?> 215 <h1 class="axc">test</h1> 216 ''', 217 str(res))
218
219 - def test_exslt_math(self):
220 tree = self.parse('<a><b>B</b><c>C</c></a>') 221 style = self.parse('''\ 222 <xsl:stylesheet version="1.0" 223 xmlns:math="http://exslt.org/math" 224 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 225 exclude-result-prefixes="math xsl"> 226 <xsl:template match="*"> 227 <xsl:copy> 228 <xsl:attribute name="pi"> 229 <xsl:value-of select="math:constant('PI', count(*)+2)"/> 230 </xsl:attribute> 231 <xsl:apply-templates/> 232 </xsl:copy> 233 </xsl:template> 234 </xsl:stylesheet>''') 235 236 st = etree.XSLT(style) 237 res = st(tree) 238 self.assertEquals('''\ 239 <?xml version="1.0"?> 240 <a pi="3.14"><b pi="3">B</b><c pi="3">C</c></a> 241 ''', 242 str(res))
243
244 - def test_xslt_input(self):
245 style = self.parse('''\ 246 <xsl:stylesheet version="1.0" 247 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 248 <xsl:template match="*" /> 249 <xsl:template match="/"> 250 <foo><xsl:value-of select="/a/b/text()" /></foo> 251 </xsl:template> 252 </xsl:stylesheet>''') 253 254 st = etree.XSLT(style) 255 st = etree.XSLT(style.getroot())
256
258 style = self.parse('''\ 259 <otherroot> 260 <xsl:stylesheet version="1.0" 261 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 262 <xsl:template match="*" /> 263 <xsl:template match="/"> 264 <foo><xsl:value-of select="/a/b/text()" /></foo> 265 </xsl:template> 266 </xsl:stylesheet> 267 </otherroot>''') 268 269 self.assertRaises(etree.XSLTParseError, etree.XSLT, style) 270 root_node = style.getroot() 271 self.assertRaises(etree.XSLTParseError, etree.XSLT, root_node) 272 st = etree.XSLT(root_node[0])
273
274 - def test_xslt_broken(self):
275 tree = self.parse('<a/>') 276 style = self.parse('''\ 277 <xsl:stylesheet version="1.0" 278 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 279 <xsl:foo /> 280 </xsl:stylesheet>''') 281 self.assertRaises(etree.XSLTParseError, 282 etree.XSLT, style)
283
284 - def test_xslt_parameters(self):
285 tree = self.parse('<a><b>B</b><c>C</c></a>') 286 style = self.parse('''\ 287 <xsl:stylesheet version="1.0" 288 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 289 <xsl:template match="/"> 290 <foo><xsl:value-of select="$bar" /></foo> 291 </xsl:template> 292 </xsl:stylesheet>''') 293 294 st = etree.XSLT(style) 295 res = st(tree, bar="'Bar'") 296 self.assertEquals('''\ 297 <?xml version="1.0"?> 298 <foo>Bar</foo> 299 ''', 300 str(res))
301
303 tree = self.parse('<a><b>B</b><c>C</c></a>') 304 style = self.parse('''\ 305 <xsl:stylesheet version="1.0" 306 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 307 <xsl:param name="bar"/> 308 <xsl:template match="/"> 309 <foo><xsl:value-of select="$bar" /></foo> 310 </xsl:template> 311 </xsl:stylesheet>''') 312 313 st = etree.XSLT(style) 314 res = self.assertRaises(etree.XSLTApplyError, 315 st, tree, bar="<test/>") 316 res = self.assertRaises(etree.XSLTApplyError, 317 st, tree, bar="....")
318 319 if etree.LIBXSLT_VERSION < (1,1,18): 320 # later versions produce no error
322 # apply() without needed parameter will lead to XSLTApplyError 323 tree = self.parse('<a><b>B</b><c>C</c></a>') 324 style = self.parse('''\ 325 <xsl:stylesheet version="1.0" 326 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 327 <xsl:template match="/"> 328 <foo><xsl:value-of select="$bar" /></foo> 329 </xsl:template> 330 </xsl:stylesheet>''') 331 332 st = etree.XSLT(style) 333 self.assertRaises(etree.XSLTApplyError, 334 st.apply, tree)
335
337 tree = self.parse('<a><b>B</b><c>C</c></a>') 338 style = self.parse('''\ 339 <xsl:stylesheet version="1.0" 340 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 341 <xsl:template match="*" /> 342 <xsl:template match="/"> 343 <foo><xsl:value-of select="$bar" /></foo> 344 <foo><xsl:value-of select="$baz" /></foo> 345 </xsl:template> 346 </xsl:stylesheet>''') 347 348 st = etree.XSLT(style) 349 res = st(tree, bar="'Bar'", baz="'Baz'") 350 self.assertEquals('''\ 351 <?xml version="1.0"?> 352 <foo>Bar</foo><foo>Baz</foo> 353 ''', 354 str(res))
355
356 - def test_xslt_parameter_xpath(self):
357 tree = self.parse('<a><b>B</b><c>C</c></a>') 358 style = self.parse('''\ 359 <xsl:stylesheet version="1.0" 360 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 361 <xsl:template match="*" /> 362 <xsl:template match="/"> 363 <foo><xsl:value-of select="$bar" /></foo> 364 </xsl:template> 365 </xsl:stylesheet>''') 366 367 st = etree.XSLT(style) 368 res = st(tree, bar="/a/b/text()") 369 self.assertEquals('''\ 370 <?xml version="1.0"?> 371 <foo>B</foo> 372 ''', 373 str(res))
374 375
377 tree = self.parse('<a><b>B</b><c>C</c></a>') 378 style = self.parse('''\ 379 <xsl:stylesheet version="1.0" 380 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 381 <xsl:param name="bar" select="'Default'" /> 382 <xsl:template match="*" /> 383 <xsl:template match="/"> 384 <foo><xsl:value-of select="$bar" /></foo> 385 </xsl:template> 386 </xsl:stylesheet>''') 387 388 st = etree.XSLT(style) 389 res = st(tree, bar="'Bar'") 390 self.assertEquals('''\ 391 <?xml version="1.0"?> 392 <foo>Bar</foo> 393 ''', 394 str(res)) 395 res = st(tree) 396 self.assertEquals('''\ 397 <?xml version="1.0"?> 398 <foo>Default</foo> 399 ''', 400 str(res))
401
402 - def test_xslt_html_output(self):
403 tree = self.parse('<a><b>B</b><c>C</c></a>') 404 style = self.parse('''\ 405 <xsl:stylesheet version="1.0" 406 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 407 <xsl:output method="html"/> 408 <xsl:strip-space elements="*"/> 409 <xsl:template match="/"> 410 <html><body><xsl:value-of select="/a/b/text()" /></body></html> 411 </xsl:template> 412 </xsl:stylesheet>''') 413 414 st = etree.XSLT(style) 415 res = st(tree) 416 self.assertEquals('''<html><body>B</body></html>''', 417 str(res).strip())
418
419 - def test_xslt_include(self):
420 tree = etree.parse(fileInTestDir('test1.xslt')) 421 st = etree.XSLT(tree)
422
424 f = open(fileInTestDir('test1.xslt'), 'r') 425 tree = etree.parse(f) 426 f.close() 427 st = etree.XSLT(tree)
428
430 xml = '<a/>' 431 xslt = '''\ 432 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 433 <xsl:template match="/"> 434 <response>Some text</response> 435 </xsl:template> 436 </xsl:stylesheet> 437 ''' 438 source = self.parse(xml) 439 styledoc = self.parse(xslt) 440 style = etree.XSLT(styledoc) 441 result = style(source) 442 443 etree.tostring(result.getroot()) 444 445 source = self.parse(xml) 446 styledoc = self.parse(xslt) 447 style = etree.XSLT(styledoc) 448 result = style(source) 449 450 etree.tostring(result.getroot())
451
452 - def test_xslt_repeat_transform(self):
453 xml = '<a/>' 454 xslt = '''\ 455 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 456 <xsl:template match="/"> 457 <response>Some text</response> 458 </xsl:template> 459 </xsl:stylesheet> 460 ''' 461 source = self.parse(xml) 462 styledoc = self.parse(xslt) 463 transform = etree.XSLT(styledoc) 464 result = transform(source) 465 result = transform(source) 466 etree.tostring(result.getroot()) 467 result = transform(source) 468 etree.tostring(result.getroot()) 469 str(result) 470 471 result1 = transform(source) 472 result2 = transform(source) 473 self.assertEquals(str(result1), str(result2)) 474 result = transform(source) 475 str(result)
476
477 - def test_xslt_empty(self):
478 # could segfault if result contains "empty document" 479 xml = '<blah/>' 480 xslt = ''' 481 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 482 <xsl:template match="/" /> 483 </xsl:stylesheet> 484 ''' 485 486 source = self.parse(xml) 487 styledoc = self.parse(xslt) 488 style = etree.XSLT(styledoc) 489 result = style(source) 490 self.assertEqual('', str(result))
491
492 - def test_xslt_message(self):
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:message>TEST TEST TEST</xsl:message> 498 </xsl:template> 499 </xsl:stylesheet> 500 ''' 501 502 source = self.parse(xml) 503 styledoc = self.parse(xslt) 504 style = etree.XSLT(styledoc) 505 result = style(source) 506 self.assertEqual('', str(result)) 507 self.assert_("TEST TEST TEST" in [entry.message 508 for entry in style.error_log])
509
511 xml = '<blah/>' 512 xslt = ''' 513 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 514 <xsl:template match="/"> 515 <xsl:message terminate="yes">TEST TEST TEST</xsl:message> 516 </xsl:template> 517 </xsl:stylesheet> 518 ''' 519 520 source = self.parse(xml) 521 styledoc = self.parse(xslt) 522 style = etree.XSLT(styledoc) 523 524 self.assertRaises(etree.XSLTApplyError, style, source) 525 self.assert_("TEST TEST TEST" in [entry.message 526 for entry in style.error_log])
527
528 - def test_xslt_shortcut(self):
529 tree = self.parse('<a><b>B</b><c>C</c></a>') 530 style = self.parse('''\ 531 <xsl:stylesheet version="1.0" 532 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 533 <xsl:template match="*" /> 534 <xsl:template match="/"> 535 <doc> 536 <foo><xsl:value-of select="$bar" /></foo> 537 <foo><xsl:value-of select="$baz" /></foo> 538 </doc> 539 </xsl:template> 540 </xsl:stylesheet>''') 541 542 result = tree.xslt(style, bar="'Bar'", baz="'Baz'") 543 self.assertEquals( 544 '<doc><foo>Bar</foo><foo>Baz</foo></doc>', 545 etree.tostring(result.getroot()))
546
547 - def test_multiple_elementrees(self):
548 tree = self.parse('<a><b>B</b><c>C</c></a>') 549 style = self.parse('''\ 550 <xsl:stylesheet version="1.0" 551 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 552 <xsl:template match="a"><A><xsl:apply-templates/></A></xsl:template> 553 <xsl:template match="b"><B><xsl:apply-templates/></B></xsl:template> 554 <xsl:template match="c"><C><xsl:apply-templates/></C></xsl:template> 555 </xsl:stylesheet>''') 556 557 self.assertEquals(self._rootstring(tree), 558 '<a><b>B</b><c>C</c></a>') 559 result = tree.xslt(style) 560 self.assertEquals(self._rootstring(tree), 561 '<a><b>B</b><c>C</c></a>') 562 self.assertEquals(self._rootstring(result), 563 '<A><B>B</B><C>C</C></A>') 564 565 b_tree = etree.ElementTree(tree.getroot()[0]) 566 self.assertEquals(self._rootstring(b_tree), 567 '<b>B</b>') 568 result = b_tree.xslt(style) 569 self.assertEquals(self._rootstring(tree), 570 '<a><b>B</b><c>C</c></a>') 571 self.assertEquals(self._rootstring(result), 572 '<B>B</B>') 573 574 c_tree = etree.ElementTree(tree.getroot()[1]) 575 self.assertEquals(self._rootstring(c_tree), 576 '<c>C</c>') 577 result = c_tree.xslt(style) 578 self.assertEquals(self._rootstring(tree), 579 '<a><b>B</b><c>C</c></a>') 580 self.assertEquals(self._rootstring(result), 581 '<C>C</C>')
582
583 - def test_extensions1(self):
584 tree = self.parse('<a><b>B</b></a>') 585 style = self.parse('''\ 586 <xsl:stylesheet version="1.0" 587 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 588 xmlns:myns="testns" 589 exclude-result-prefixes="myns"> 590 <xsl:template match="a"><A><xsl:value-of select="myns:mytext(b)"/></A></xsl:template> 591 </xsl:stylesheet>''') 592 593 def mytext(ctxt, values): 594 return 'X' * len(values)
595 596 result = tree.xslt(style, {('testns', 'mytext') : mytext}) 597 self.assertEquals(self._rootstring(result), 598 '<A>X</A>')
599
600 - def test_extensions2(self):
601 tree = self.parse('<a><b>B</b></a>') 602 style = self.parse('''\ 603 <xsl:stylesheet version="1.0" 604 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 605 xmlns:myns="testns" 606 exclude-result-prefixes="myns"> 607 <xsl:template match="a"><A><xsl:value-of select="myns:mytext(b)"/></A></xsl:template> 608 </xsl:stylesheet>''') 609 610 def mytext(ctxt, values): 611 return 'X' * len(values)
612 613 namespace = etree.FunctionNamespace('testns') 614 namespace['mytext'] = mytext 615 616 result = tree.xslt(style) 617 self.assertEquals(self._rootstring(result), 618 '<A>X</A>') 619
620 - def test_extension_element(self):
621 tree = self.parse('<a><b>B</b></a>') 622 style = self.parse('''\ 623 <xsl:stylesheet version="1.0" 624 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 625 xmlns:myns="testns" 626 extension-element-prefixes="myns" 627 exclude-result-prefixes="myns"> 628 <xsl:template match="a"> 629 <A><myns:myext>b</myns:myext></A> 630 </xsl:template> 631 </xsl:stylesheet>''') 632 633 class MyExt(etree.XSLTExtension): 634 def execute(self, context, self_node, input_node, output_parent): 635 child = etree.Element(self_node.text) 636 child.text = 'X' 637 output_parent.append(child)
638 639 extensions = { ('testns', 'myext') : MyExt() } 640 641 result = tree.xslt(style, extensions=extensions) 642 self.assertEquals(self._rootstring(result), 643 '<A><b>X</b></A>') 644
645 - def test_extension_element_content(self):
646 tree = self.parse('<a><b>B</b></a>') 647 style = self.parse('''\ 648 <xsl:stylesheet version="1.0" 649 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 650 xmlns:myns="testns" 651 extension-element-prefixes="myns"> 652 <xsl:template match="a"> 653 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A> 654 </xsl:template> 655 </xsl:stylesheet>''') 656 657 class MyExt(etree.XSLTExtension): 658 def execute(self, context, self_node, input_node, output_parent): 659 output_parent.extend(list(self_node)[1:])
660 661 extensions = { ('testns', 'myext') : MyExt() } 662 663 result = tree.xslt(style, extensions=extensions) 664 self.assertEquals(self._rootstring(result), 665 '<A><y>Y</y><z/></A>') 666
667 - def test_extension_element_apply_templates(self):
668 tree = self.parse('<a><b>B</b></a>') 669 style = self.parse('''\ 670 <xsl:stylesheet version="1.0" 671 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 672 xmlns:myns="testns" 673 extension-element-prefixes="myns"> 674 <xsl:template match="a"> 675 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A> 676 </xsl:template> 677 <xsl:template match="x" /> 678 <xsl:template match="z">XYZ</xsl:template> 679 </xsl:stylesheet>''') 680 681 class MyExt(etree.XSLTExtension): 682 def execute(self, context, self_node, input_node, output_parent): 683 for child in self_node: 684 for result in self.apply_templates(context, child): 685 if isinstance(result, basestring): 686 el = etree.Element("T") 687 el.text = result 688 else: 689 el = result 690 output_parent.append(el)
691 692 extensions = { ('testns', 'myext') : MyExt() } 693 694 result = tree.xslt(style, extensions=extensions) 695 self.assertEquals(self._rootstring(result), 696 '<A><T>Y</T><T>XYZ</T></A>') 697
698 - def test_extension_element_raise(self):
699 tree = self.parse('<a><b>B</b></a>') 700 style = self.parse('''\ 701 <xsl:stylesheet version="1.0" 702 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 703 xmlns:myns="testns" 704 extension-element-prefixes="myns" 705 exclude-result-prefixes="myns"> 706 <xsl:template match="a"> 707 <A><myns:myext>b</myns:myext></A> 708 </xsl:template> 709 </xsl:stylesheet>''') 710 711 class MyError(Exception): 712 pass
713 714 class MyExt(etree.XSLTExtension): 715 def execute(self, context, self_node, input_node, output_parent): 716 raise MyError("expected!") 717 718 extensions = { ('testns', 'myext') : MyExt() } 719 self.assertRaises(MyError, tree.xslt, style, extensions=extensions) 720
721 - def test_xslt_document_XML(self):
722 # make sure document('') works from parsed strings 723 xslt = etree.XSLT(etree.XML("""\ 724 <xsl:stylesheet version="1.0" 725 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 726 <xsl:template match="/"> 727 <test>TEXT<xsl:copy-of select="document('')//test"/></test> 728 </xsl:template> 729 </xsl:stylesheet> 730 """)) 731 result = xslt(etree.XML('<a/>')) 732 root = result.getroot() 733 self.assertEquals(root.tag, 734 'test') 735 self.assertEquals(root[0].tag, 736 'test') 737 self.assertEquals(root[0].text, 738 'TEXT') 739 self.assertEquals(root[0][0].tag, 740 '{http://www.w3.org/1999/XSL/Transform}copy-of')
741
742 - def test_xslt_document_parse(self):
743 # make sure document('') works from loaded files 744 xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt"))) 745 result = xslt(etree.XML('<a/>')) 746 root = result.getroot() 747 self.assertEquals(root.tag, 748 'test') 749 self.assertEquals(root[0].tag, 750 '{http://www.w3.org/1999/XSL/Transform}stylesheet')
751
752 - def test_xslt_document_elementtree(self):
753 # make sure document('') works from loaded files 754 xslt = etree.XSLT(etree.ElementTree(file=fileInTestDir("test-document.xslt"))) 755 result = xslt(etree.XML('<a/>')) 756 root = result.getroot() 757 self.assertEquals(root.tag, 758 'test') 759 self.assertEquals(root[0].tag, 760 '{http://www.w3.org/1999/XSL/Transform}stylesheet')
761
762 - def test_xslt_document_error(self):
763 xslt = etree.XSLT(etree.XML("""\ 764 <xsl:stylesheet version="1.0" 765 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 766 <xsl:template match="/"> 767 <test>TEXT<xsl:copy-of select="document('uri:__junkfood__is__evil__')//test"/></test> 768 </xsl:template> 769 </xsl:stylesheet> 770 """)) 771 self.assertRaises(etree.XSLTApplyError, xslt, etree.XML('<a/>'))
772
773 - def test_xslt_document_XML_resolver(self):
774 # make sure document('') works when custom resolvers are in use 775 assertEquals = self.assertEquals 776 called = {'count' : 0} 777 class TestResolver(etree.Resolver): 778 def resolve(self, url, id, context): 779 assertEquals(url, 'file://ANYTHING') 780 called['count'] += 1 781 return self.resolve_string('<CALLED/>', context)
782 783 parser = etree.XMLParser() 784 parser.resolvers.add(TestResolver()) 785 786 xslt = etree.XSLT(etree.XML("""\ 787 <xsl:stylesheet version="1.0" 788 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 789 xmlns:l="local"> 790 <xsl:template match="/"> 791 <test> 792 <xsl:for-each select="document('')//l:data/l:entry"> 793 <xsl:copy-of select="document('file://ANYTHING')"/> 794 <xsl:copy> 795 <xsl:attribute name="value"> 796 <xsl:value-of select="."/> 797 </xsl:attribute> 798 </xsl:copy> 799 </xsl:for-each> 800 </test> 801 </xsl:template> 802 <l:data> 803 <l:entry>A</l:entry> 804 <l:entry>B</l:entry> 805 </l:data> 806 </xsl:stylesheet> 807 """, parser)) 808 809 self.assertEquals(called['count'], 0) 810 result = xslt(etree.XML('<a/>')) 811 self.assertEquals(called['count'], 1) 812 813 root = result.getroot() 814 self.assertEquals(root.tag, 815 'test') 816 self.assertEquals(len(root), 4) 817 818 self.assertEquals(root[0].tag, 819 'CALLED') 820 self.assertEquals(root[1].tag, 821 '{local}entry') 822 self.assertEquals(root[1].text, 823 None) 824 self.assertEquals(root[1].get("value"), 825 'A') 826 self.assertEquals(root[2].tag, 827 'CALLED') 828 self.assertEquals(root[3].tag, 829 '{local}entry') 830 self.assertEquals(root[3].text, 831 None) 832 self.assertEquals(root[3].get("value"), 833 'B') 834
835 - def test_xslt_document_parse_allow(self):
836 access_control = etree.XSLTAccessControl(read_file=True) 837 xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt")), 838 access_control = access_control) 839 result = xslt(etree.XML('<a/>')) 840 root = result.getroot() 841 self.assertEquals(root.tag, 842 'test') 843 self.assertEquals(root[0].tag, 844 '{http://www.w3.org/1999/XSL/Transform}stylesheet')
845
846 - def test_xslt_document_parse_deny(self):
847 access_control = etree.XSLTAccessControl(read_file=False) 848 xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt")), 849 access_control = access_control) 850 self.assertRaises(etree.XSLTApplyError, xslt, etree.XML('<a/>'))
851
852 - def test_xslt_document_parse_deny_all(self):
853 access_control = etree.XSLTAccessControl.DENY_ALL 854 xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt")), 855 access_control = access_control) 856 self.assertRaises(etree.XSLTApplyError, xslt, etree.XML('<a/>'))
857
858 - def test_xslt_move_result(self):
859 root = etree.XML('''\ 860 <transform> 861 <widget displayType="fieldset"/> 862 </transform>''') 863 864 xslt = etree.XSLT(etree.XML('''\ 865 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 866 <xsl:output method="html" indent="no"/> 867 <xsl:template match="/"> 868 <html> 869 <xsl:apply-templates/> 870 </html> 871 </xsl:template> 872 873 <xsl:template match="widget"> 874 <xsl:element name="{@displayType}"/> 875 </xsl:template> 876 877 </xsl:stylesheet>''')) 878 879 result = xslt(root[0]) 880 root[:] = result.getroot()[:] 881 del root # segfaulted before
882
883 - def test_xslt_pi(self):
884 tree = self.parse('''\ 885 <?xml version="1.0"?> 886 <?xml-stylesheet type="text/xsl" href="%s"?> 887 <a> 888 <b>B</b> 889 <c>C</c> 890 </a>''' % fileInTestDir("test1.xslt")) 891 892 style_root = tree.getroot().getprevious().parseXSL().getroot() 893 self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet", 894 style_root.tag)
895
896 - def test_xslt_pi_embedded_xmlid(self):
897 # test xml:id dictionary lookup mechanism 898 tree = self.parse('''\ 899 <?xml version="1.0"?> 900 <?xml-stylesheet type="text/xsl" href="#style"?> 901 <a> 902 <b>B</b> 903 <c>C</c> 904 <xsl:stylesheet version="1.0" xml:id="style" 905 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 906 <xsl:template match="*" /> 907 <xsl:template match="/"> 908 <foo><xsl:value-of select="/a/b/text()" /></foo> 909 </xsl:template> 910 </xsl:stylesheet> 911 </a>''') 912 913 style_root = tree.getroot().getprevious().parseXSL().getroot() 914 self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet", 915 style_root.tag) 916 917 st = etree.XSLT(style_root) 918 res = st(tree) 919 self.assertEquals('''\ 920 <?xml version="1.0"?> 921 <foo>B</foo> 922 ''', 923 str(res))
924
925 - def test_xslt_pi_embedded_id(self):
926 # test XPath lookup mechanism 927 tree = self.parse('''\ 928 <?xml version="1.0"?> 929 <?xml-stylesheet type="text/xsl" href="#style"?> 930 <a> 931 <b>B</b> 932 <c>C</c> 933 </a>''') 934 935 style = self.parse('''\ 936 <xsl:stylesheet version="1.0" xml:id="style" 937 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 938 <xsl:template match="*" /> 939 <xsl:template match="/"> 940 <foo><xsl:value-of select="/a/b/text()" /></foo> 941 </xsl:template> 942 </xsl:stylesheet> 943 ''') 944 945 tree.getroot().append(style.getroot()) 946 947 style_root = tree.getroot().getprevious().parseXSL().getroot() 948 self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet", 949 style_root.tag) 950 951 st = etree.XSLT(style_root) 952 res = st(tree) 953 self.assertEquals('''\ 954 <?xml version="1.0"?> 955 <foo>B</foo> 956 ''', 957 str(res))
958
959 - def test_xslt_pi_get(self):
960 tree = self.parse('''\ 961 <?xml version="1.0"?> 962 <?xml-stylesheet type="text/xsl" href="TEST"?> 963 <a> 964 <b>B</b> 965 <c>C</c> 966 </a>''') 967 968 pi = tree.getroot().getprevious() 969 self.assertEquals("TEST", pi.get("href"))
970
971 - def test_xslt_pi_get_all(self):
972 tree = self.parse('''\ 973 <?xml version="1.0"?> 974 <?xml-stylesheet type="text/xsl" href="TEST"?> 975 <a> 976 <b>B</b> 977 <c>C</c> 978 </a>''') 979 980 pi = tree.getroot().getprevious() 981 self.assertEquals("TEST", pi.get("href")) 982 self.assertEquals("text/xsl", pi.get("type")) 983 self.assertEquals(None, pi.get("motz"))
984
985 - def test_xslt_pi_get_all_reversed(self):
986 tree = self.parse('''\ 987 <?xml version="1.0"?> 988 <?xml-stylesheet href="TEST" type="text/xsl"?> 989 <a> 990 <b>B</b> 991 <c>C</c> 992 </a>''') 993 994 pi = tree.getroot().getprevious() 995 self.assertEquals("TEST", pi.get("href")) 996 self.assertEquals("text/xsl", pi.get("type")) 997 self.assertEquals(None, pi.get("motz"))
998
999 - def test_xslt_pi_get_unknown(self):
1000 tree = self.parse('''\ 1001 <?xml version="1.0"?> 1002 <?xml-stylesheet type="text/xsl" href="TEST"?> 1003 <a> 1004 <b>B</b> 1005 <c>C</c> 1006 </a>''') 1007 1008 pi = tree.getroot().getprevious() 1009 self.assertEquals(None, pi.get("unknownattribute"))
1010
1011 - def test_xslt_pi_set_replace(self):
1012 tree = self.parse('''\ 1013 <?xml version="1.0"?> 1014 <?xml-stylesheet type="text/xsl" href="TEST"?> 1015 <a> 1016 <b>B</b> 1017 <c>C</c> 1018 </a>''') 1019 1020 pi = tree.getroot().getprevious() 1021 self.assertEquals("TEST", pi.get("href")) 1022 1023 pi.set("href", "TEST123") 1024 self.assertEquals("TEST123", pi.get("href"))
1025
1026 - def test_xslt_pi_set_new(self):
1027 tree = self.parse('''\ 1028 <?xml version="1.0"?> 1029 <?xml-stylesheet type="text/xsl"?> 1030 <a> 1031 <b>B</b> 1032 <c>C</c> 1033 </a>''') 1034 1035 pi = tree.getroot().getprevious() 1036 self.assertEquals(None, pi.get("href")) 1037 1038 pi.set("href", "TEST") 1039 self.assertEquals("TEST", pi.get("href"))
1040
1041 - def test_exslt_regexp_test(self):
1042 xslt = etree.XSLT(etree.XML("""\ 1043 <xsl:stylesheet version="1.0" 1044 xmlns:regexp="http://exslt.org/regular-expressions" 1045 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1046 <xsl:template match="*"> 1047 <test><xsl:copy-of select="*[regexp:test(string(.), '8.')]"/></test> 1048 </xsl:template> 1049 </xsl:stylesheet> 1050 """)) 1051 result = xslt(etree.XML('<a><b>123</b><b>098</b><b>987</b></a>')) 1052 root = result.getroot() 1053 self.assertEquals(root.tag, 1054 'test') 1055 self.assertEquals(len(root), 1) 1056 self.assertEquals(root[0].tag, 1057 'b') 1058 self.assertEquals(root[0].text, 1059 '987')
1060
1061 - def test_exslt_regexp_replace(self):
1062 xslt = etree.XSLT(etree.XML("""\ 1063 <xsl:stylesheet version="1.0" 1064 xmlns:regexp="http://exslt.org/regular-expressions" 1065 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1066 <xsl:template match="*"> 1067 <test> 1068 <xsl:copy-of select="regexp:replace(string(.), 'd.', '', 'XX')"/> 1069 <xsl:text>-</xsl:text> 1070 <xsl:copy-of select="regexp:replace(string(.), 'd.', 'gi', 'XX')"/> 1071 </test> 1072 </xsl:template> 1073 </xsl:stylesheet> 1074 """)) 1075 result = xslt(etree.XML('<a>abdCdEeDed</a>')) 1076 root = result.getroot() 1077 self.assertEquals(root.tag, 1078 'test') 1079 self.assertEquals(len(root), 0) 1080 self.assertEquals(root.text, 'abXXdEeDed-abXXXXeXXd')
1081
1082 - def test_exslt_regexp_match(self):
1083 xslt = etree.XSLT(etree.XML("""\ 1084 <xsl:stylesheet version="1.0" 1085 xmlns:regexp="http://exslt.org/regular-expressions" 1086 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1087 <xsl:template match="*"> 1088 <test> 1089 <test1><xsl:copy-of select="regexp:match(string(.), 'd.')"/></test1> 1090 <test2><xsl:copy-of select="regexp:match(string(.), 'd.', 'g')"/></test2> 1091 <test2i><xsl:copy-of select="regexp:match(string(.), 'd.', 'gi')"/></test2i> 1092 </test> 1093 </xsl:template> 1094 </xsl:stylesheet> 1095 """)) 1096 result = xslt(etree.XML('<a>abdCdEeDed</a>')) 1097 root = result.getroot() 1098 self.assertEquals(root.tag, 'test') 1099 self.assertEquals(len(root), 3) 1100 1101 self.assertEquals(len(root[0]), 1) 1102 self.assertEquals(root[0][0].tag, 'match') 1103 self.assertEquals(root[0][0].text, 'dC') 1104 1105 self.assertEquals(len(root[1]), 2) 1106 self.assertEquals(root[1][0].tag, 'match') 1107 self.assertEquals(root[1][0].text, 'dC') 1108 self.assertEquals(root[1][1].tag, 'match') 1109 self.assertEquals(root[1][1].text, 'dE') 1110 1111 self.assertEquals(len(root[2]), 3) 1112 self.assertEquals(root[2][0].tag, 'match') 1113 self.assertEquals(root[2][0].text, 'dC') 1114 self.assertEquals(root[2][1].tag, 'match') 1115 self.assertEquals(root[2][1].text, 'dE') 1116 self.assertEquals(root[2][2].tag, 'match') 1117 self.assertEquals(root[2][2].text, 'De')
1118
1119 - def test_exslt_regexp_match_groups(self):
1120 xslt = etree.XSLT(etree.XML("""\ 1121 <xsl:stylesheet version="1.0" 1122 xmlns:regexp="http://exslt.org/regular-expressions" 1123 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1124 <xsl:template match="/"> 1125 <test> 1126 <xsl:for-each select="regexp:match( 1127 '123abc567', '([0-9]+)([a-z]+)([0-9]+)' )"> 1128 <test1><xsl:value-of select="."/></test1> 1129 </xsl:for-each> 1130 </test> 1131 </xsl:template> 1132 </xsl:stylesheet> 1133 """)) 1134 result = xslt(etree.XML('<a/>')) 1135 root = result.getroot() 1136 self.assertEquals(root.tag, 'test') 1137 self.assertEquals(len(root), 4) 1138 1139 self.assertEquals(root[0].text, "123abc567") 1140 self.assertEquals(root[1].text, "123") 1141 self.assertEquals(root[2].text, "abc") 1142 self.assertEquals(root[3].text, "567")
1143
1144 - def test_exslt_regexp_match1(self):
1145 # taken from http://www.exslt.org/regexp/functions/match/index.html 1146 xslt = etree.XSLT(etree.XML("""\ 1147 <xsl:stylesheet version="1.0" 1148 xmlns:regexp="http://exslt.org/regular-expressions" 1149 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1150 <xsl:template match="/"> 1151 <test> 1152 <xsl:for-each select="regexp:match( 1153 'http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml', 1154 '(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)')"> 1155 <test1><xsl:value-of select="."/></test1> 1156 </xsl:for-each> 1157 </test> 1158 </xsl:template> 1159 </xsl:stylesheet> 1160 """)) 1161 result = xslt(etree.XML('<a/>')) 1162 root = result.getroot() 1163 self.assertEquals(root.tag, 'test') 1164 self.assertEquals(len(root), 5) 1165 1166 self.assertEquals( 1167 root[0].text, 1168 "http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml") 1169 self.assertEquals( 1170 root[1].text, 1171 "http") 1172 self.assertEquals( 1173 root[2].text, 1174 "www.bayes.co.uk") 1175 self.assertFalse(root[3].text) 1176 self.assertEquals( 1177 root[4].text, 1178 "/xml/index.xml?/xml/utils/rechecker.xml")
1179
1180 - def test_exslt_regexp_match2(self):
1181 # taken from http://www.exslt.org/regexp/functions/match/index.html 1182 xslt = etree.XSLT(etree.XML("""\ 1183 <xsl:stylesheet version="1.0" 1184 xmlns:regexp="http://exslt.org/regular-expressions" 1185 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1186 <xsl:template match="/"> 1187 <test> 1188 <xsl:for-each select="regexp:match( 1189 'This is a test string', '(\w+)', 'g')"> 1190 <test1><xsl:value-of select="."/></test1> 1191 </xsl:for-each> 1192 </test> 1193 </xsl:template> 1194 </xsl:stylesheet> 1195 """)) 1196 result = xslt(etree.XML('<a/>')) 1197 root = result.getroot() 1198 self.assertEquals(root.tag, 'test') 1199 self.assertEquals(len(root), 5) 1200 1201 self.assertEquals(root[0].text, "This") 1202 self.assertEquals(root[1].text, "is") 1203 self.assertEquals(root[2].text, "a") 1204 self.assertEquals(root[3].text, "test") 1205 self.assertEquals(root[4].text, "string")
1206
1207 - def _test_exslt_regexp_match3(self):
1208 # taken from http://www.exslt.org/regexp/functions/match/index.html 1209 # THIS IS NOT SUPPORTED! 1210 xslt = etree.XSLT(etree.XML("""\ 1211 <xsl:stylesheet version="1.0" 1212 xmlns:regexp="http://exslt.org/regular-expressions" 1213 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1214 <xsl:template match="/"> 1215 <test> 1216 <xsl:for-each select="regexp:match( 1217 'This is a test string', '([a-z])+ ', 'g')"> 1218 <test1><xsl:value-of select="."/></test1> 1219 </xsl:for-each> 1220 </test> 1221 </xsl:template> 1222 </xsl:stylesheet> 1223 """)) 1224 result = xslt(etree.XML('<a/>')) 1225 root = result.getroot() 1226 self.assertEquals(root.tag, 'test') 1227 self.assertEquals(len(root), 4) 1228 1229 self.assertEquals(root[0].text, "his") 1230 self.assertEquals(root[1].text, "is") 1231 self.assertEquals(root[2].text, "a") 1232 self.assertEquals(root[3].text, "test")
1233
1234 - def _test_exslt_regexp_match4(self):
1235 # taken from http://www.exslt.org/regexp/functions/match/index.html 1236 # THIS IS NOT SUPPORTED! 1237 xslt = etree.XSLT(etree.XML("""\ 1238 <xsl:stylesheet version="1.0" 1239 xmlns:regexp="http://exslt.org/regular-expressions" 1240 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 1241 <xsl:template match="/"> 1242 <test> 1243 <xsl:for-each select="regexp:match( 1244 'This is a test string', '([a-z])+ ', 'gi')"> 1245 <test1><xsl:value-of select="."/></test1> 1246 </xsl:for-each> 1247 </test> 1248 </xsl:template> 1249 </xsl:stylesheet> 1250 """)) 1251 result = xslt(etree.XML('<a/>')) 1252 root = result.getroot() 1253 self.assertEquals(root.tag, 'test') 1254 self.assertEquals(len(root), 4) 1255 1256 self.assertEquals(root[0].text, "This") 1257 self.assertEquals(root[1].text, "is") 1258 self.assertEquals(root[2].text, "a") 1259 self.assertEquals(root[3].text, "test")
1260
1261 -def test_suite():
1262 suite = unittest.TestSuite() 1263 suite.addTests([unittest.makeSuite(ETreeXSLTTestCase)]) 1264 suite.addTests( 1265 [doctest.DocFileSuite('../../../doc/extensions.txt')]) 1266 suite.addTests( 1267 [doctest.DocFileSuite('../../../doc/xpathxslt.txt')]) 1268 return suite
1269 1270 if __name__ == '__main__': 1271 print 'to test use test.py %s' % __file__ 1272