假设我有一个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)。
答案 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}}进行评估,但未定义bar
和baz
的相对评估顺序。
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中的断点,我发现订单几乎是随机的。