xslt样式表中的执行顺序

时间:2009-09-02 01:56:38

标签: 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 method="html" encoding="utf-8" indent="no" />
<xsl:variable name="foo" value="'foo'" />
<xsl:variable name="bar" value="'bar'" />

</xsl:stylesheet>

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

4 个答案:

答案 0 :(得分:4)

一般而言,评估的顺序并不能保证,除非这些保证遵循表达式的依赖性。例如:

<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和{ {1}}之前将对{1}}进行评估,但未定义barbaz的相对评估顺序。

foo是一个有趣的案例。它实际上并没有在任何地方使用,因此可以完全省略,但是,如果我对规范的理解是正确的,那么处理器必须提出错误,就像它被评估一样。这样做并不重要,因为没有办法从XSLT内部告诉 - 所以bar将在执行期间的某个未指定时刻进行评估(可能是它做的第一件事,或者是所有输出后的最后一件事)已生成),但保证转换失败并显示错误。

这是关于XSLT和XPath 1.0的全部内容。在2.0中,它更加轻松 - 甚至根本不需要进行评估;如果处理器可以通过跳过某些表达式的评估来获得有效结果,否则它们会导致错误,它有一个全面的许可。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

编辑[删除了错误的语句]:正如Pavel解释here,在这种情况下,XSLT具有明确定义的行为,规定了如何评估变量。特别是,以下测试用例说明了您所询问的行为。

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

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

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

顺序也可以反转(例如)

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

对于它的价值,我认为你的意思是select你在帖子中写了value

编辑1: 由于XSLT中的变量是不可变的,并且由于执行函数can't have side effects,因此顺序并不重要。特别是,在订单重要的情况下可能出现的唯一条件是我的简单说明(您应该将其作为测试运行),其中一个变量取决于另一个变量的值。

编辑2:在示例“代码”

中修复了一个混乱

答案 3 :(得分:-1)

我正在使用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中的断点,我发现订单几乎是随机的。