我有基本的查询。我一直在使用xsl:template并使用call tempate对模板进行递归调用。我看到xsl:function也有可能使递归函数调用像递归模板调用并实现相同。什么时候应该使用xsl:function以及何时应该使用xsl:template。我不确定两者之间的差异是什么以及何时应该使用它们。他们每个人的特点是什么?有人可以帮助我更好地理解这一点。
答案 0 :(得分:6)
这是 how I replied to a similar question 差不多3年前:
使用
<xsl:function/>
的好处:
组合性。
在使用它作为参数的表达式中看起来很棒,如 返回值或部分 应用
可读性(紧凑性)和可维护性。
更松散的耦合(不依赖于隐式上下文节点)
- 醇>
可以在XPath表达式中引用
<强>缺点:强>
- 标识
参数仅由位置(而非名称)
- 醇>
可能不纯(可能有副作用,例如创建新节点) 只是看一个表达式 人们可以参考这个功能 不明白它有一面 影响。不过这种可能性 如果适当,可以消除混淆 使用命名。
我倾向于使用
<xsl:function/>
。 在函数创建的情况下 新节点我遵循惯例 用它开始它的本地名称 字符串“make”,如makePerson()
。
我只能补充一点:
始终尽可能使用<xsl:function>
。
在XPath 3.0中,函数是该语言的第一类数据类型(也称为HOF - 高阶函数)。它们可以作为参数传递或作为结果返回到其他函数或从其他函数返回功能
这是使用命名模板的一个非常强大的飞跃。
答案 1 :(得分:2)
概念上xsl:apply-templates
是一个带有多态函数的映射,表示您声明的所有规则。 xsl:function
声明一个“常规”函数,您可以在任何其他接受XPath表达式的指令或声明中使用它。 xsl:call-template
指令“调用”一个特定的命名模板(你可以用某种方式将其视为一个函数)。
因为这一点,评估上下文在每个参与中的含义存在差异:xsl:apply-templates
定义一个新的上下文列表,从中获取上下文节点以及接近位置; xsl:function
没有定义上下文节点(依赖它是一个错误); xsl:call-template
不会更改评估上下文。
其他明显的区别是它们与输出的关系:xsl:apply-templates
和xsl:call-template
,因为XSLT指令输出它们构造的序列; xsl:function
作为XPath表达式的一部分,它没有。
答案 2 :(得分:1)
我发现Dimitre的回复 - http://www.stylusstudio.com/xsllist/200811/post00400.html - 很有帮助。
使用
<xsl:function/>
的好处:
组合性。
在使用它作为参数的表达式中看起来很棒,如 返回值或部分 应用
可读性(紧凑性)和可维护性。
更松散的耦合(不依赖于隐式上下文节点)
- 醇>
可以在XPath表达式中引用
<强>缺点:强>
- 标识
参数仅由位置(而非名称)
- 醇>
可能不纯(可能有副作用,例如创建新节点) 只是看一个表达式 人们可以参考这个功能 不明白它有一面 影响。不过这种可能性 如果适当,可以消除混淆 使用命名。
我倾向于使用
<xsl:function/>
。 在函数创建的情况下 新节点我遵循惯例 用它开始它的本地名称 字符串“make”,如makePerson()
。
答案 3 :(得分: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>