1
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
13 """XPath tests etree"""
14
16 tree = self.parse('<a><b>B</b><c>C</c></a>')
17 style = self.parse('''\
18 <xsl:stylesheet version="1.0"
19 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
20 <xsl:template match="*" />
21 <xsl:template match="/">
22 <foo><xsl:value-of select="/a/b/text()" /></foo>
23 </xsl:template>
24 </xsl:stylesheet>''')
25
26 st = etree.XSLT(style)
27 res = st(tree)
28 self.assertEquals('''\
29 <?xml version="1.0"?>
30 <foo>B</foo>
31 ''',
32 str(res))
33
36
39
40 if False and etree.LIBXSLT_VERSION >= (1,1,15):
41
42 if etree.LIBXSLT_VERSION > (1,1,17):
44 style = self.parse('''\
45 <xsl:stylesheet version="1.0"
46 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
47 <xsl:stylesheet />
48 </xsl:stylesheet>''')
49
50 self.assertRaises(
51 etree.XSLTParseError, etree.XSLT, style)
52
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
89 tree = self.parse(u'<a><b>\uF8D2</b><c>\uF8D2</c></a>')
90 style = self.parse('''\
91 <xsl:stylesheet version="1.0"
92 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
93 <xsl:output encoding="UTF-8"/>
94 <xsl:template match="/">
95 <foo><xsl:value-of select="/a/b/text()" /></foo>
96 </xsl:template>
97 </xsl:stylesheet>''')
98
99 st = etree.XSLT(style)
100 res = st(tree)
101 expected = u'''\
102 <?xml version="1.0" encoding="UTF-8"?>
103 <foo>\uF8D2</foo>
104 '''
105 self.assertEquals(expected,
106 unicode(str(res), 'UTF-8'))
107
109 tree = self.parse(u'<a><b>\uF8D2</b><c>\uF8D2</c></a>')
110 style = self.parse('''\
111 <xsl:stylesheet version="1.0"
112 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
113 <xsl:output encoding="UTF-16"/>
114 <xsl:template match="/">
115 <foo><xsl:value-of select="/a/b/text()" /></foo>
116 </xsl:template>
117 </xsl:stylesheet>''')
118
119 st = etree.XSLT(style)
120 res = st(tree)
121 expected = u'''\
122 <?xml version="1.0" encoding="UTF-16"?>
123 <foo>\uF8D2</foo>
124 '''
125 self.assertEquals(expected,
126 unicode(str(res), 'UTF-16'))
127
129 tree = self.parse(u'<a><b>\uF8D2</b><c>\uF8D2</c></a>')
130 style = self.parse('''\
131 <xsl:stylesheet version="1.0"
132 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
133 <xsl:output encoding="UTF-8"/>
134 <xsl:template match="/">
135 <foo><xsl:value-of select="/a/b/text()" /></foo>
136 </xsl:template>
137 </xsl:stylesheet>''')
138
139 st = etree.XSLT(style)
140 res = st(tree)
141 expected = u"""\
142 <?xml version='1.0' encoding='UTF-16'?>\
143 <foo>\uF8D2</foo>"""
144
145 f = StringIO()
146 res.write(f, encoding='UTF-16')
147 result = unicode(f.getvalue(), 'UTF-16').replace('\n', '')
148 self.assertEquals(expected,
149 result)
150
152 tree = self.parse(u'<a><b>\uF8D2</b><c>\uF8D2</c></a>')
153 style = self.parse('''\
154 <xsl:stylesheet version="1.0"
155 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
156 <xsl:output encoding="UTF-16"/>
157 <xsl:template match="/">
158 <foo><xsl:value-of select="/a/b/text()" /></foo>
159 </xsl:template>
160 </xsl:stylesheet>''')
161
162 st = etree.XSLT(style)
163 res = st(tree)
164 expected = u'''\
165 <?xml version="1.0"?>
166 <foo>\uF8D2</foo>
167 '''
168 self.assertEquals(expected,
169 unicode(res))
170
172 tree = self.parse('<a><b>B</b><c>C</c></a>')
173 style = self.parse('''\
174 <xsl:stylesheet version="1.0"
175 xmlns:str="http://exslt.org/strings"
176 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
177 exclude-result-prefixes="str xsl">
178 <xsl:template match="text()">
179 <xsl:value-of select="str:align(string(.), '***', 'center')" />
180 </xsl:template>
181 <xsl:template match="*">
182 <xsl:copy>
183 <xsl:apply-templates/>
184 </xsl:copy>
185 </xsl:template>
186 </xsl:stylesheet>''')
187
188 st = etree.XSLT(style)
189 res = st(tree)
190 self.assertEquals('''\
191 <?xml version="1.0"?>
192 <a><b>*B*</b><c>*C*</c></a>
193 ''',
194 str(res))
195
196 if etree.LIBXSLT_VERSION >= (1,1,21):
198 tree = self.parse('<a><b>B</b><c>C</c></a>')
199 style = self.parse('''\
200 <xsl:stylesheet version = "1.0"
201 xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
202 xmlns:str="http://exslt.org/strings"
203 extension-element-prefixes="str">
204
205 <xsl:template match="/">
206 <h1 class="{str:replace('abc', 'b', 'x')}">test</h1>
207 </xsl:template>
208
209 </xsl:stylesheet>''')
210
211 st = etree.XSLT(style)
212 res = st(tree)
213 self.assertEquals('''\
214 <?xml version="1.0"?>
215 <h1 class="axc">test</h1>
216 ''',
217 str(res))
218
220 tree = self.parse('<a><b>B</b><c>C</c></a>')
221 style = self.parse('''\
222 <xsl:stylesheet version="1.0"
223 xmlns:math="http://exslt.org/math"
224 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
225 exclude-result-prefixes="math xsl">
226 <xsl:template match="*">
227 <xsl:copy>
228 <xsl:attribute name="pi">
229 <xsl:value-of select="math:constant('PI', count(*)+2)"/>
230 </xsl:attribute>
231 <xsl:apply-templates/>
232 </xsl:copy>
233 </xsl:template>
234 </xsl:stylesheet>''')
235
236 st = etree.XSLT(style)
237 res = st(tree)
238 self.assertEquals('''\
239 <?xml version="1.0"?>
240 <a pi="3.14"><b pi="3">B</b><c pi="3">C</c></a>
241 ''',
242 str(res))
243
256
273
275 tree = self.parse('<a/>')
276 style = self.parse('''\
277 <xsl:stylesheet version="1.0"
278 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
279 <xsl:foo />
280 </xsl:stylesheet>''')
281 self.assertRaises(etree.XSLTParseError,
282 etree.XSLT, style)
283
285 tree = self.parse('<a><b>B</b><c>C</c></a>')
286 style = self.parse('''\
287 <xsl:stylesheet version="1.0"
288 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
289 <xsl:template match="/">
290 <foo><xsl:value-of select="$bar" /></foo>
291 </xsl:template>
292 </xsl:stylesheet>''')
293
294 st = etree.XSLT(style)
295 res = st(tree, bar="'Bar'")
296 self.assertEquals('''\
297 <?xml version="1.0"?>
298 <foo>Bar</foo>
299 ''',
300 str(res))
301
302 if etree.LIBXSLT_VERSION < (1,1,18):
303
305
306 tree = self.parse('<a><b>B</b><c>C</c></a>')
307 style = self.parse('''\
308 <xsl:stylesheet version="1.0"
309 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
310 <xsl:template match="/">
311 <foo><xsl:value-of select="$bar" /></foo>
312 </xsl:template>
313 </xsl:stylesheet>''')
314
315 st = etree.XSLT(style)
316 self.assertRaises(etree.XSLTApplyError,
317 st.apply, tree)
318
320 tree = self.parse('<a><b>B</b><c>C</c></a>')
321 style = self.parse('''\
322 <xsl:stylesheet version="1.0"
323 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
324 <xsl:template match="*" />
325 <xsl:template match="/">
326 <foo><xsl:value-of select="$bar" /></foo>
327 <foo><xsl:value-of select="$baz" /></foo>
328 </xsl:template>
329 </xsl:stylesheet>''')
330
331 st = etree.XSLT(style)
332 res = st(tree, bar="'Bar'", baz="'Baz'")
333 self.assertEquals('''\
334 <?xml version="1.0"?>
335 <foo>Bar</foo><foo>Baz</foo>
336 ''',
337 str(res))
338
340 tree = self.parse('<a><b>B</b><c>C</c></a>')
341 style = self.parse('''\
342 <xsl:stylesheet version="1.0"
343 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
344 <xsl:template match="*" />
345 <xsl:template match="/">
346 <foo><xsl:value-of select="$bar" /></foo>
347 </xsl:template>
348 </xsl:stylesheet>''')
349
350 st = etree.XSLT(style)
351 res = st(tree, bar="/a/b/text()")
352 self.assertEquals('''\
353 <?xml version="1.0"?>
354 <foo>B</foo>
355 ''',
356 str(res))
357
358
360 tree = self.parse('<a><b>B</b><c>C</c></a>')
361 style = self.parse('''\
362 <xsl:stylesheet version="1.0"
363 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
364 <xsl:param name="bar" select="'Default'" />
365 <xsl:template match="*" />
366 <xsl:template match="/">
367 <foo><xsl:value-of select="$bar" /></foo>
368 </xsl:template>
369 </xsl:stylesheet>''')
370
371 st = etree.XSLT(style)
372 res = st(tree, bar="'Bar'")
373 self.assertEquals('''\
374 <?xml version="1.0"?>
375 <foo>Bar</foo>
376 ''',
377 str(res))
378 res = st(tree)
379 self.assertEquals('''\
380 <?xml version="1.0"?>
381 <foo>Default</foo>
382 ''',
383 str(res))
384
386 tree = self.parse('<a><b>B</b><c>C</c></a>')
387 style = self.parse('''\
388 <xsl:stylesheet version="1.0"
389 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
390 <xsl:output method="html"/>
391 <xsl:strip-space elements="*"/>
392 <xsl:template match="/">
393 <html><body><xsl:value-of select="/a/b/text()" /></body></html>
394 </xsl:template>
395 </xsl:stylesheet>''')
396
397 st = etree.XSLT(style)
398 res = st(tree)
399 self.assertEquals('''<html><body>B</body></html>''',
400 str(res).strip())
401
405
411
434
459
461
462 xml = '<blah/>'
463 xslt = '''
464 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
465 <xsl:template match="/" />
466 </xsl:stylesheet>
467 '''
468
469 source = self.parse(xml)
470 styledoc = self.parse(xslt)
471 style = etree.XSLT(styledoc)
472 result = style(source)
473 self.assertEqual('', str(result))
474
476 xml = '<blah/>'
477 xslt = '''
478 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
479 <xsl:template match="/">
480 <xsl:message>TEST TEST TEST</xsl:message>
481 </xsl:template>
482 </xsl:stylesheet>
483 '''
484
485 source = self.parse(xml)
486 styledoc = self.parse(xslt)
487 style = etree.XSLT(styledoc)
488 result = style(source)
489 self.assertEqual('', str(result))
490 self.assert_("TEST TEST TEST" in [entry.message
491 for entry in style.error_log])
492
494 xml = '<blah/>'
495 xslt = '''
496 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
497 <xsl:template match="/">
498 <xsl:message terminate="yes">TEST TEST TEST</xsl:message>
499 </xsl:template>
500 </xsl:stylesheet>
501 '''
502
503 source = self.parse(xml)
504 styledoc = self.parse(xslt)
505 style = etree.XSLT(styledoc)
506 result = style(source)
507 self.assertEqual('', str(result))
508 self.assert_("TEST TEST TEST" in [entry.message
509 for entry in style.error_log])
510
512 tree = self.parse('<a><b>B</b><c>C</c></a>')
513 style = self.parse('''\
514 <xsl:stylesheet version="1.0"
515 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
516 <xsl:template match="*" />
517 <xsl:template match="/">
518 <doc>
519 <foo><xsl:value-of select="$bar" /></foo>
520 <foo><xsl:value-of select="$baz" /></foo>
521 </doc>
522 </xsl:template>
523 </xsl:stylesheet>''')
524
525 result = tree.xslt(style, bar="'Bar'", baz="'Baz'")
526 self.assertEquals(
527 '<doc><foo>Bar</foo><foo>Baz</foo></doc>',
528 etree.tostring(result.getroot()))
529
531 tree = self.parse('<a><b>B</b><c>C</c></a>')
532 style = self.parse('''\
533 <xsl:stylesheet version="1.0"
534 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
535 <xsl:template match="a"><A><xsl:apply-templates/></A></xsl:template>
536 <xsl:template match="b"><B><xsl:apply-templates/></B></xsl:template>
537 <xsl:template match="c"><C><xsl:apply-templates/></C></xsl:template>
538 </xsl:stylesheet>''')
539
540 self.assertEquals(self._rootstring(tree),
541 '<a><b>B</b><c>C</c></a>')
542 result = tree.xslt(style)
543 self.assertEquals(self._rootstring(tree),
544 '<a><b>B</b><c>C</c></a>')
545 self.assertEquals(self._rootstring(result),
546 '<A><B>B</B><C>C</C></A>')
547
548 b_tree = etree.ElementTree(tree.getroot()[0])
549 self.assertEquals(self._rootstring(b_tree),
550 '<b>B</b>')
551 result = b_tree.xslt(style)
552 self.assertEquals(self._rootstring(tree),
553 '<a><b>B</b><c>C</c></a>')
554 self.assertEquals(self._rootstring(result),
555 '<B>B</B>')
556
557 c_tree = etree.ElementTree(tree.getroot()[1])
558 self.assertEquals(self._rootstring(c_tree),
559 '<c>C</c>')
560 result = c_tree.xslt(style)
561 self.assertEquals(self._rootstring(tree),
562 '<a><b>B</b><c>C</c></a>')
563 self.assertEquals(self._rootstring(result),
564 '<C>C</C>')
565
567 tree = self.parse('<a><b>B</b></a>')
568 style = self.parse('''\
569 <xsl:stylesheet version="1.0"
570 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
571 xmlns:myns="testns"
572 exclude-result-prefixes="myns">
573 <xsl:template match="a"><A><xsl:value-of select="myns:mytext(b)"/></A></xsl:template>
574 </xsl:stylesheet>''')
575
576 def mytext(ctxt, values):
577 return 'X' * len(values)
578
579 result = tree.xslt(style, {('testns', 'mytext') : mytext})
580 self.assertEquals(self._rootstring(result),
581 '<A>X</A>')
582
584 tree = self.parse('<a><b>B</b></a>')
585 style = self.parse('''\
586 <xsl:stylesheet version="1.0"
587 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
588 xmlns:myns="testns"
589 exclude-result-prefixes="myns">
590 <xsl:template match="a"><A><xsl:value-of select="myns:mytext(b)"/></A></xsl:template>
591 </xsl:stylesheet>''')
592
593 def mytext(ctxt, values):
594 return 'X' * len(values)
595
596 namespace = etree.FunctionNamespace('testns')
597 namespace['mytext'] = mytext
598
599 result = tree.xslt(style)
600 self.assertEquals(self._rootstring(result),
601 '<A>X</A>')
602
604 tree = self.parse('<a><b>B</b></a>')
605 style = self.parse('''\
606 <xsl:stylesheet version="1.0"
607 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
608 xmlns:myns="testns"
609 extension-element-prefixes="myns"
610 exclude-result-prefixes="myns">
611 <xsl:template match="a">
612 <A><myns:myext>b</myns:myext></A>
613 </xsl:template>
614 </xsl:stylesheet>''')
615
616 class MyExt(etree.XSLTExtension):
617 def execute(self, context, self_node, input_node, output_parent):
618 child = etree.Element(self_node.text)
619 child.text = 'X'
620 output_parent.append(child)
621
622 extensions = { ('testns', 'myext') : MyExt() }
623
624 result = tree.xslt(style, extensions=extensions)
625 self.assertEquals(self._rootstring(result),
626 '<A><b>X</b></A>')
627
629 tree = self.parse('<a><b>B</b></a>')
630 style = self.parse('''\
631 <xsl:stylesheet version="1.0"
632 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
633 xmlns:myns="testns"
634 extension-element-prefixes="myns">
635 <xsl:template match="a">
636 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A>
637 </xsl:template>
638 </xsl:stylesheet>''')
639
640 class MyExt(etree.XSLTExtension):
641 def execute(self, context, self_node, input_node, output_parent):
642 output_parent.extend(list(self_node)[1:])
643
644 extensions = { ('testns', 'myext') : MyExt() }
645
646 result = tree.xslt(style, extensions=extensions)
647 self.assertEquals(self._rootstring(result),
648 '<A><y>Y</y><z/></A>')
649
651 tree = self.parse('<a><b>B</b></a>')
652 style = self.parse('''\
653 <xsl:stylesheet version="1.0"
654 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
655 xmlns:myns="testns"
656 extension-element-prefixes="myns">
657 <xsl:template match="a">
658 <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A>
659 </xsl:template>
660 <xsl:template match="x" />
661 <xsl:template match="z">XYZ</xsl:template>
662 </xsl:stylesheet>''')
663
664 class MyExt(etree.XSLTExtension):
665 def execute(self, context, self_node, input_node, output_parent):
666 for child in self_node:
667 for result in self.apply_templates(context, child):
668 if isinstance(result, basestring):
669 el = etree.Element("T")
670 el.text = result
671 else:
672 el = result
673 output_parent.append(el)
674
675 extensions = { ('testns', 'myext') : MyExt() }
676
677 result = tree.xslt(style, extensions=extensions)
678 self.assertEquals(self._rootstring(result),
679 '<A><T>Y</T><T>XYZ</T></A>')
680
682 tree = self.parse('<a><b>B</b></a>')
683 style = self.parse('''\
684 <xsl:stylesheet version="1.0"
685 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
686 xmlns:myns="testns"
687 extension-element-prefixes="myns"
688 exclude-result-prefixes="myns">
689 <xsl:template match="a">
690 <A><myns:myext>b</myns:myext></A>
691 </xsl:template>
692 </xsl:stylesheet>''')
693
694 class MyError(Exception):
695 pass
696
697 class MyExt(etree.XSLTExtension):
698 def execute(self, context, self_node, input_node, output_parent):
699 raise MyError("expected!")
700
701 extensions = { ('testns', 'myext') : MyExt() }
702 self.assertRaises(MyError, tree.xslt, style, extensions=extensions)
703
705
706 xslt = etree.XSLT(etree.XML("""\
707 <xsl:stylesheet version="1.0"
708 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
709 <xsl:template match="/">
710 <test>TEXT<xsl:copy-of select="document('')//test"/></test>
711 </xsl:template>
712 </xsl:stylesheet>
713 """))
714 result = xslt(etree.XML('<a/>'))
715 root = result.getroot()
716 self.assertEquals(root.tag,
717 'test')
718 self.assertEquals(root[0].tag,
719 'test')
720 self.assertEquals(root[0].text,
721 'TEXT')
722 self.assertEquals(root[0][0].tag,
723 '{http://www.w3.org/1999/XSL/Transform}copy-of')
724
734
744
746 xslt = etree.XSLT(etree.XML("""\
747 <xsl:stylesheet version="1.0"
748 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
749 <xsl:template match="/">
750 <test>TEXT<xsl:copy-of select="document('uri:__junkfood__is__evil__')//test"/></test>
751 </xsl:template>
752 </xsl:stylesheet>
753 """))
754 self.assertRaises(etree.XSLTApplyError, xslt, etree.XML('<a/>'))
755
757
758 assertEquals = self.assertEquals
759 called = {'count' : 0}
760 class TestResolver(etree.Resolver):
761 def resolve(self, url, id, context):
762 assertEquals(url, 'file://ANYTHING')
763 called['count'] += 1
764 return self.resolve_string('<CALLED/>', context)
765
766 parser = etree.XMLParser()
767 parser.resolvers.add(TestResolver())
768
769 xslt = etree.XSLT(etree.XML("""\
770 <xsl:stylesheet version="1.0"
771 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
772 xmlns:l="local">
773 <xsl:template match="/">
774 <test>
775 <xsl:for-each select="document('')//l:data/l:entry">
776 <xsl:copy-of select="document('file://ANYTHING')"/>
777 <xsl:copy>
778 <xsl:attribute name="value">
779 <xsl:value-of select="."/>
780 </xsl:attribute>
781 </xsl:copy>
782 </xsl:for-each>
783 </test>
784 </xsl:template>
785 <l:data>
786 <l:entry>A</l:entry>
787 <l:entry>B</l:entry>
788 </l:data>
789 </xsl:stylesheet>
790 """, parser))
791
792 self.assertEquals(called['count'], 0)
793 result = xslt(etree.XML('<a/>'))
794 self.assertEquals(called['count'], 1)
795
796 root = result.getroot()
797 self.assertEquals(root.tag,
798 'test')
799 self.assertEquals(len(root), 4)
800
801 self.assertEquals(root[0].tag,
802 'CALLED')
803 self.assertEquals(root[1].tag,
804 '{local}entry')
805 self.assertEquals(root[1].text,
806 None)
807 self.assertEquals(root[1].get("value"),
808 'A')
809 self.assertEquals(root[2].tag,
810 'CALLED')
811 self.assertEquals(root[3].tag,
812 '{local}entry')
813 self.assertEquals(root[3].text,
814 None)
815 self.assertEquals(root[3].get("value"),
816 'B')
817
828
834
840
842 root = etree.XML('''\
843 <transform>
844 <widget displayType="fieldset"/>
845 </transform>''')
846
847 xslt = etree.XSLT(etree.XML('''\
848 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
849 <xsl:output method="html" indent="no"/>
850 <xsl:template match="/">
851 <html>
852 <xsl:apply-templates/>
853 </html>
854 </xsl:template>
855
856 <xsl:template match="widget">
857 <xsl:element name="{@displayType}"/>
858 </xsl:template>
859
860 </xsl:stylesheet>'''))
861
862 result = xslt(root[0])
863 root[:] = result.getroot()[:]
864 del root
865
867 tree = self.parse('''\
868 <?xml version="1.0"?>
869 <?xml-stylesheet type="text/xsl" href="%s"?>
870 <a>
871 <b>B</b>
872 <c>C</c>
873 </a>''' % fileInTestDir("test1.xslt"))
874
875 style_root = tree.getroot().getprevious().parseXSL().getroot()
876 self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet",
877 style_root.tag)
878
880
881 tree = self.parse('''\
882 <?xml version="1.0"?>
883 <?xml-stylesheet type="text/xsl" href="#style"?>
884 <a>
885 <b>B</b>
886 <c>C</c>
887 <xsl:stylesheet version="1.0" xml:id="style"
888 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
889 <xsl:template match="*" />
890 <xsl:template match="/">
891 <foo><xsl:value-of select="/a/b/text()" /></foo>
892 </xsl:template>
893 </xsl:stylesheet>
894 </a>''')
895
896 style_root = tree.getroot().getprevious().parseXSL().getroot()
897 self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet",
898 style_root.tag)
899
900 st = etree.XSLT(style_root)
901 res = st(tree)
902 self.assertEquals('''\
903 <?xml version="1.0"?>
904 <foo>B</foo>
905 ''',
906 str(res))
907
909
910 tree = self.parse('''\
911 <?xml version="1.0"?>
912 <?xml-stylesheet type="text/xsl" href="#style"?>
913 <a>
914 <b>B</b>
915 <c>C</c>
916 </a>''')
917
918 style = self.parse('''\
919 <xsl:stylesheet version="1.0" xml:id="style"
920 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
921 <xsl:template match="*" />
922 <xsl:template match="/">
923 <foo><xsl:value-of select="/a/b/text()" /></foo>
924 </xsl:template>
925 </xsl:stylesheet>
926 ''')
927
928 tree.getroot().append(style.getroot())
929
930 style_root = tree.getroot().getprevious().parseXSL().getroot()
931 self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet",
932 style_root.tag)
933
934 st = etree.XSLT(style_root)
935 res = st(tree)
936 self.assertEquals('''\
937 <?xml version="1.0"?>
938 <foo>B</foo>
939 ''',
940 str(res))
941
943 tree = self.parse('''\
944 <?xml version="1.0"?>
945 <?xml-stylesheet type="text/xsl" href="TEST"?>
946 <a>
947 <b>B</b>
948 <c>C</c>
949 </a>''')
950
951 pi = tree.getroot().getprevious()
952 self.assertEquals("TEST", pi.get("href"))
953
955 tree = self.parse('''\
956 <?xml version="1.0"?>
957 <?xml-stylesheet type="text/xsl" href="TEST"?>
958 <a>
959 <b>B</b>
960 <c>C</c>
961 </a>''')
962
963 pi = tree.getroot().getprevious()
964 self.assertEquals("TEST", pi.get("href"))
965 self.assertEquals("text/xsl", pi.get("type"))
966 self.assertEquals(None, pi.get("motz"))
967
969 tree = self.parse('''\
970 <?xml version="1.0"?>
971 <?xml-stylesheet href="TEST" type="text/xsl"?>
972 <a>
973 <b>B</b>
974 <c>C</c>
975 </a>''')
976
977 pi = tree.getroot().getprevious()
978 self.assertEquals("TEST", pi.get("href"))
979 self.assertEquals("text/xsl", pi.get("type"))
980 self.assertEquals(None, pi.get("motz"))
981
983 tree = self.parse('''\
984 <?xml version="1.0"?>
985 <?xml-stylesheet type="text/xsl" href="TEST"?>
986 <a>
987 <b>B</b>
988 <c>C</c>
989 </a>''')
990
991 pi = tree.getroot().getprevious()
992 self.assertEquals(None, pi.get("unknownattribute"))
993
995 tree = self.parse('''\
996 <?xml version="1.0"?>
997 <?xml-stylesheet type="text/xsl" href="TEST"?>
998 <a>
999 <b>B</b>
1000 <c>C</c>
1001 </a>''')
1002
1003 pi = tree.getroot().getprevious()
1004 self.assertEquals("TEST", pi.get("href"))
1005
1006 pi.set("href", "TEST123")
1007 self.assertEquals("TEST123", pi.get("href"))
1008
1010 tree = self.parse('''\
1011 <?xml version="1.0"?>
1012 <?xml-stylesheet type="text/xsl"?>
1013 <a>
1014 <b>B</b>
1015 <c>C</c>
1016 </a>''')
1017
1018 pi = tree.getroot().getprevious()
1019 self.assertEquals(None, pi.get("href"))
1020
1021 pi.set("href", "TEST")
1022 self.assertEquals("TEST", pi.get("href"))
1023
1025 xslt = etree.XSLT(etree.XML("""\
1026 <xsl:stylesheet version="1.0"
1027 xmlns:regexp="http://exslt.org/regular-expressions"
1028 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
1029 <xsl:template match="*">
1030 <test><xsl:copy-of select="*[regexp:test(string(.), '8.')]"/></test>
1031 </xsl:template>
1032 </xsl:stylesheet>
1033 """))
1034 result = xslt(etree.XML('<a><b>123</b><b>098</b><b>987</b></a>'))
1035 root = result.getroot()
1036 self.assertEquals(root.tag,
1037 'test')
1038 self.assertEquals(len(root), 1)
1039 self.assertEquals(root[0].tag,
1040 'b')
1041 self.assertEquals(root[0].text,
1042 '987')
1043
1045 xslt = etree.XSLT(etree.XML("""\
1046 <xsl:stylesheet version="1.0"
1047 xmlns:regexp="http://exslt.org/regular-expressions"
1048 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
1049 <xsl:template match="*">
1050 <test>
1051 <xsl:copy-of select="regexp:replace(string(.), 'd.', '', 'XX')"/>
1052 <xsl:text>-</xsl:text>
1053 <xsl:copy-of select="regexp:replace(string(.), 'd.', 'gi', 'XX')"/>
1054 </test>
1055 </xsl:template>
1056 </xsl:stylesheet>
1057 """))
1058 result = xslt(etree.XML('<a>abdCdEeDed</a>'))
1059 root = result.getroot()
1060 self.assertEquals(root.tag,
1061 'test')
1062 self.assertEquals(len(root), 0)
1063 self.assertEquals(root.text, 'abXXdEeDed-abXXXXeXXd')
1064
1066 xslt = etree.XSLT(etree.XML("""\
1067 <xsl:stylesheet version="1.0"
1068 xmlns:regexp="http://exslt.org/regular-expressions"
1069 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
1070 <xsl:template match="*">
1071 <test>
1072 <test1><xsl:copy-of select="regexp:match(string(.), 'd.')"/></test1>
1073 <test2><xsl:copy-of select="regexp:match(string(.), 'd.', 'g')"/></test2>
1074 <test2i><xsl:copy-of select="regexp:match(string(.), 'd.', 'gi')"/></test2i>
1075 </test>
1076 </xsl:template>
1077 </xsl:stylesheet>
1078 """))
1079 result = xslt(etree.XML('<a>abdCdEeDed</a>'))
1080 root = result.getroot()
1081 self.assertEquals(root.tag, 'test')
1082 self.assertEquals(len(root), 3)
1083
1084 self.assertEquals(len(root[0]), 1)
1085 self.assertEquals(root[0][0].tag, 'match')
1086 self.assertEquals(root[0][0].text, 'dC')
1087
1088 self.assertEquals(len(root[1]), 2)
1089 self.assertEquals(root[1][0].tag, 'match')
1090 self.assertEquals(root[1][0].text, 'dC')
1091 self.assertEquals(root[1][1].tag, 'match')
1092 self.assertEquals(root[1][1].text, 'dE')
1093
1094 self.assertEquals(len(root[2]), 3)
1095 self.assertEquals(root[2][0].tag, 'match')
1096 self.assertEquals(root[2][0].text, 'dC')
1097 self.assertEquals(root[2][1].tag, 'match')
1098 self.assertEquals(root[2][1].text, 'dE')
1099 self.assertEquals(root[2][2].tag, 'match')
1100 self.assertEquals(root[2][2].text, 'De')
1101
1103 xslt = etree.XSLT(etree.XML("""\
1104 <xsl:stylesheet version="1.0"
1105 xmlns:regexp="http://exslt.org/regular-expressions"
1106 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
1107 <xsl:template match="/">
1108 <test>
1109 <xsl:for-each select="regexp:match(
1110 '123abc567', '([0-9]+)([a-z]+)([0-9]+)' )">
1111 <test1><xsl:value-of select="."/></test1>
1112 </xsl:for-each>
1113 </test>
1114 </xsl:template>
1115 </xsl:stylesheet>
1116 """))
1117 result = xslt(etree.XML('<a/>'))
1118 root = result.getroot()
1119 self.assertEquals(root.tag, 'test')
1120 self.assertEquals(len(root), 4)
1121
1122 self.assertEquals(root[0].text, "123abc567")
1123 self.assertEquals(root[1].text, "123")
1124 self.assertEquals(root[2].text, "abc")
1125 self.assertEquals(root[3].text, "567")
1126
1128
1129 xslt = etree.XSLT(etree.XML("""\
1130 <xsl:stylesheet version="1.0"
1131 xmlns:regexp="http://exslt.org/regular-expressions"
1132 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
1133 <xsl:template match="/">
1134 <test>
1135 <xsl:for-each select="regexp:match(
1136 'http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml',
1137 '(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)')">
1138 <test1><xsl:value-of select="."/></test1>
1139 </xsl:for-each>
1140 </test>
1141 </xsl:template>
1142 </xsl:stylesheet>
1143 """))
1144 result = xslt(etree.XML('<a/>'))
1145 root = result.getroot()
1146 self.assertEquals(root.tag, 'test')
1147 self.assertEquals(len(root), 5)
1148
1149 self.assertEquals(
1150 root[0].text,
1151 "http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml")
1152 self.assertEquals(
1153 root[1].text,
1154 "http")
1155 self.assertEquals(
1156 root[2].text,
1157 "www.bayes.co.uk")
1158 self.assertFalse(root[3].text)
1159 self.assertEquals(
1160 root[4].text,
1161 "/xml/index.xml?/xml/utils/rechecker.xml")
1162
1164
1165 xslt = etree.XSLT(etree.XML("""\
1166 <xsl:stylesheet version="1.0"
1167 xmlns:regexp="http://exslt.org/regular-expressions"
1168 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
1169 <xsl:template match="/">
1170 <test>
1171 <xsl:for-each select="regexp:match(
1172 'This is a test string', '(\w+)', 'g')">
1173 <test1><xsl:value-of select="."/></test1>
1174 </xsl:for-each>
1175 </test>
1176 </xsl:template>
1177 </xsl:stylesheet>
1178 """))
1179 result = xslt(etree.XML('<a/>'))
1180 root = result.getroot()
1181 self.assertEquals(root.tag, 'test')
1182 self.assertEquals(len(root), 5)
1183
1184 self.assertEquals(root[0].text, "This")
1185 self.assertEquals(root[1].text, "is")
1186 self.assertEquals(root[2].text, "a")
1187 self.assertEquals(root[3].text, "test")
1188 self.assertEquals(root[4].text, "string")
1189
1191
1192
1193 xslt = etree.XSLT(etree.XML("""\
1194 <xsl:stylesheet version="1.0"
1195 xmlns:regexp="http://exslt.org/regular-expressions"
1196 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
1197 <xsl:template match="/">
1198 <test>
1199 <xsl:for-each select="regexp:match(
1200 'This is a test string', '([a-z])+ ', 'g')">
1201 <test1><xsl:value-of select="."/></test1>
1202 </xsl:for-each>
1203 </test>
1204 </xsl:template>
1205 </xsl:stylesheet>
1206 """))
1207 result = xslt(etree.XML('<a/>'))
1208 root = result.getroot()
1209 self.assertEquals(root.tag, 'test')
1210 self.assertEquals(len(root), 4)
1211
1212 self.assertEquals(root[0].text, "his")
1213 self.assertEquals(root[1].text, "is")
1214 self.assertEquals(root[2].text, "a")
1215 self.assertEquals(root[3].text, "test")
1216
1218
1219
1220 xslt = etree.XSLT(etree.XML("""\
1221 <xsl:stylesheet version="1.0"
1222 xmlns:regexp="http://exslt.org/regular-expressions"
1223 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
1224 <xsl:template match="/">
1225 <test>
1226 <xsl:for-each select="regexp:match(
1227 'This is a test string', '([a-z])+ ', 'gi')">
1228 <test1><xsl:value-of select="."/></test1>
1229 </xsl:for-each>
1230 </test>
1231 </xsl:template>
1232 </xsl:stylesheet>
1233 """))
1234 result = xslt(etree.XML('<a/>'))
1235 root = result.getroot()
1236 self.assertEquals(root.tag, 'test')
1237 self.assertEquals(len(root), 4)
1238
1239 self.assertEquals(root[0].text, "This")
1240 self.assertEquals(root[1].text, "is")
1241 self.assertEquals(root[2].text, "a")
1242 self.assertEquals(root[3].text, "test")
1243
1245 suite = unittest.TestSuite()
1246 suite.addTests([unittest.makeSuite(ETreeXSLTTestCase)])
1247 suite.addTests(
1248 [doctest.DocFileSuite('../../../doc/extensions.txt')])
1249 suite.addTests(
1250 [doctest.DocFileSuite('../../../doc/xpathxslt.txt')])
1251 return suite
1252
1253 if __name__ == '__main__':
1254 print 'to test use test.py %s' % __file__
1255