>模板执行的顺序,和
>当它们执行时,它们匹配(a)原始源XML,还是(b)XSLT的当前输出到该点?
例:
<person> <firstName>Deane</firstName> <lastName>Barker</lastName> </person>
这里是XSLT的一个片段:
<!-- Template #1 --> <xsl:template match="/"> <xsl:value-of select="firstName"/> <xsl:value-of select="lastName"/> </xsl:template> <!-- Template #2 --> <xsl:template match="/person/firstName"> First Name: <xsl:value-of select="firstName"/> </xsl:template>
两个问题:
>我假设模板#1将首先执行。我不知道为什么我认为这是 – 只是因为它首先出现在文档中?
>将模板#2执行吗?它匹配源XML中的一个节点,但到我们到达这个模板时(假定它运行第二),“firstName”节点将不在输出树中。
因此,“以后的”模板是否注意到“早期”模板中发生的情况,或者它们是否对源文档进行操作,而忽视了在“先前”模板中发生了什么? (所有这些单词都在引号中,因为我发现很难讨论基于时间的问题,当我真的不知道如何确定模板顺序在第一…)
在上面的例子中,我们有一个在根节点(“/”)上匹配的模板,当它被执行时基本上从输出中删除所有节点。在这种情况下,这将阻止所有其他模板执行,因为在第一个模板完成后没有什么匹配?
到这一点,我一直关注以后的模板不执行,因为他们操作的节点不出现在输出中,但是反过来呢? “早期”模板是否可以创建一个“稍后”模板可以执行某项操作的节点?
在与上面相同的XML上,考虑这个XSL:
<!-- Template #1 --> <xsl:template match="/"> <fullName> <xsl:value-of select="firstName"/> <xsl:value-of select="lastName"/> </fullName> </xsl:template> <!-- Template #2 --> <xsl:template match="//fullName"> Full Name: <xsl:value-of select="."/> </xsl:template>
模板#1创建一个名为“fullName”的新节点。模板#2在同一节点上匹配。将模板#2执行,因为“fullName”节点存在于输出中,当我们到达模板#2时?
我意识到我对XSLT的“禅”很无知。到目前为止,我的样式表包括一个匹配根节点的模板,然后从那里完全是程序性的。我厌倦了这样做。我宁愿真正理解XSLT正确,因此我的问题。
正式来说,我会回答你的每个问题。
- In what order do the templates execute,and
- When they execute,do they match on (a) the original source XML,or (b)
the current output of the XSLT to that
point?
在XSLT处理的任何给定点,在某种意义上,有两个上下文,您标识为(a)和(b):您在源树中,以及您在结果树中的位置。您在源树中的位置称为当前节点。它可以改变和跳转在源代码树周围,当您选择任意集合的节点使用XPath进行处理。但是,从概念上讲,你从不以同样的方式“跳过”结果树。 XSLT处理器以有序的方式构造它;首先它创建结果树的根节点;然后它添加孩子,以文档顺序(深度优先)构建结果。 [你的帖子激励我去拿XSLT实验的软件可视化…]
样式表中的模板规则的顺序从不重要。你不能告诉,只是通过查看样式表,模板规则将被实例化的顺序,一个规则将被实例化的次数,或者甚至它是否会。 (match =“/”是一个例外;你总是可以知道它会被触发。)
I am assuming that Template #1 will
execute first. I don’t know why I
assume this — is it just because it
appears first in the document?
不。它会被称为第一,即使你把它最后一个在文档中。模板规则顺序从不重要(除非在错误条件下,有多个模板规则具有相同的优先级匹配同一节点;即使这样,它对于实现者是可选的,你不应该依赖这种行为)。它首先被调用,因为每当运行XSLT处理器时总是发生的第一件事是对< xsl:apply-templates select =“/”/>的虚拟调用。 。一个虚拟调用构造整个结果树。外面没有什么。您可以通过定义模板规则来定制或“配置”该指令的行为。
Will Template #2 execute? It matches a node in the source XML,but
by the time the we get to this
template (assuming it runs second),
the “firstName” node will not be in
the output tree.
模板#2(也不会有任何其他模板规则)永远不会被触发,除非您有< xsl:apply-templates />调用match =“/”规则中的某处。如果你没有任何,那么除了match =“/”之外没有模板规则将被触发。以这种方式思考:为了使模板规则得到触发,它不能仅仅匹配输入中的一个节点。它必须匹配您选择处理的节点(使用< xsl:apply-templates />)。相反,它将继续匹配节点多次,直到您选择处理它。
Would [the
match="/"
template] pre-empt all other templates
from executing since there is nothing
to match on after that first template
is complete?
该规则无处不在,包括< xsl:apply-templates />在里面。仍然有大量的节点可以在源树中处理。他们总是在那里,成熟的采摘;按你想要的次数处理每一个。但是使用模板规则处理它们的唯一方法是调用< xsl:apply-templates /> ;.
To this point,I’ve been concerned
with later templates not executing
because the nodes they have operated
on do not appear in the output,but
what about the inverse? Can an
“earlier” template create a node that
a “later” template can do something
with?
这不是一个“早期”模板创建一个新的节点来处理;这是一个“早期”模板依次使用相同的指令(< xsl:apply-templates)处理来自源树的更多节点。你可以认为它是递归调用相同的“函数”,每次使用不同的参数(根据上下文和select属性确定要处理的节点)。 最后,你得到的是对同一“函数”(< xsl:apply-templates>)的递归调用的树结构堆栈。这个树结构与你的实际结果是同构的。不是每个人都意识到这一点或者已经这样想过了;这是因为我们没有任何有效的可视化工具…。
Template #1 creates a new node called
“fullName”. Template #2 matches on
that same node. Will Template #2
execute because the “fullName” node
exists in the output by the time we
get around to Template #2?
不。做一个处理链的唯一方法是以这种方式显式地设置它。创建一个变量,例如$ tempTree,其中包含新的< fullName>元素,然后处理它,像这样< xsl:apply-templates select =“$ tempTree”> ;.为了在XSLT 1.0中做到这一点,你需要用一个扩展函数(例如exsl:node-set())包装变量引用,但是在XSLT 2.0中它将工作。 无论您是从原始源树处理节点还是在构建的临时树中处理节点,都需要明确说明要处理的节点。 我们没有覆盖的是XSLT如何获得所有的隐式行为。您还必须了解内置模板规则。我总是写样式表,甚至不包括根节点的明确规则(match =“/”)。相反,我依赖于根节点的内置规则(将模板应用于子节点),这与元素节点的内置规则相同。因此,我可以忽略大部分的输入,让XSLT处理器自动遍历它,只有当它遇到一个我感兴趣的节点,我会做一些特别的事情。或者我可以写一个单独的规则,递归地复制一切(称为身份转换),只在必要时覆盖它,对输入进行增量更改。在阅读“XSLT的工作原理”之后,您的下一个任务是查找“身份转换”。
I realize that I’m deeply ignorant
about the “zen” of XSLT. To date,my
stylesheets have consisted of a
template matching the root node,then
are completely procedural from there.
I’m tired of doing this. I would
rather actually understand XSLT
correctly,hence my question.
我赞扬你。现在是时候拿“红丸”:读“How XSLT Works”