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