xslt样式表中的执行顺序

xslt样式表中的执行顺序,xslt,libxslt,Xslt,Libxslt,假设我有一个xslt样式表,如下所示: <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="exslt" version="1.0"> <xsl:output m

假设我有一个xslt样式表,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exslt="http://exslt.org/common"
    exclude-result-prefixes="exslt"
    version="1.0">

<xsl:output method="html" encoding="utf-8" indent="no" />
<xsl:variable name="foo" value="'foo'" />
<xsl:variable name="bar" value="'bar'" />

</xsl:stylesheet>


这里的执行顺序是什么?是否保证全局变量$foo将在全局变量$bar之前求值?(如果依赖于处理引擎,我使用的是libxslt)。

根据我的经验,在执行模板时,变量总是可用的。事实上,我已经根据模板之外的变量处理了模板。

根据我的经验,在执行模板时,变量总是可用的。事实上,我已经根据模板之外的变量处理了模板。

在模板中,变量定义将按从上到下的顺序执行(
foo
然后
bar

Edit[error statement removed]:正如Pavel解释的那样,XSLT在这种情况下具有定义良好的行为,规定了如何计算变量。特别是,以下测试用例说明了您所询问的行为

一个好的测试用例可能是使一个变量依赖于另一个变量

<xsl:variable name="foo" select="'foo'" />
<xsl:variable name="bar" select="$foo" />

然后可能将变量打印到屏幕上

顺序也可以颠倒(例如)


至于它的价值,我想你的意思是
选择
你在帖子中写
value
的地方

编辑1: 因为XSLT中的变量是不可变的,而且执行函数的顺序也不重要。特别是,在顺序很重要的情况下,唯一可能出现的情况是我的简单示例中的一个(您应该将其作为测试来运行),其中一个变量取决于另一个变量的值


编辑2:修复了模板中“代码”示例中的一个错误,变量定义将按自上而下的顺序执行(
foo
然后
bar

Edit[error statement removed]:正如Pavel解释的那样,XSLT在这种情况下具有定义良好的行为,规定了如何计算变量。特别是,以下测试用例说明了您所询问的行为

一个好的测试用例可能是使一个变量依赖于另一个变量

<xsl:variable name="foo" select="'foo'" />
<xsl:variable name="bar" select="$foo" />

然后可能将变量打印到屏幕上

顺序也可以颠倒(例如)


至于它的价值,我想你的意思是
选择
你在帖子中写
value
的地方

编辑1: 因为XSLT中的变量是不可变的,而且执行函数的顺序也不重要。特别是,在顺序很重要的情况下,唯一可能出现的情况是我的简单示例中的一个(您应该将其作为测试来运行),其中一个变量取决于另一个变量的值


编辑2:修复了示例“代码”中的一个错误。通常,计算顺序不受保证,除非这些保证来自表达式的依赖关系。例如:

<xsl:variable name="foo" value="123" />

<xsl:variable name="bar" value="456" />

<xsl:variable name="baz" value="$foo + $bar" />

<xsl:variable name="dummy" value="42 div 0" />

<xsl:template match="/">
  <xsl:value-of select="$baz"/>
</xsl:template>

在这里,可以肯定的是,
baz
将在输出之前的某个点进行评估-可能仅在输出之前,可能在启动时,可能介于两者之间-并且
foo
bar
将在
baz
之前进行评估-但是
foo
bar
的评估相对顺序没有定义

dummy
是一个有趣的例子。它实际上没有在任何地方使用,因此可以完全省略,但是,如果我对规范的理解是正确的,处理器必须像评估它一样发出错误。它在什么时候这样做并不重要,因为无法从XSLT内部进行判断-因此在执行过程中的某个未指定的时刻(可能是它做的第一件事,也可能是生成所有输出后的最后一件事)将对
dummy
进行评估,但肯定会导致转换失败并产生错误


这都是关于XSLT和XPath1.0的。在2.0中,它更为宽松——甚至不需要进行评估;如果处理器可以通过跳过某些表达式的求值来获得有效的结果,否则会导致错误,则处理器有权这样做。

通常不保证求值顺序,除非这些保证来自表达式的依赖项。例如:

<xsl:variable name="foo" value="123" />

<xsl:variable name="bar" value="456" />

<xsl:variable name="baz" value="$foo + $bar" />

<xsl:variable name="dummy" value="42 div 0" />

<xsl:template match="/">
  <xsl:value-of select="$baz"/>
</xsl:template>

在这里,可以肯定的是,
baz
将在输出之前的某个点进行评估-可能仅在输出之前,可能在启动时,可能介于两者之间-并且
foo
bar
将在
baz
之前进行评估-但是
foo
bar
的评估相对顺序没有定义

dummy
是一个有趣的例子。它实际上没有在任何地方使用,因此可以完全省略,但是,如果我对规范的理解是正确的,处理器必须像评估它一样发出错误。它在什么时候这样做并不重要,因为无法从XSLT内部进行判断-因此在执行过程中的某个未指定的时刻(可能是它做的第一件事,也可能是生成所有输出后的最后一件事)将对
dummy
进行评估,但肯定会导致转换失败并产生错误


这都是关于XSLT和XPath1.0的。在2.0中,它更为宽松——甚至不需要进行评估;如果处理器可以通过跳过某些表达式的求值来获得有效的结果,否则会导致错误,那么它拥有这样做的全面许可。

我正在与ajitomatix合作解决这个问题,真正的问题是:初始化后,我们在任何模板之外有一堆变量声明:

<xsl:variable name="ignore" select="fun_init(args)" />
<xsl:variable name="foo1" select="fun('foo1')" />
<xsl:variable name="foo2" select="fun('foo2')" />
<xsl:variable name="foo3" select="fun('foo3')" />
...

...

函数fun()将给出正确的结果,前提是我们确保init函数在之前被调用过。但是通过gdb中的断点,我发现顺序几乎是随机的。

我正在与ajitomati合作