XSLT文档中的模板以什么顺序执行,它们是否匹配源XML或缓冲输出?
这里总是暗示我对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将首先执行。我不知道为什么我认为这是 – 只是因为它首先出现在文档中? 因此,“以后的”模板是否注意到“早期”模板中发生的情况,或者它们是否对源文档进行操作,而忽视了在“先前”模板中发生了什么? (所有这些单词都在引号中,因为我发现很难讨论基于时间的问题,当我真的不知道如何确定模板顺序在第一…) 在上面的例子中,我们有一个在根节点(“/”)上匹配的模板,当它被执行时基本上从输出中删除所有节点。在这种情况下,这将阻止所有其他模板执行,因为在第一个模板完成后没有什么匹配? 到这一点,我一直关注以后的模板不执行,因为他们操作的节点不出现在输出中,但是反过来呢? “早期”模板是否可以创建一个“稍后”模板可以执行某项操作的节点? 在与上面相同的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正确,因此我的问题。
我爱你的问题。你很清楚你还不明白什么。你只需要一些东西把事情捆绑在一起。我的建议是,你读了
“How XSLT Works”,我写了一个章,以解决你提出的问题。我很愿意听到,如果它把事情联系在一起为你。
正式来说,我会回答你的每个问题。
在XSLT处理的任何给定点,在某种意义上,有两个上下文,您标识为(a)和(b):您在源树中,以及您在结果树中的位置。您在源树中的位置称为当前节点。它可以改变和跳转在源代码树周围,当您选择任意集合的节点使用XPath进行处理。但是,从概念上讲,你从不以同样的方式“跳过”结果树。 XSLT处理器以有序的方式构造它;首先它创建结果树的根节点;然后它添加孩子,以文档顺序(深度优先)构建结果。 [你的帖子激励我去拿XSLT实验的软件可视化…] 样式表中的模板规则的顺序从不重要。你不能告诉,只是通过查看样式表,模板规则将被实例化的顺序,一个规则将被实例化的次数,或者甚至它是否会。 (match =“/”是一个例外;你总是可以知道它会被触发。)
不。它会被称为第一,即使你把它最后一个在文档中。模板规则顺序从不重要(除非在错误条件下,有多个模板规则具有相同的优先级匹配同一节点;即使这样,它对于实现者是可选的,你不应该依赖这种行为)。它首先被调用,因为每当运行XSLT处理器时总是发生的第一件事是对< xsl:apply-templates select =“/”/>的虚拟调用。 。一个虚拟调用构造整个结果树。外面没有什么。您可以通过定义模板规则来定制或“配置”该指令的行为。
模板#2(也不会有任何其他模板规则)永远不会被触发,除非您有< xsl:apply-templates />调用match =“/”规则中的某处。如果你没有任何,那么除了match =“/”之外没有模板规则将被触发。以这种方式思考:为了使模板规则得到触发,它不能仅仅匹配输入中的一个节点。它必须匹配您选择处理的节点(使用< xsl:apply-templates />)。相反,它将继续匹配节点多次,直到您选择处理它。
该规则无处不在,包括< xsl:apply-templates />在里面。仍然有大量的节点可以在源树中处理。他们总是在那里,成熟的采摘;按你想要的次数处理每一个。但是使用模板规则处理它们的唯一方法是调用< xsl:apply-templates /> ;.
这不是一个“早期”模板创建一个新的节点来处理;这是一个“早期”模板依次使用相同的指令(< xsl:apply-templates)处理来自源树的更多节点。你可以认为它是递归调用相同的“函数”,每次使用不同的参数(根据上下文和select属性确定要处理的节点)。 最后,你得到的是对同一“函数”(< xsl:apply-templates>)的递归调用的树结构堆栈。这个树结构与你的实际结果是同构的。不是每个人都意识到这一点或者已经这样想过了;这是因为我们没有任何有效的可视化工具…。
不。做一个处理链的唯一方法是以这种方式显式地设置它。创建一个变量,例如$ tempTree,其中包含新的< fullName>元素,然后处理它,像这样< xsl:apply-templates select =“$ tempTree”> ;.为了在XSLT 1.0中做到这一点,你需要用一个扩展函数(例如exsl:node-set())包装变量引用,但是在XSLT 2.0中它将工作。 无论您是从原始源树处理节点还是在构建的临时树中处理节点,都需要明确说明要处理的节点。 我们没有覆盖的是XSLT如何获得所有的隐式行为。您还必须了解内置模板规则。我总是写样式表,甚至不包括根节点的明确规则(match =“/”)。相反,我依赖于根节点的内置规则(将模板应用于子节点),这与元素节点的内置规则相同。因此,我可以忽略大部分的输入,让XSLT处理器自动遍历它,只有当它遇到一个我感兴趣的节点,我会做一些特别的事情。或者我可以写一个单独的规则,递归地复制一切(称为身份转换),只在必要时覆盖它,对输入进行增量更改。在阅读“XSLT的工作原理”之后,您的下一个任务是查找“身份转换”。
我赞扬你。现在是时候拿“红丸”:读“How XSLT Works” (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |