xslt 样式表中的执行顺序
假设我有一个如下所示的 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)。
Lets say I have a xslt stylesheet like the following:
<?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>
What is the order of execution here? Is it guaranteed that global variable $foo will evaluate before global variable $bar? (If it's dependent on the processing engine, I'm using libxslt).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一般来说,不保证求值的顺序,除非这种保证来自表达式的依赖关系。例如:
在这里,可以肯定
baz
将在输出之前的某个时刻进行评估 - 也许仅在输出之前,也许在启动时,也许在两者之间 - 以及foo
和bar
将在baz
之前计算 - 但foo
和bar
的计算相对顺序没有定义。dummy
是一个有趣的案例。它实际上并没有在任何地方使用,因此可以完全省略,但是,如果我对规范的理解是正确的,处理器仍然必须引发错误,就像它被评估一样。它在哪一点这样做并不重要,因为没有办法从 XSLT 内部判断 - 所以dummy
将在执行期间的某个未指定的时刻进行评估(可能是它做的第一件事,也可能是最后一件事情)在所有输出已经生成之后),但肯定会导致转换失败并出现错误。这就是关于 XSLT 和 XPath 1.0 的全部内容。在 2.0 中,情况更加宽松——甚至根本不需要进行评估;如果处理器可以通过跳过某些表达式的求值来获得有效结果,否则它们会导致错误,则它具有这样做的全面权限。
The order of evaluation is, in general, not guaranteed except where such guarantees follow from dependencies of expressions. For example:
Here, it is certain that
baz
will get evaluated at some point prior to being output -maybe only immediately before being output, maybe at startup, maybe somewhere in between - and thatfoo
andbar
will be evaluated beforebaz
- but the relative order of evaluation forfoo
andbar
is not defined.dummy
is an interesting case. It's not actually used anywhere, and so could be omitted entirely, but, if my understanding of the spec is correct, the processor must nonetheless raise an error as if it was evaluated. At which point it does so is not important, because there's no way to tell from inside XSLT - sodummy
will be evaluated at some unspecified moment during execution (could be the first thing it does, or the last after all output is already generated), but is guaranteed to cause the transformation to fail with an error.This is all about XSLT and XPath 1.0. In 2.0, it is more relaxed - evaluation isn't even required to happen at all; if processor can obtain a valid result by skipping evaluation of some expressions where otherwise they would result in error, it has a blanket permission to do so.
根据我的经验,执行模板时变量始终可用。事实上,我已经根据模板外部的变量处理了模板。
From my experience the variables are always available when the templates are executed. In fact I've processed templates based off of variables outside of templates.
在模板中,变量定义将按从上到下的顺序执行(
foo
然后bar
)编辑[删除不正确的语句]:正如 Pavel 所解释的此处,在这种情况下,XSLT 具有明确定义的行为,规定如何评估变量。特别是,以下测试用例说明了您所询问的行为。
一个好的测试用例可能是使一个变量依赖于另一个变量......例如
然后可能将变量打印到屏幕上。
顺序也可以颠倒(例如)
就其价值而言,我认为您的意思是
select
您在帖子中写入value
的位置。编辑1:
由于 XSLT 中的变量是不可变的,并且由于执行函数 不能产生副作用顺序应该不重要。特别是,顺序重要时可能出现的唯一条件是我的简单插图中的条件(您应该将其作为测试运行以确保),其中一个变量取决于另一个变量的值。
编辑2:修复了示例“代码”中的一个错误
Within a template the variable definitions will execute in top to bottom order (
foo
thenbar
)Edit [incorrect statement removed]: As Pavel explains here, XSLT has well defined behavior in this case that stipulates how the variables will be evaluated. In particular, the following test cases illustrate the behavior you're asking about.
A good test case might be to make one variable depend on the other...e.g.
Then maybe print the variables to screen.
The order can be inverted as well (e.g.)
For what it's worth, I think you mean
select
where you wrotevalue
in your post.Edit 1:
Since variables in XSLT are immutable and since executing functions can't have side effects the order shouldn't really matter. In particular, the only condition that could arise where the order matters is the one in my simple illustration (which you should run as a test to be sure) where one variable depends on the value of another.
Edit 2: fixed a goof in the example "code"
我正在与 ajitomatix 合作解决这个问题,真正的问题是:在初始化之后,我们在任何模板之外都有一堆这些变量声明:
只有当我们确保 init 函数时,函数 fun() 才会给出正确的结果之前被叫过。但通过 gdb 中的断点,我发现顺序几乎是随机的。
I am working with ajitomatix on this problem and the real issue is this: we have a bunch of these variable declarations outside of any templates, after an initialization:
The function fun() will give right result only if we make sure that the init function got called before. But through breakpoints in gdb I find the order is near random.