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