xsl中for-each和模板之间的差异?

时间:2010-12-16 11:23:21

标签: templates xslt foreach

xsl:for-eachxsl:template都用于从xsl样式表中的xml中检索节点。但它们之间的根本区别是什么?请指导我。提前谢谢。

7 个答案:

答案 0 :(得分:12)

我通常同意其他答案,但我会说,根据我的经验,使用xsl:for-each编写的样式表比依赖xsl:apply-templates的样式表更容易阅读,理解和维护。 } ...特别是xsl:apply-templates带有隐式选择(或非常通用的选择,如select="node()")。

为什么呢?因为很容易看出每个人会做什么。使用apply-templates,你实质上必须(a)知道所有可能的XML输入(如果你有一个模式会更容易,但是你仍然需要消化模式;很多时候你没有模式,尤其是对于在管道的一个阶段发送的临时中间XML数据;即使您有模式,您的开发框架(例如ESB或CMS)也可能无法为您的管道的每个点提供验证XML的方法。因此,如果您将无法立即通知无效数据,那么您可以预测将选择哪种节点(例如,上下文节点的子节点); (b)查看样式表中的每个模板,以查看哪个模板匹配具有最高优先级的节点(以及文档顺序中的最后一个)。处理顺序也可以跳过所有文件或不同文件(导入或包含)。这可能使“看到”正在发生的事情变得非常困难。

而对于for-each,您确切地知道将实例化哪些代码:for-each中的代码。因为for-each需要一个明确的select表达式,所以你更可能有一个较窄的字段来猜测可以匹配哪些节点。

现在我并不否认apply-templates比for-each更强大,更灵活。这正是重点:更强大,更灵活的构造,更难以约束,理解和调试(并防止安全漏洞)。这是Rule of Least Power:“强大的语言(或者在这种情况下,构造)会抑制信息重用。” (Also discussed here。)

使用apply-templates时,每个模板都更模块化,因此本身更具可重用性,但样式表更复杂,模板之间的交互更少 可预测的。当您使用for-each时,处理流程很容易预测和查看。

使用<xsl:apply-templates />,(或使用<xsl:for-each select="node()"/>),当输入XML的结构发生更改时,样式表的行为会发生变化,而无需开发人员的审核。这是好还是坏取决于你在样式表中预先考虑了多少,以及XML架构开发人员和样式表开发人员(可能是同一个人或可能属于不同组织)之间有多少良好的沟通。

所以对我来说,这是一个判断。如果你有面向文档的XML,比如HTML,其中许多元素类型确实可以在任意深度的层次结构中有许多不同类型的子元素,并且给定元素类型的处理并不经常依​​赖于它的上下文,那么apply-templates绝对必不可少。另一方面,如果你有“面向数据”的XML,具有可预测的结构,你通常不会在不同的上下文中使用相同的元素类型来表示相同的东西,那么每个读取和调试都可以更直接(因此要正确快速地写出来)。

答案 1 :(得分:7)

我认为除了比较xsl:for-eachxsl:template match="..."之外,还有一些与理解push vs. pull样式处理有关的方法。当问题可以通过更优雅的XSLTish方式解决时,您经常会看到来自其他学科的程序员使用大量xsl:ifxsl:choose和for循环。

但问题是: 在我看来,如果您考虑使用xsl:for-each而不是使用xsl:apply-templates处理数据,则需要重新考虑。在某些情况下,for循环适用于XSLT,但只要匹配模板执行相同操作,模板就可以实现。根据我的经验,您通常可以使用xsl:for-each代替xsl:apply-templates进行大多数工作。

我认为在for-loop上使用匹配模板的一些好处是:

  • 样式表更易于维护和扩展,尤其是在源数据发生变化时。
  • 正如@chiborg所提到的,模板可以重复使用,因为它们没有内置到特定的模板中。与XSLT 2.0中的xsl:next-match一起,您可以以强大的方式将模板链接在一起。
  • 您不必模仿已经内置于所有XSLT处理器的行为,即;使用xsl:apply-templates并让处理器为您工作。
  • 此外,我发现更容易理解和调试推送样式样式表。如果你划分样式表信息小模板,这些模板可以做一件或几件事情并编写特定的匹配模式,那么很容易看出哪个模板正在做什么并追踪问题的来源。

答案 2 :(得分:5)

  

'for-each'和'template'都是   用于从xml中检索节点   xsl。但有什么区别   他们之间基本上是

以下是一些最重要的差异

  1. xsl:apply-templatesxsl:for-each更加丰富和深刻,甚至 只是因为我们不知道将在节点上应用什么代码 选择 - 在一般情况下,此代码将有所不同 节点列表的不同节点。

  2. 将应用的代码 可以在xsl:apply template写完之后写出来 那些不了解原作者的人。

  3. 如果XSLT没有<xsl:apply-templates>指令,则无法在XSLT中实现FXSL library高阶函数(HOF)

    摘要:模板和<xsl:apply-templates>指令是XSLT实现和处理多态的方式。

    参考:查看整个帖子: http://www.stylusstudio.com/xsllist/200411/post60540.html

答案 3 :(得分:3)

这并不重要,但你可能想要为我发现的以下规则思考它:

  • 如果代码取决于上下文 位置(position()),把它放在一个 <xsl:for-each>
  • 如果代码取决于上下文 节点(。或任何位置路径),把它 在匹配的模板中。
  • 否则,请使用命名模板。

参考并阅读更多内容: http://www.jenitennison.com/blog/node/9

答案 4 :(得分:2)

这些是完成不同的XSLT指令。

不仅仅是推式与拉式,这更像是迭代与递归。

xsl:for-each是一个迭代器指令,在无状态声明范例中具有迭代的所有优点和约束:一个好的处理器不应该调用调用堆栈。

xsl:apply-templates是一般递归指令。一般来说它比xsl:call-template更强大:你将所选节点“抛出”到模式匹配机制,这是一个真正的“动态函数调用”。

答案 5 :(得分:1)

for-each只能在模板中的一个位置使用。模板可以与不同的apply-templates电话一起使用。我主要使用模板而不是for-each,因为它具有更大的灵活性。

答案 6 :(得分:1)

for-each的一种用法我没有看到提到过:您可以使用它将上下文节点切换到另一个文档。我用它将数据XML转换为HTML输入表单。与数据字段匹配的模板包含选择单个节点的for-each:XSD中描述要转换的数据字段的xs:element

使用XSD中的描述,可以将一个数据字段转换为单选按钮组,下拉框或简单的文本输入。没有for-each我无法同时浏览这两个文件。

一般来说,我更喜欢匹配模板。我发现它对应于单个变换的概念,一次应用比每个节点更好,然后是下一个,然后是之后的那个,等等。但这当然是个人偏好。