性能:调用模板与应用模板

时间:2020-03-05 18:59:10  来源:igfitidea点击:

在XSLT处理中,apply-template和call-template之间是否存在性能差异?在我的样式表中,有很多实例可以使用它们之一,哪个是最佳选择?

解决方案

回答

apply-template和call-template不会执行相同的任务,因此性能比较在这里并不是很重要。
call-template采用模板名称作为参数,而apply-template采用xpath表达式。因此,Apply-template的功能要强大得多,因为我们实际上并不知道将执行哪个模板。
如果使用复杂的xpath表达式,则会遇到性能问题。在xpath表达式中避免使用" //",因为将评估输入文档的每个节点。

回答

它可能取决于我们使用的xml解析器。除了.NET 2003解析器外,我什么都说不了。这类似于要求:apply-template = push和call-template = pull。我坚信推送会更快,但事实并非如此。差不多了。

抱歉,我现在没有确切的测试。我建议使用我们选择的解析器尝试一下,看看是否有任何主要区别。我敢打赌不会有。

回答

与所有性能问题一样,答案将取决于特定配置(特别是我们使用的XSLT处理器)以及我们正在执行的处理类型。

&lt;xsl:apply-templates>接受一系列节点,并一个接一个地遍历它们。对于每一个,它都找到与该节点匹配的具有最高优先级的模板,然后调用它。因此,<xsl:apply-templates>就像一个<xsl:for-each>,里面带有一个<xsl:choose>,但是更具模块化。

相反," <xsl:call-template>"按名称调用模板。上下文节点没有变化(没有<xsl:for-each>),也没有选择使用哪个模板。

因此,在完全相同的情况下,我们可能会想到&lt;xsl:call-template>会更快,因为它所做的工作更少。但是,如果我们处于可以使用&lt;xsl:apply-templates>或者&lt;xsl:call-template>的情况下,则可能要使用`<xsl:for-each>在幕后由XSLT自己处理,而不是由处理器为我们完成。因此,最终我猜想它可能会实现平衡。但是正如我所说,这在很大程度上取决于处理器已进行的优化类型以及我们正在执行的处理。测量一下,看看。

关于何时使用匹配模板以及何时使用命名模板的经验法则是:

  • 如果要处理单个节点以创建结果,请使用&lt;xsl:apply-templates>和匹配模板;如果需要以几种不同的方式来处理特定节点(例如,目录与文档正文中的方式),则使用模式
  • 如果我们要处理的不是单个节点,则使用&lt;xsl:call-template>和一个命名模板,例如字符串或者数字或者节点集
  • (在XSLT 2.0中)如果要返回原子值或者现有节点,请使用&lt;xsl:function>