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.apply(tree)
      28          self.assertEquals('''\
      29  <?xml version="1.0"?>
      30  <foo>B</foo>
      31  ''',
      32                            st.tostring(res))
      33
      34 -    def test_xslt_elementtree_error(self):
      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):
      43 -            def test_xslt_invalid_stylesheet(self):
      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.apply(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.apply(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
     128 -    def test_xslt_encoding_override(self):
     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.apply(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.apply(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 -    def test_exslt_math(self):
     197          tree = self.parse('<a><b>B</b><c>C</c></a>')
     198          style = self.parse('''\
     199  <xsl:stylesheet version="1.0"
     200      xmlns:math="http://exslt.org/math"
     201      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     202      exclude-result-prefixes="math xsl">
     203    <xsl:template match="*">
     204      <xsl:copy>
     205        <xsl:attribute name="pi">
     206          <xsl:value-of select="math:constant('PI', count(*)+2)"/>
     207        </xsl:attribute>
     208        <xsl:apply-templates/>
     209      </xsl:copy>
     210    </xsl:template>
     211  </xsl:stylesheet>''')
     212
     213          st = etree.XSLT(style)
     214          res = st(tree)
     215          self.assertEquals('''\
     216  <?xml version="1.0"?>
     217  <a pi="3.14"><b pi="3">B</b><c pi="3">C</c></a>
     218  ''',
     219                            str(res))
     220
     221 -    def test_xslt_input(self):
     222          style = self.parse('''\
     223  <xsl:stylesheet version="1.0"
     224      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     225    <xsl:template match="*" />
     226    <xsl:template match="/">
     227      <foo><xsl:value-of select="/a/b/text()" /></foo>
     228    </xsl:template>
     229  </xsl:stylesheet>''')
     230
     231          st = etree.XSLT(style)
     232          st = etree.XSLT(style.getroot())
     233
     234 -    def test_xslt_input_partial_doc(self):
     235          style = self.parse('''\
     236  <otherroot>
     237  <xsl:stylesheet version="1.0"
     238      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     239    <xsl:template match="*" />
     240    <xsl:template match="/">
     241      <foo><xsl:value-of select="/a/b/text()" /></foo>
     242    </xsl:template>
     243  </xsl:stylesheet>
     244  </otherroot>''')
     245
     246          self.assertRaises(etree.XSLTParseError, etree.XSLT, style)
     247          root_node = style.getroot()
     248          self.assertRaises(etree.XSLTParseError, etree.XSLT, root_node)
     249          st = etree.XSLT(root_node[0])
     250
     251 -    def test_xslt_broken(self):
     252          tree = self.parse('<a/>')
     253          style = self.parse('''\
     254  <xsl:stylesheet version="1.0"
     255      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     256      <xsl:foo />
     257  </xsl:stylesheet>''')
     258          self.assertRaises(etree.XSLTParseError,
     259                            etree.XSLT, style)
     260
     261 -    def test_xslt_parameters(self):
     262          tree = self.parse('<a><b>B</b><c>C</c></a>')
     263          style = self.parse('''\
     264  <xsl:stylesheet version="1.0"
     265      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     266    <xsl:template match="/">
     267      <foo><xsl:value-of select="$bar" /></foo>
     268    </xsl:template>
     269  </xsl:stylesheet>''')
     270
     271          st = etree.XSLT(style)
     272          res = st.apply(tree, bar="'Bar'")
     273          self.assertEquals('''\
     274  <?xml version="1.0"?>
     275  <foo>Bar</foo>
     276  ''',
     277                            st.tostring(res))
     278
     279 -    def test_xslt_parameter_invalid(self):
     280          tree = self.parse('<a><b>B</b><c>C</c></a>')
     281          style = self.parse('''\
     282  <xsl:stylesheet version="1.0"
     283      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     284    <xsl:param name="bar"/>
     285    <xsl:template match="/">
     286      <foo><xsl:value-of select="$bar" /></foo>
     287    </xsl:template>
     288  </xsl:stylesheet>''')
     289
     290          st = etree.XSLT(style)
     291          res = self.assertRaises(etree.XSLTApplyError,
     292                                  st, tree, bar="<test/>")
     293          res = self.assertRaises(etree.XSLTApplyError,
     294                                  st, tree, bar="....")
     295
     296      if etree.LIBXSLT_VERSION < (1,1,18):
     297          # later versions produce no error
     298 -        def test_xslt_parameter_missing(self):
     299              # apply() without needed parameter will lead to XSLTApplyError
     300              tree = self.parse('<a><b>B</b><c>C</c></a>')
     301              style = self.parse('''\
     302  <xsl:stylesheet version="1.0"
     303      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     304    <xsl:template match="/">
     305      <foo><xsl:value-of select="$bar" /></foo>
     306    </xsl:template>
     307  </xsl:stylesheet>''')
     308
     309              st = etree.XSLT(style)
     310              self.assertRaises(etree.XSLTApplyError,
     311                                st.apply, tree)
     312
     313 -    def test_xslt_multiple_parameters(self):
     314          tree = self.parse('<a><b>B</b><c>C</c></a>')
     315          style = self.parse('''\
     316  <xsl:stylesheet version="1.0"
     317      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     318    <xsl:template match="*" />
     319    <xsl:template match="/">
     320      <foo><xsl:value-of select="$bar" /></foo>
     321      <foo><xsl:value-of select="$baz" /></foo>
     322    </xsl:template>
     323  </xsl:stylesheet>''')
     324
     325          st = etree.XSLT(style)
     326          res = st.apply(tree, bar="'Bar'", baz="'Baz'")
     327          self.assertEquals('''\
     328  <?xml version="1.0"?>
     329  <foo>Bar</foo><foo>Baz</foo>
     330  ''',
     331                            st.tostring(res))
     332
     333 -    def test_xslt_parameter_xpath(self):
     334          tree = self.parse('<a><b>B</b><c>C</c></a>')
     335          style = self.parse('''\
     336  <xsl:stylesheet version="1.0"
     337      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     338    <xsl:template match="*" />
     339    <xsl:template match="/">
     340      <foo><xsl:value-of select="$bar" /></foo>
     341    </xsl:template>
     342  </xsl:stylesheet>''')
     343
     344          st = etree.XSLT(style)
     345          res = st.apply(tree, bar="/a/b/text()")
     346          self.assertEquals('''\
     347  <?xml version="1.0"?>
     348  <foo>B</foo>
     349  ''',
     350                            st.tostring(res))
     351
     352
     353 -    def test_xslt_default_parameters(self):
     354          tree = self.parse('<a><b>B</b><c>C</c></a>')
     355          style = self.parse('''\
     356  <xsl:stylesheet version="1.0"
     357      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     358    <xsl:param name="bar" select="'Default'" />
     359    <xsl:template match="*" />
     360    <xsl:template match="/">
     361      <foo><xsl:value-of select="$bar" /></foo>
     362    </xsl:template>
     363  </xsl:stylesheet>''')
     364
     365          st = etree.XSLT(style)
     366          res = st.apply(tree, bar="'Bar'")
     367          self.assertEquals('''\
     368  <?xml version="1.0"?>
     369  <foo>Bar</foo>
     370  ''',
     371                            st.tostring(res))
     372          res = st.apply(tree)
     373          self.assertEquals('''\
     374  <?xml version="1.0"?>
     375  <foo>Default</foo>
     376  ''',
     377                            st.tostring(res))
     378
     379 -    def test_xslt_html_output(self):
     380          tree = self.parse('<a><b>B</b><c>C</c></a>')
     381          style = self.parse('''\
     382  <xsl:stylesheet version="1.0"
     383      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     384    <xsl:output method="html"/>
     385    <xsl:strip-space elements="*"/>
     386    <xsl:template match="/">
     387      <html><body><xsl:value-of select="/a/b/text()" /></body></html>
     388    </xsl:template>
     389  </xsl:stylesheet>''')
     390
     391          st = etree.XSLT(style)
     392          res = st(tree)
     393          self.assertEquals('''<html><body>B</body></html>''',
     394                            str(res).strip())
     395
     396 -    def test_xslt_include(self):
     397          tree = etree.parse(fileInTestDir('test1.xslt'))
     398          st = etree.XSLT(tree)
     399
     400 -    def test_xslt_include_from_filelike(self):
     401          f = open(fileInTestDir('test1.xslt'), 'r')
     402          tree = etree.parse(f)
     403          f.close()
     404          st = etree.XSLT(tree)
     405
     406 -    def test_xslt_multiple_transforms(self):
     407          xml = '<a/>'
     408          xslt = '''\
     409  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
     410      <xsl:template match="/">
     411          <response>Some text</response>
     412      </xsl:template>
     413  </xsl:stylesheet>
     414  '''
     415          source = self.parse(xml)
     416          styledoc = self.parse(xslt)
     417          style = etree.XSLT(styledoc)
     418          result = style.apply(source)
     419
     420          etree.tostring(result.getroot())
     421
     422          source = self.parse(xml)
     423          styledoc = self.parse(xslt)
     424          style = etree.XSLT(styledoc)
     425          result = style.apply(source)
     426
     427          etree.tostring(result.getroot())
     428
     429 -    def test_xslt_repeat_transform(self):
     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          transform = etree.XSLT(styledoc)
     441          result = transform.apply(source)
     442          result = transform.apply(source)
     443          etree.tostring(result.getroot())
     444          result = transform.apply(source)
     445          etree.tostring(result.getroot())
     446          str(result)
     447
     448          result1 = transform(source)
     449          result2 = transform(source)
     450          self.assertEquals(str(result1), str(result2))
     451          result = transform(source)
     452          str(result)
     453
     454 -    def test_xslt_empty(self):
     455          # could segfault if result contains "empty document"
     456          xml = '<blah/>'
     457          xslt = '''
     458          <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
     459            <xsl:template match="/" />
     460          </xsl:stylesheet>
     461          '''
     462
     463          source = self.parse(xml)
     464          styledoc = self.parse(xslt)
     465          style = etree.XSLT(styledoc)
     466          result = style.apply(source)
     467          self.assertEqual('', style.tostring(result))
     468          self.assertEqual('', str(result))
     469
     470 -    def test_xslt_message(self):
     471          xml = '<blah/>'
     472          xslt = '''
     473          <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
     474            <xsl:template match="/">
     475              <xsl:message>TEST TEST TEST</xsl:message>
     476            </xsl:template>
     477          </xsl:stylesheet>
     478          '''
     479
     480          source = self.parse(xml)
     481          styledoc = self.parse(xslt)
     482          style = etree.XSLT(styledoc)
     483          result = style.apply(source)
     484          self.assertEqual('', style.tostring(result))
     485          self.assertEqual('', str(result))
     486          self.assert_("TEST TEST TEST" in [entry.message
     487                                            for entry in style.error_log])
     488
     489 -    def test_xslt_message_terminate(self):
     490          xml = '<blah/>'
     491          xslt = '''
     492          <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
     493            <xsl:template match="/">
     494              <xsl:message terminate="yes">TEST TEST TEST</xsl:message>
     495            </xsl:template>
     496          </xsl:stylesheet>
     497          '''
     498
     499          source = self.parse(xml)
     500          styledoc = self.parse(xslt)
     501          style = etree.XSLT(styledoc)
     502
     503          self.assertRaises(etree.XSLTApplyError, style, source)
     504          self.assert_("TEST TEST TEST" in [entry.message
     505                                            for entry in style.error_log])
     506
     507 -    def test_xslt_shortcut(self):
     508          tree = self.parse('<a><b>B</b><c>C</c></a>')
     509          style = self.parse('''\
     510  <xsl:stylesheet version="1.0"
     511      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     512    <xsl:template match="*" />
     513    <xsl:template match="/">
     514      <doc>
     515      <foo><xsl:value-of select="$bar" /></foo>
     516      <foo><xsl:value-of select="$baz" /></foo>
     517      </doc>
     518    </xsl:template>
     519  </xsl:stylesheet>''')
     520
     521          result = tree.xslt(style, bar="'Bar'", baz="'Baz'")
     522          self.assertEquals(
     523              '<doc><foo>Bar</foo><foo>Baz</foo></doc>',
     524              etree.tostring(result.getroot()))
     525
     526 -    def test_multiple_elementrees(self):
     527          tree = self.parse('<a><b>B</b><c>C</c></a>')
     528          style = self.parse('''\
     529  <xsl:stylesheet version="1.0"
     530      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     531    <xsl:template match="a"><A><xsl:apply-templates/></A></xsl:template>
     532    <xsl:template match="b"><B><xsl:apply-templates/></B></xsl:template>
     533    <xsl:template match="c"><C><xsl:apply-templates/></C></xsl:template>
     534  </xsl:stylesheet>''')
     535
     536          self.assertEquals(self._rootstring(tree),
     537                            '<a><b>B</b><c>C</c></a>')
     538          result = tree.xslt(style)
     539          self.assertEquals(self._rootstring(tree),
     540                            '<a><b>B</b><c>C</c></a>')
     541          self.assertEquals(self._rootstring(result),
     542                            '<A><B>B</B><C>C</C></A>')
     543
     544          b_tree = etree.ElementTree(tree.getroot()[0])
     545          self.assertEquals(self._rootstring(b_tree),
     546                            '<b>B</b>')
     547          result = b_tree.xslt(style)
     548          self.assertEquals(self._rootstring(tree),
     549                            '<a><b>B</b><c>C</c></a>')
     550          self.assertEquals(self._rootstring(result),
     551                            '<B>B</B>')
     552
     553          c_tree = etree.ElementTree(tree.getroot()[1])
     554          self.assertEquals(self._rootstring(c_tree),
     555                            '<c>C</c>')
     556          result = c_tree.xslt(style)
     557          self.assertEquals(self._rootstring(tree),
     558                            '<a><b>B</b><c>C</c></a>')
     559          self.assertEquals(self._rootstring(result),
     560                            '<C>C</C>')
     561
     562 -    def test_extensions1(self):
     563          tree = self.parse('<a><b>B</b></a>')
     564          style = self.parse('''\
     565  <xsl:stylesheet version="1.0"
     566      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     567      xmlns:myns="testns"
     568      exclude-result-prefixes="myns">
     569    <xsl:template match="a"><A><xsl:value-of select="myns:mytext(b)"/></A></xsl:template>
     570  </xsl:stylesheet>''')
     571
     572          def mytext(ctxt, values):
     573              return 'X' * len(values)
     574
     575          result = tree.xslt(style, {('testns', 'mytext') : mytext})
     576          self.assertEquals(self._rootstring(result),
     577                            '<A>X</A>')
     578
     579 -    def test_extensions2(self):
     580          tree = self.parse('<a><b>B</b></a>')
     581          style = self.parse('''\
     582  <xsl:stylesheet version="1.0"
     583      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     584      xmlns:myns="testns"
     585      exclude-result-prefixes="myns">
     586    <xsl:template match="a"><A><xsl:value-of select="myns:mytext(b)"/></A></xsl:template>
     587  </xsl:stylesheet>''')
     588
     589          def mytext(ctxt, values):
     590              return 'X' * len(values)
     591
     592          namespace = etree.FunctionNamespace('testns')
     593          namespace['mytext'] = mytext
     594
     595          result = tree.xslt(style)
     596          self.assertEquals(self._rootstring(result),
     597                            '<A>X</A>')
     598
     599 -    def test_xslt_document_XML(self):
     600          # make sure document('') works from parsed strings
     601          xslt = etree.XSLT(etree.XML("""\
     602  <xsl:stylesheet version="1.0"
     603     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     604    <xsl:template match="/">
     605      <test>TEXT<xsl:copy-of select="document('')//test"/></test>
     606    </xsl:template>
     607  </xsl:stylesheet>
     608  """))
     609          result = xslt(etree.XML('<a/>'))
     610          root = result.getroot()
     611          self.assertEquals(root.tag,
     612                            'test')
     613          self.assertEquals(root[0].tag,
     614                            'test')
     615          self.assertEquals(root[0].text,
     616                            'TEXT')
     617          self.assertEquals(root[0][0].tag,
     618                            '{http://www.w3.org/1999/XSL/Transform}copy-of')
     619
     620 -    def test_xslt_document_parse(self):
     621          # make sure document('') works from loaded files
     622          xslt = etree.XSLT(etree.parse(fileInTestDir("test-document.xslt")))
     623          result = xslt(etree.XML('<a/>'))
     624          root = result.getroot()
     625          self.assertEquals(root.tag,
     626                            'test')
     627          self.assertEquals(root[0].tag,
     628                            '{http://www.w3.org/1999/XSL/Transform}stylesheet')
     629
     630 -    def test_xslt_document_elementtree(self):
     631          # make sure document('') works from loaded files
     632          xslt = etree.XSLT(etree.ElementTree(file=fileInTestDir("test-document.xslt")))
     633          result = xslt(etree.XML('<a/>'))
     634          root = result.getroot()
     635          self.assertEquals(root.tag,
     636                            'test')
     637          self.assertEquals(root[0].tag,
     638                            '{http://www.w3.org/1999/XSL/Transform}stylesheet')
     639
     640 -    def test_xslt_document_error(self):
     641          xslt = etree.XSLT(etree.XML("""\
     642  <xsl:stylesheet version="1.0"
     643     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     644    <xsl:template match="/">
     645      <test>TEXT<xsl:copy-of select="document('uri:__junkfood__is__evil__')//test"/></test>
     646    </xsl:template>
     647  </xsl:stylesheet>
     648  """))
     649          self.assertRaises(etree.XSLTApplyError, xslt, etree.XML('<a/>'))
     650
     651 -    def test_xslt_document_XML_resolver(self):
     652          # make sure document('') works when custom resolvers are in use
     653          assertEquals = self.assertEquals
     654          called = {'count' : 0}
     655          class TestResolver(etree.Resolver):
     656              def resolve(self, url, id, context):
     657                  assertEquals(url, 'file://ANYTHING')
     658                  called['count'] += 1
     659                  return self.resolve_string('<CALLED/>', context)
     660
     661          parser = etree.XMLParser()
     662          parser.resolvers.add(TestResolver())
     663
     664          xslt = etree.XSLT(etree.XML("""\
     665  <xsl:stylesheet version="1.0"
     666     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     667     xmlns:l="local">
     668    <xsl:template match="/">
     669      <test>
     670        <xsl:for-each select="document('')//l:data/l:entry">
     671          <xsl:copy-of select="document('file://ANYTHING')"/>
     672          <xsl:copy>
     673            <xsl:attribute name="value">
     674              <xsl:value-of select="."/>
     675            </xsl:attribute>
     676          </xsl:copy>
     677        </xsl:for-each>
     678      </test>
     679    </xsl:template>
     680    <l:data>
     681      <l:entry>A</l:entry>
     682      <l:entry>B</l:entry>
     683    </l:data>
     684  </xsl:stylesheet>
     685  """, parser))
     686
     687          self.assertEquals(called['count'], 0)
     688          result = xslt(etree.XML('<a/>'))
     689          self.assertEquals(called['count'], 1)
     690
     691          root = result.getroot()
     692          self.assertEquals(root.tag,
     693                            'test')
     694          self.assertEquals(len(root), 4)
     695
     696          self.assertEquals(root[0].tag,
     697                            'CALLED')
     698          self.assertEquals(root[1].tag,
     699                            '{local}entry')
     700          self.assertEquals(root[1].text,
     701                            None)
     702          self.assertEquals(root[1].get("value"),
     703                            'A')
     704          self.assertEquals(root[2].tag,
     705                            'CALLED')
     706          self.assertEquals(root[3].tag,
     707                            '{local}entry')
     708          self.assertEquals(root[3].text,
     709                            None)
     710          self.assertEquals(root[3].get("value"),
     711                            'B')
     712
     713 -    def test_xslt_move_result(self):
     714          root = etree.XML('''\
     715          <transform>
     716            <widget displayType="fieldset"/>
     717          </transform>''')
     718
     719          xslt = etree.XSLT(etree.XML('''\
     720          <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     721            <xsl:output method="html" indent="no"/>
     722            <xsl:template match="/">
     723              <html>
     724                <xsl:apply-templates/>
     725              </html>
     726            </xsl:template>
     727
     728            <xsl:template match="widget">
     729              <xsl:element name="{@displayType}"/>
     730            </xsl:template>
     731
     732          </xsl:stylesheet>'''))
     733
     734          result = xslt(root[0])
     735          root[:] = result.getroot()[:]
     736          del root # segfaulted before
     737
     738 -    def test_xslt_pi(self):
     739          tree = self.parse('''\
     740  <?xml version="1.0"?>
     741  <?xml-stylesheet type="text/xsl" href="%s"?>
     742  <a>
     743    <b>B</b>
     744    <c>C</c>
     745  </a>''' % fileInTestDir("test1.xslt"))
     746
     747          style_root = tree.getroot().getprevious().parseXSL().getroot()
     748          self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet",
     749                            style_root.tag)
     750
     751 -    def test_xslt_pi_embedded_xmlid(self):
     752          # test xml:id dictionary lookup mechanism
     753          tree = self.parse('''\
     754  <?xml version="1.0"?>
     755  <?xml-stylesheet type="text/xsl" href="#style"?>
     756  <a>
     757    <b>B</b>
     758    <c>C</c>
     759    <xsl:stylesheet version="1.0" xml:id="style"
     760        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     761      <xsl:template match="*" />
     762      <xsl:template match="/">
     763        <foo><xsl:value-of select="/a/b/text()" /></foo>
     764      </xsl:template>
     765    </xsl:stylesheet>
     766  </a>''')
     767
     768          style_root = tree.getroot().getprevious().parseXSL().getroot()
     769          self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet",
     770                            style_root.tag)
     771
     772          st = etree.XSLT(style_root)
     773          res = st.apply(tree)
     774          self.assertEquals('''\
     775  <?xml version="1.0"?>
     776  <foo>B</foo>
     777  ''',
     778                            st.tostring(res))
     779
     780 -    def test_xslt_pi_embedded_id(self):
     781          # test XPath lookup mechanism
     782          tree = self.parse('''\
     783  <?xml version="1.0"?>
     784  <?xml-stylesheet type="text/xsl" href="#style"?>
     785  <a>
     786    <b>B</b>
     787    <c>C</c>
     788  </a>''')
     789
     790          style = self.parse('''\
     791  <xsl:stylesheet version="1.0" xml:id="style"
     792      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     793    <xsl:template match="*" />
     794    <xsl:template match="/">
     795      <foo><xsl:value-of select="/a/b/text()" /></foo>
     796    </xsl:template>
     797  </xsl:stylesheet>
     798  ''')
     799
     800          tree.getroot().append(style.getroot())
     801
     802          style_root = tree.getroot().getprevious().parseXSL().getroot()
     803          self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet",
     804                            style_root.tag)
     805
     806          st = etree.XSLT(style_root)
     807          res = st.apply(tree)
     808          self.assertEquals('''\
     809  <?xml version="1.0"?>
     810  <foo>B</foo>
     811  ''',
     812                            st.tostring(res))
     813
     814 -    def test_xslt_pi_get(self):
     815          tree = self.parse('''\
     816  <?xml version="1.0"?>
     817  <?xml-stylesheet type="text/xsl" href="TEST"?>
     818  <a>
     819    <b>B</b>
     820    <c>C</c>
     821  </a>''')
     822
     823          pi = tree.getroot().getprevious()
     824          self.assertEquals("TEST", pi.get("href"))
     825
     826 -    def test_xslt_pi_get_all(self):
     827          tree = self.parse('''\
     828  <?xml version="1.0"?>
     829  <?xml-stylesheet type="text/xsl" href="TEST"?>
     830  <a>
     831    <b>B</b>
     832    <c>C</c>
     833  </a>''')
     834
     835          pi = tree.getroot().getprevious()
     836          self.assertEquals("TEST", pi.get("href"))
     837          self.assertEquals("text/xsl", pi.get("type"))
     838          self.assertEquals(None, pi.get("motz"))
     839
     840 -    def test_xslt_pi_get_all_reversed(self):
     841          tree = self.parse('''\
     842  <?xml version="1.0"?>
     843  <?xml-stylesheet href="TEST" type="text/xsl"?>
     844  <a>
     845    <b>B</b>
     846    <c>C</c>
     847  </a>''')
     848
     849          pi = tree.getroot().getprevious()
     850          self.assertEquals("TEST", pi.get("href"))
     851          self.assertEquals("text/xsl", pi.get("type"))
     852          self.assertEquals(None, pi.get("motz"))
     853
     854 -    def test_xslt_pi_get_unknown(self):
     855          tree = self.parse('''\
     856  <?xml version="1.0"?>
     857  <?xml-stylesheet type="text/xsl" href="TEST"?>
     858  <a>
     859    <b>B</b>
     860    <c>C</c>
     861  </a>''')
     862
     863          pi = tree.getroot().getprevious()
     864          self.assertEquals(None, pi.get("unknownattribute"))
     865
     866 -    def test_xslt_pi_set_replace(self):
     867          tree = self.parse('''\
     868  <?xml version="1.0"?>
     869  <?xml-stylesheet type="text/xsl" href="TEST"?>
     870  <a>
     871    <b>B</b>
     872    <c>C</c>
     873  </a>''')
     874
     875          pi = tree.getroot().getprevious()
     876          self.assertEquals("TEST", pi.get("href"))
     877
     878          pi.set("href", "TEST123")
     879          self.assertEquals("TEST123", pi.get("href"))
     880
     881 -    def test_xslt_pi_set_new(self):
     882          tree = self.parse('''\
     883  <?xml version="1.0"?>
     884  <?xml-stylesheet type="text/xsl"?>
     885  <a>
     886    <b>B</b>
     887    <c>C</c>
     888  </a>''')
     889
     890          pi = tree.getroot().getprevious()
     891          self.assertEquals(None, pi.get("href"))
     892
     893          pi.set("href", "TEST")
     894          self.assertEquals("TEST", pi.get("href"))
     895
     896 -    def test_exslt_regexp_test(self):
     897          xslt = etree.XSLT(etree.XML("""\
     898  <xsl:stylesheet version="1.0"
     899     xmlns:regexp="http://exslt.org/regular-expressions"
     900     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     901    <xsl:template match="*">
     902      <test><xsl:copy-of select="*[regexp:test(string(.), '8.')]"/></test>
     903    </xsl:template>
     904  </xsl:stylesheet>
     905  """))
     906          result = xslt(etree.XML('<a><b>123</b><b>098</b><b>987</b></a>'))
     907          root = result.getroot()
     908          self.assertEquals(root.tag,
     909                            'test')
     910          self.assertEquals(len(root), 1)
     911          self.assertEquals(root[0].tag,
     912                            'b')
     913          self.assertEquals(root[0].text,
     914                            '987')
     915
     916 -    def test_exslt_regexp_replace(self):
     917          xslt = etree.XSLT(etree.XML("""\
     918  <xsl:stylesheet version="1.0"
     919     xmlns:regexp="http://exslt.org/regular-expressions"
     920     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     921    <xsl:template match="*">
     922      <test>
     923        <xsl:copy-of select="regexp:replace(string(.), 'd.', '',   'XX')"/>
     924        <xsl:text>-</xsl:text>
     925        <xsl:copy-of select="regexp:replace(string(.), 'd.', 'gi', 'XX')"/>
     926      </test>
     927    </xsl:template>
     928  </xsl:stylesheet>
     929  """))
     930          result = xslt(etree.XML('<a>abdCdEeDed</a>'))
     931          root = result.getroot()
     932          self.assertEquals(root.tag,
     933                            'test')
     934          self.assertEquals(len(root), 0)
     935          self.assertEquals(root.text, 'abXXdEeDed-abXXXXeXXd')
     936
     937 -    def test_exslt_regexp_match(self):
     938          xslt = etree.XSLT(etree.XML("""\
     939  <xsl:stylesheet version="1.0"
     940     xmlns:regexp="http://exslt.org/regular-expressions"
     941     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     942    <xsl:template match="*">
     943      <test>
     944        <test1><xsl:copy-of  select="regexp:match(string(.), 'd.')"/></test1>
     945        <test2><xsl:copy-of  select="regexp:match(string(.), 'd.', 'g')"/></test2>
     946        <test2i><xsl:copy-of select="regexp:match(string(.), 'd.', 'gi')"/></test2i>
     947      </test>
     948    </xsl:template>
     949  </xsl:stylesheet>
     950  """))
     951          result = xslt(etree.XML('<a>abdCdEeDed</a>'))
     952          root = result.getroot()
     953          self.assertEquals(root.tag,  'test')
     954          self.assertEquals(len(root), 3)
     955
     956          self.assertEquals(len(root[0]), 1)
     957          self.assertEquals(root[0][0].tag, 'match')
     958          self.assertEquals(root[0][0].text, 'dC')
     959
     960          self.assertEquals(len(root[1]), 2)
     961          self.assertEquals(root[1][0].tag, 'match')
     962          self.assertEquals(root[1][0].text, 'dC')
     963          self.assertEquals(root[1][1].tag, 'match')
     964          self.assertEquals(root[1][1].text, 'dE')
     965
     966          self.assertEquals(len(root[2]), 3)
     967          self.assertEquals(root[2][0].tag, 'match')
     968          self.assertEquals(root[2][0].text, 'dC')
     969          self.assertEquals(root[2][1].tag, 'match')
     970          self.assertEquals(root[2][1].text, 'dE')
     971          self.assertEquals(root[2][2].tag, 'match')
     972          self.assertEquals(root[2][2].text, 'De')
     973
     974 -    def test_exslt_regexp_match_groups(self):
     975          xslt = etree.XSLT(etree.XML("""\
     976  <xsl:stylesheet version="1.0"
     977     xmlns:regexp="http://exslt.org/regular-expressions"
     978     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     979    <xsl:template match="/">
     980      <test>
     981        <xsl:for-each select="regexp:match(
     982              '123abc567', '([0-9]+)([a-z]+)([0-9]+)' )">
     983          <test1><xsl:value-of select="."/></test1>
     984        </xsl:for-each>
     985      </test>
     986    </xsl:template>
     987  </xsl:stylesheet>
     988  """))
     989          result = xslt(etree.XML('<a/>'))
     990          root = result.getroot()
     991          self.assertEquals(root.tag,  'test')
     992          self.assertEquals(len(root), 4)
     993
     994          self.assertEquals(root[0].text, "123abc567")
     995          self.assertEquals(root[1].text, "123")
     996          self.assertEquals(root[2].text, "abc")
     997          self.assertEquals(root[3].text, "567")
     998
     999 -    def test_exslt_regexp_match1(self):
    1000          # taken from http://www.exslt.org/regexp/functions/match/index.html
    1001          xslt = etree.XSLT(etree.XML("""\
    1002  <xsl:stylesheet version="1.0"
    1003     xmlns:regexp="http://exslt.org/regular-expressions"
    1004     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    1005    <xsl:template match="/">
    1006      <test>
    1007        <xsl:for-each select="regexp:match(
    1008              'http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml',
    1009              '(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)')">
    1010          <test1><xsl:value-of select="."/></test1>
    1011        </xsl:for-each>
    1012      </test>
    1013    </xsl:template>
    1014  </xsl:stylesheet>
    1015  """))
    1016          result = xslt(etree.XML('<a/>'))
    1017          root = result.getroot()
    1018          self.assertEquals(root.tag,  'test')
    1019          self.assertEquals(len(root), 5)
    1020
    1021          self.assertEquals(
    1022              root[0].text,
    1023              "http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml")
    1024          self.assertEquals(
    1025              root[1].text,
    1026              "http")
    1027          self.assertEquals(
    1028              root[2].text,
    1029              "www.bayes.co.uk")
    1030          self.assertFalse(root[3].text)
    1031          self.assertEquals(
    1032              root[4].text,
    1033              "/xml/index.xml?/xml/utils/rechecker.xml")
    1034
    1035 -    def test_exslt_regexp_match2(self):
    1036          # taken from http://www.exslt.org/regexp/functions/match/index.html
    1037          xslt = etree.XSLT(etree.XML("""\
    1038  <xsl:stylesheet version="1.0"
    1039     xmlns:regexp="http://exslt.org/regular-expressions"
    1040     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    1041    <xsl:template match="/">
    1042      <test>
    1043        <xsl:for-each select="regexp:match(
    1044              'This is a test string', '(\w+)', 'g')">
    1045          <test1><xsl:value-of select="."/></test1>
    1046        </xsl:for-each>
    1047      </test>
    1048    </xsl:template>
    1049  </xsl:stylesheet>
    1050  """))
    1051          result = xslt(etree.XML('<a/>'))
    1052          root = result.getroot()
    1053          self.assertEquals(root.tag,  'test')
    1054          self.assertEquals(len(root), 5)
    1055
    1056          self.assertEquals(root[0].text, "This")
    1057          self.assertEquals(root[1].text, "is")
    1058          self.assertEquals(root[2].text, "a")
    1059          self.assertEquals(root[3].text, "test")
    1060          self.assertEquals(root[4].text, "string")
    1061
    1062 -    def _test_exslt_regexp_match3(self):
    1063          # taken from http://www.exslt.org/regexp/functions/match/index.html
    1064          # THIS IS NOT SUPPORTED!
    1065          xslt = etree.XSLT(etree.XML("""\
    1066  <xsl:stylesheet version="1.0"
    1067     xmlns:regexp="http://exslt.org/regular-expressions"
    1068     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    1069    <xsl:template match="/">
    1070      <test>
    1071        <xsl:for-each select="regexp:match(
    1072              'This is a test string', '([a-z])+ ', 'g')">
    1073          <test1><xsl:value-of select="."/></test1>
    1074        </xsl:for-each>
    1075      </test>
    1076    </xsl:template>
    1077  </xsl:stylesheet>
    1078  """))
    1079          result = xslt(etree.XML('<a/>'))
    1080          root = result.getroot()
    1081          self.assertEquals(root.tag,  'test')
    1082          self.assertEquals(len(root), 4)
    1083
    1084          self.assertEquals(root[0].text, "his")
    1085          self.assertEquals(root[1].text, "is")
    1086          self.assertEquals(root[2].text, "a")
    1087          self.assertEquals(root[3].text, "test")
    1088
    1089 -    def _test_exslt_regexp_match4(self):
    1090          # taken from http://www.exslt.org/regexp/functions/match/index.html
    1091          # THIS IS NOT SUPPORTED!
    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:for-each select="regexp:match(
    1099              'This is a test string', '([a-z])+ ', 'gi')">
    1100          <test1><xsl:value-of select="."/></test1>
    1101        </xsl:for-each>
    1102      </test>
    1103    </xsl:template>
    1104  </xsl:stylesheet>
    1105  """))
    1106          result = xslt(etree.XML('<a/>'))
    1107          root = result.getroot()
    1108          self.assertEquals(root.tag,  'test')
    1109          self.assertEquals(len(root), 4)
    1110
    1111          self.assertEquals(root[0].text, "This")
    1112          self.assertEquals(root[1].text, "is")
    1113          self.assertEquals(root[2].text, "a")
    1114          self.assertEquals(root[3].text, "test")
    1115
    1116 -def test_suite():
    1117      suite = unittest.TestSuite()
    1118      suite.addTests([unittest.makeSuite(ETreeXSLTTestCase)])
    1119      suite.addTests(
    1120          [doctest.DocFileSuite('../../../doc/extensions.txt')])
    1121      suite.addTests(
    1122          [doctest.DocFileSuite('../../../doc/xpathxslt.txt')])
    1123      return suite
    1124
    1125  if __name__ == '__main__':
    1126      print 'to test use test.py %s' % __file__
    1127