XSL递归调用 - xsl:functions vs xsl:带调用模板的模板

问题描述 投票:9回答:4

我有基本的查询。我一直在使用xsl:template并使用call tempate对模板进行递归调用。我看到xsl:function也有可能使递归函数调用像递归模板调用并实现相同。什么时候应该使用xsl:function以及何时应该使用xsl:template。我不确定两者之间的差异是什么以及何时应该使用它们。他们每个人的特点是什么?有人可以帮助我更好地理解这一点。

xslt xslt-2.0 xslt-1.0
4个回答
6
投票

这是几乎3年前的how I replied to a similar question

使用<xsl:function/>的好处:

  1. 组合性。
  2. 在一个表达式中看起来很棒,它将它用作参数,返回值或部分应用程序。
  3. 可读性(紧凑性)和可维护性。
  4. 更松散的耦合(不依赖于隐式上下文节点)
  5. 可以在XPath表达式中引用

不足之处:

  1. 参数仅由位置(而不是名称)标识
  2. 可能是不纯的(可能有副作用,例如创建新节点),只是通过查看引用此函数的表达式,人们可能不明白它有副作用。但是,如果使用适当的命名,则可以消除这种混淆的可能性。

我倾向于使用<xsl:function/>。在函数创建新节点的情况下,我遵循使用字符串“make”启动其local-name的约定,如makePerson()

我只能添加到这个:

总是在可能的时候使用<xsl:function>

在XPath 3.0中,函数是该语言的第一类数据类型(也称为HOF - 高阶函数)。它们可以作为参数传递或作为结果返回到其他函数或从其他函数返回。

这是使用命名模板的一个非常强大的飞跃。


2
投票

从概念上讲,xsl:apply-templates是一个具有多态函数的映射,表示您声明的所有规则。 xsl:function声明了一个“常规”函数,您可以在任何其他接受XPath表达式的指令或声明中使用它。 xsl:call-template指令“调用”一个特定的命名模板(你可以在某种程度上将其视为一个函数)。

因此,关于评估上下文如何在每个参与中存在差异:xsl:apply-templates定义了一个新的上下文列表,从中获取上下文节点以及接近位置; xsl:function没有定义上下文节点(依赖它是一个错误); xsl:call-template不会改变评估背景。

其他明显的区别是它们与输出的关系:xsl:apply-templatesxsl:call-template作为XSLT指令输出它们构造的序列; xsl:function作为XPath表达式的一部分,它没有。


1
投票

我发现Dimitre的回应 - http://www.stylusstudio.com/xsllist/200811/post00400.html - 很有帮助。

使用<xsl:function/>的好处:

  1. 组合性。
  2. 在一个表达式中看起来很棒,它将它用作参数,返回值或部分应用程序。
  3. 可读性(紧凑性)和可维护性。
  4. 更松散的耦合(不依赖于隐式上下文节点)
  5. 可以在XPath表达式中引用

不足之处:

  1. 参数仅由位置(而不是名称)标识
  2. 可能是不纯的(可能有副作用,例如创建新节点),只是通过查看引用此函数的表达式,人们可能不明白它有副作用。但是,如果使用适当的命名,则可以消除这种混淆的可能性。

我倾向于使用<xsl:function/>。在函数创建新节点的情况下,我遵循使用字符串“make”启动其local-name的约定,如makePerson()


0
投票
Templates are useful when you have the requirement to store the results of each recursion into a variable as a attribute ( at the end of each recursion before calling the next ).

**Example:**

    <xsl:variable name="test">
     <record>
        <xsl:call-template name="templateRecursion">
              <xsl:with-param name="xyz" select="xyz"/>   
        </xsl:call-template>
     <record>
    </xsl:variable>

**templateRecursion:**

    <xsl:template name="templateRecursion">

    <!-- Do processing -->
     <xsl:attribute name="" value=""

    </xsl:template>

So, the variable test will have 

    <record>
     <attribute_name="" value=""/>
      .
      .
    </record>
© www.soinside.com 2019 - 2024. All rights reserved.