2011-04-29 58 views
9

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

+0

好问题,+1。请参阅我的答案以获得解释,比较和建议。 – 2011-05-01 19:36:34

回答

1

我发现Dimitre的回复 - http://www.stylusstudio.com/xsllist/200811/post00400.html - 有帮助。使用<xsl:function/>

优点:

  1. 组合性。

  2. 在使用它作为参数的表达式中看起来不错,因为 返回值或作为部分 应用程序。

  3. 可读性(紧凑性)和可维护性。

  4. 更多松耦合(不依赖隐式上下文节点上)

  5. 可以在XPath表达式中引用

缺点:

  1. 参数是仅由位置标识(不按名称)

  2. 可以是不纯的(可以有副作用,如创建新节点(S)) 和只是看着表达 引用这个功能的人可能 不明白,它有一个侧 效果。然而,如果使用适当的命名,则可以消除这种混淆的可能性。

我倾向于总是使用<xsl:function/>。 在功能创建 新节点的情况下,我按照 的惯例开始其本地名称, 字符串“make”,如makePerson()中所示。

2

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

因为这样,关于每个评估上下文如何涉及评估上下文有所不同:xsl:apply-templates定义了一个新的上下文列表,从中获取上下文节点以及接近位置; xsl:function没有定义上下文节点(依赖它是错误的); xsl:call-template不会更改评估上下文。

其他明显不同的是它们与输出的关系:当XSLT指令输出其构造的序列时,它们都是xsl:apply-templatesxsl:call-template; xsl:function作为它不包含的XPath表达式的一部分。

+0

@Alejandro:我在你的答案中找到两个有问题(不完全正确)的陈述。 1)''xsl:function'没有定义上下文节点(依赖于它是错误的);“更准确地说,如果在主体中遇到相对XPath表达式,XSLT处理器必须发出错误信号的功能。 2)“xsl:函数作为它不包含的XPath表达式的一部分(输出构造的序列)”。这不是真的。 'xsl:function'可以创建节点并返回它们 - 我使用这种技术。是的,'xsl:function'可能有副作用。 – 2011-05-02 13:18:05

+0

@Dimitre:From http://www.w3.org/TR/xslt20/#stylesheet-functions _“在样式表函数的主体中,焦点最初是未定义的;这意味着任何尝试引用上下文项,上下文位置或上下文大小是一个不可恢复的动态错误。“_关于两个:它不是输出到结果树的函数,而是XSLT指令。关于副作用,好吧,它可能会引起争议:即使构造新节点作为结果的函数也会为相同的参数构造相同的结果,除此之外它可能不具有相同的节点标识。 – 2011-05-02 14:08:43

+0

@Dimitre:主题:它看起来像是一个主要的retag,它改变了'xpath'的所有'xpathengines'标签,甚至改变了该版本的属性(如果我用'xpathengines'标记,现在它说我已经标记了它与'xpath')。请参阅http://meta.stackexchange.com/questions/89005/what-did-happen-with-xpathengines-and-xqueryengines-tags – 2011-05-02 14:16:58

6

这是how I replied to a similar question近3年前:

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

  1. 组合性。

  2. 在使用它作为参数的表达式中看起来不错,因为 返回值或作为部分 应用程序。

  3. 可读性(紧凑性)和可维护性。

  4. 更多松耦合(不依赖隐式上下文节点上)

  5. 可以在XPath表达式中引用

缺点:

  1. 参数是仅由位置标识(不按名称)

  2. 可以是不纯的(可以有副作用,如创建新节点(S)) 和只是看着表达 引用这个功能的人可能 不明白,它有一个侧 效果。然而,如果使用适当的命名,则可以消除这种混淆的可能性。

我倾向于总是使用<xsl:function/>。 在功能创建 新节点的情况下,我按照 的惯例开始其本地名称, 字符串“make”,如makePerson()中所示。

我只能添加到这个:

总是尽可能使用<xsl:function>

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

这是一个令人难以置信的强大的飞跃使用命名模板。

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>