为了账号安全,请及时绑定邮箱和手机立即绑定

XSL中的“调用模板”和“应用模板”之间有什么区别?

XSL中的“调用模板”和“应用模板”之间有什么区别?

qq_花开花谢_0 2019-10-17 10:48:49
我是XSLT的新手,所以我对这两个标签有些困惑,<xsl:apply-templates name="nodes">和<xsl:call-template select="nodes"> 那么您能列出它们之间的区别吗?
查看完整描述

3 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

<xsl:call-template> 与在传统编程语言中调用函数非常相似。


您可以在XSLT中定义函数,例如这种简单的输出字符串的函数。


<xsl:template name="dosomething">

  <xsl:text>A function that does something</xsl:text>

</xsl:template>

可以通过调用此函数<xsl:call-template name="dosomething">。


<xsl:apply-templates>略有不同,它是XSLT的真正功能:它接受任意数量的XML节点(无论您在select属性中定义的是什么),都对它们进行迭代(这很重要:apply-templates就像一个循环!)并找到匹配的模板对于他们:


<!-- sample XML snippet -->

<xml>

  <foo /><bar /><baz />

</xml>


<!-- sample XSLT snippet -->

<xsl:template match="xml">

  <xsl:apply-templates select="*" /> <!-- three nodes selected here -->

</xsl:template>


<xsl:template match="foo"> <!-- will be called once -->

  <xsl:text>foo element encountered</xsl:text>

</xsl:template>


<xsl:template match="*"> <!-- will be called twice -->

  <xsl:text>other element countered</xsl:text>

</xsl:template>

这样,您就可以放弃对XSLT处理器的一点控制-不必确定程序流向何处,而是可以通过为当前正在处理的节点找到最合适的匹配项来实现。


如果多个模板可以匹配一个节点,则具有更具体匹配表达式的模板将获胜。如果存在多个具有相同特异性的匹配模板,则最后声明的一个为准。


您可以将更多的精力放在开发模板上,而花费更少的时间进行“管道”。您的程序将变得更强大,更模块化,更少嵌套和更快(因为XSLT处理器针对模板匹配进行了优化)。


XSLT可以理解的一个概念是“当前节点”的概念。随着<xsl:apply-templates>当前节点与每个迭代上移动,而<xsl:call-template>不会改变当前节点。即,.被调用模板中的指代与.调用模板中相同的节点。套用范本不是这种情况。


这是基本区别。模板还有其他一些方面会影响其行为:mode和priority,模板可以同时具有name和match。模板是否已导入(<xsl:import>)也都会产生影响。这些是高级用途,您可以在到达那里时进行处理。


查看完整回答
反对 回复 2019-10-17
?
Helenr

TA贡献1780条经验 获得超3个赞

xsl:apply-templates通常(但不是必须)用于处理具有所有适用模板的当前节点的所有子节点或子节点的子集。这支持XSLT应用程序的递归性,该递归性与已处理XML的(可能)递归性相匹配。


xsl:call-template另一方面,它更像是正常的函数调用。您通常只使用一个或多个参数来执行一个(命名)模板。


因此,xsl:apply-templates如果我想截取一个有趣的节点并(通常)向输出流中注入一些东西,我就使用它。一个典型(简化)的例子是


<xsl:template match="foo">

  <bar>

    <xsl:apply-templates/>

  </bar>

</xsl:template>

而xsl:call-template我通常会解决一些问题,例如将一些子节点的文本添加到一起,将选择的节点集转换为文本或其他节点集之类的东西-您会为此编写专门的可重用函数。


编辑:

作为对您特定问题文本的补充说明:


<xsl:call-template name="nodes"/> 

这将调用一个名为“节点”的模板:


    <xsl:template name="nodes">...</xsl:template>

这与以下语义不同:


<xsl:apply-templates select="nodes"/>

...将所有模板应用于名称为“ nodes”的当前XML节点的所有子级。


查看完整回答
反对 回复 2019-10-17
  • 3 回答
  • 0 关注
  • 592 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信