Hi,
> <xsl:stylesheet version="2.0" ...
> <xsl:variable name="test" select="/a:root/@val" as="xs:string"/>
> <xsl:template match="a:root">
> ...
> When I run a standalone xml file with the above xslt it
> transforms fine. When I run it from Xspec however I get the
> following error: 'An empty sequence is not allowed as the value
> of variable $test'. Any idea why?
That's because you can not control the value of the global
variables in a test case. You can set their value once per test
suite, but you can not make them dependent on the context of one
test case:
<x:description ...
<x:param name="test" select="333"/>
<x:scenario label="Namespace test">
...
Personally, I don't think that's big a limitation. If you need
to have their values to change from test cases to test cases,
then you might probably use instead a tunnel param in the tule
for the document node.
Regards,
--
Florent Georges
http://fgeorges.org/
Hi,
> We have a significant number of global variables, I think all
> of them are dependent on the test case they are being invoked
> against.
The only way I see then is to create a separate test suite (a
separate XSpec file) for each different set of global variable
values.
> We also have global, shared, stylesheet params, keys,
> character-maps, functions and global xsl:output declarations -
> are we likely to experience a similar problem with any of
> these?
Except for params (which are the same as variables), no,
because those are static components (the "value" of an output
declaration for instance cannot change depending on the main
input tree).
> If I have a global variable in the XSL:
> <xsl:variable name="test2" as="element()">
> <xsl:sequence select="/a:root/a:secondlevel"/>
> </xsl:variable>
> [...]
> How can I replicate this: <xsl:value-of
> select="$test2/parent::a:root/ @val"/> using an XSpec global
> variable?
There is no mechanism to set the global context for the whole
stylesheet. Just for the one template rule a test case is
testing. The trick is to create a global variable in the XSpec
suite with the same name, which will override the one in the
stylesheet, and to initialize it with the same context:
<x:description ...>
<!-- the context -->
<x:variable name="context">
<a:root val="bbbb">
<a:secondlevel attrValue="nnnn">
<a:b>nnnnnn</a:b>
</a:secondlevel>
</a:root>
</x:variable>
<!-- the global variable, using the context -->
<x:variable name="test" select="$context/@val"/>
<!-- one test case, using the same context -->
<x:scenario label="Namespace test">
<x:context select="$context"/>
<x:expect>
<html>bbbb</html>
</x:expect>
</x:scenario>
</x:description>
If you have a lot of global variable, you can replcae them
from:
<xsl:stylesheet ...>
<xsl:variable name="v1" select="/*/@a"/>
<xsl:variable name="v2" select="/*/*[1]"/>
...
to:
<xsl:stylesheet ...>
<xsl:variable name="input" select="/*"/>
<xsl:variable name="v1" select="$input/@a"/>
<xsl:variable name="v2" select="$input/*[1]"/>
...
so in a specific suite you just have to define the global
variable $input and use it as the context in the test cases:
<x:description ...>
<x:variable name="input">
...
</x:variable>
No. That's different than your previous example, where the
variables were initialized against the main input tree. If they
don't use the main input tree, that's not a problem. But you
haven't showed us how $Var is initialized, so maybe it does
depend on the main input tree after all.
That's also why I suggested to create a variable with the main
input tree root, and make the other variables using it, instead
of using the main input tree directly. So in that case you only
have to create one variable in the test suite, in accordance with
the test case context.
But of course, if you have other variables that don't rely on
the main input tree, then that does change anything for them.