xslt 样式表中的执行顺序

发布于 2024-08-03 19:20:32 字数 530 浏览 10 评论 0原文

假设我有一个如下所示的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

瀞厅☆埖开 2024-08-10 19:20:32

一般来说,不保证求值的顺序,除非这种保证来自表达式的依赖关系。例如:

<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 将在输出之前的某个时刻进行评估 - 也许仅在输出之前,也许在启动时,也许在两者之间 - 以及 foobar 将在 baz 之前计算 - 但 foobar 的计算相对顺序没有定义。

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:

<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>

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 that foo and bar will be evaluated before baz - but the relative order of evaluation for foo and bar 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 - so dummy 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.

安人多梦 2024-08-10 19:20:32

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

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.

煮茶煮酒煮时光 2024-08-10 19:20:32

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

编辑[删除不正确的语句]:正如 Pavel 所解释的此处,在这种情况下,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 中的变量是不可变的,并且由于执行函数 不能产生副作用顺序应该不重要。特别是,顺序重要时可能出现的唯一条件是我的简单插图中的条件(您应该将其作为测试运行以确保),其中一个变量取决于另一个变量的值。

编辑2:修复了示例“代码”中的一个错误

Within a template the variable definitions will execute in top to bottom order (foo then bar)

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.

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

Then maybe print the variables to screen.

The order can be inverted as well (e.g.)

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

For what it's worth, I think you mean select where you wrote value 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"

2024-08-10 19:20:32

我正在与 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')" />
...

只有当我们确保 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:

<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')" />
...

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文