The main XSieve commands are x:eval
and x:apply-templates
which correspond to the XSLT functions xsl:copy-of
and xsl:apply-templates
. To make a stress test for the XSieve commands, we can take an XSLT program, convert the XSLT program to an XSieve program and compare results of the XSLT and XSieve programs. Results should be same.
The XSieve program xslt2xsieve.xsl
automatically converts XSLT to XSieve. There are several tests.
In the first test, the XSLT program input.xsl
is converted to the XSieve program tmp-input.xsl
. To check the correctness of the transformation, both the XSLT and XSieve programs are executed against the file input.xml
, and the corresponding output files tmp-output-1.xml
and tmp-output-2.xml
are compared with the etalon file output.xml
.
The second test is similar to the first test. It converts and tests input.xsl
, but converter is not xslt2xsieve.xsl
, but tmp-xslt2xsieve.xsl
, which is xslt2xsieve.xsl
applied to itself.
The grand test is converting and using the DocBook stylesheets. See Section 6.7, “DocBook XSieve stylesheets”.
Example 21. Converting xsl:copy-of
XSLT fragment:
<x:copy-of select="xpath
"/>
XSieve fragment:
<s:scheme>(x:eval "escaped-xpath
")</s:scheme>
Example 22. Converting xsl:value-of
XSLT fragment:
<x:value-of select="xpath
"/>
XSieve fragment:
<s:scheme>(x:string (x:eval "escaped-xpath
"))</s:scheme>
XSieve doesn't support the attribute disable-output-escaping
, so xslt2xsieve
skips xsl:value-of
elements with this attribute.
Example 23. Converting xsl:apply-templates
XSLT fragment:
<x:apply-templates mode="mode
" select="xpath
"> <x:with-param name="param1" select="xpath1
"/> ... <x:with-param name="paramN" select="xpathN
"/> </x:apply-templates>
XSieve fragment:
(x:apply-templates 'mode 'mode
'with-param 'param1 (x:eval "escaped-xpath1
") ... 'with-param 'paramN (x:eval "escaped-xpathN
") (x:eval "escaped-xpath
"))
The attribute mode
and the elements with-param
can be missed. In this case the XSieve code doesn't contain the corresponding fragments.
To be converted to XSieve, an element xsl:apply-templates
should satisfy all the following requirements.
An attribute select
is present.
There is no element xsl:sort
.
All xsl:with-param
elements have an attribute select
.
Example 24. Converting xsl:variable, xsl:param, xsl:with-param
XSLT fragment:
<x:variable name="varname
" select="xpath
"/>
XSLT with XSieve fragment:
<x:variable name="varname
"> <s:scheme>(x:eval "escaped-xpath
")</s:scheme> </x:variable>
For xsl:param
and xsl:with-param
, translation is similar.
This conversion is disabled for two reasons;
It makes the DocBook test very slow.
Sometimes it's incorrect to use a content template instead of the attribute select
.
Example 25. Moving select
is not correct
<x:template match="/*"> <x:variable name="v1" select="false()"/> <x:variable name="v2"><x:copy-of select="false()"/></x:variable> <x> <t1><x:value-of select="not($v1)"/></t1> <t2><x:value-of select="not($v2)"/></t2> </x> </x:template>
Result is the following.
<x><t1>true</t1><t2>false</t2></x>
Variable v2
is a nodeset, not a value, so not($v2)
is false.
In a naive approach, when the value of an attribute select
contains quotes, the corresponding x:eval
raises an error.
Example 26. Incorrect transformation of the attribute select
<x:text>(x:eval "</x:text> <x:value-of select="@select"/> <x:text>")</x:text>
Consider the following source XML.
<... select="concat("'",d,'"')" .../>
Result of the transformation is an incorrect Scheme program.
(x:eval "concat("'",d,'"')")
To make the program correct, it's required to escape quotes. The task is not easy for the plain XSLT, so the xslt2xsieve
program is an XSieve program. The right transformation uses a function written in Scheme.
Example 27. Correct transformation of the attribute select
<x:text>(x:eval "</x:text> <s:scheme>(xlib:escape-for-string (x:string (x:eval "@select")))</s:scheme> <x:text>")</x:text>
The function xlib:escape-for-string
is defined in the file xslt2xsieve.scm
.
The simplest way to create elements is to write them literally. Unfortunately, it's not an option for xslt2xsieve.xsl
because it is an XSieve program, and literal XSieve elements are executed instead of been copied to output.
Example 28. Executing instead of copying
<x:stylesheet ... xmlns:s="http://xsieve.sourceforge.net" extension-element-prefixes="s" ... > ... <x:template match="hello"> <s:scheme> (display "Hello, <x:value-of select="@object"/>") </s:scheme> </x:template>
The XSLT specification recommends to use the xsl:namespace-alias
element to workaround the problem.
Example 29. Using xsl:namespace-alias
<x:stylesheet ... xmlns:s="http://xsieve.sourceforge.net" extension-element-prefixes="s" xmlns:sa="http://xsieve.sourceforge.netAlias" ... > <x:namespace-alias stylesheet-prefix="sa" result-prefix="s"/> ... <x:template match="hello"> <sa:scheme> (display "Hello, <x:value-of select="@object"/>") </sa:scheme> </x:template>
Unfortunately, in the xslt2xsieve
program, using xsl:namespace-alias
doesn't help. Applying the program to itself gives namespace collision, and it's not the fault of XSieve, but the fault of libxslt. A simplified example is submitted as a bug to the libxslt team.
As result, instead of the literal form, the real xslt2xsieve
program uses xsl:element
to create XSieve elements.
A part of generating a correct XSieve program is
defining the XSieve namespace and
and making this namespace an extension namespace.
The corresponding fragment of xslt2xsieve.xsl
follows.
Example 31. Creating an XSieve program heading
<x:template match="x:stylesheet"> <x:copy> <x:copy-of select="@*"/> <x:attribute name="extension-element-prefixes"> <x:value-of select="concat('s ',@extension-element-prefixes)"/> </x:attribute> <x:attribute name="s:dummy"/> <x:apply-templates select="node()"/> </x:copy> </x:template>
Unfortunately, the code isn't 100%-correct. Imagine a situation when input file uses the prefix s
with some URI other than XSieve URI. In this case we get namespace prefix collision, which in general can't be resolved (consider content of extension-element-prefixes
). Hopefully, the possibility of the situation should be very very small.