<xsl:call-template...> 的目的是什么

What is the purpose of <xsl:call-template...>

我有一个 XML 文件如下所示

- <select1>
   - <sel_details>
      <type>Primary Type</type> 
      <name>Some Name</name> 
      <id>ID Num</id>
     <sel_details>
     .....
  <select1>

XSL 看起来像这样

<xsl:for-each select="//select1">
     <xsl:call-template name="sel_details" />
     <xsl:with-param name="xmlSection" select="sel_details" />
     </xsl:call-template>
     <xsl:call-template name="....." />
     <xsl:with-param name="xmlSection" select="....." />
     </xsl:call-template>
     ..........
</xsl:for-each>

<xsl:template name="sel_details">
     <xsl:param name="xmlSection" />
        <xsl:for-each select="xmlSection">
            <xsl:value-of select="./type" />
        </xsl:for-each>
</xsl:template>

<xsl:call-template...>然后<xsl:template name...>的目的是什么?

如果我只写 3 行这样,我可以获得相同的值:

<xsl:for-each select="//select1/sel_details">
     <xsl:value-of select="./type" />
</xsl:for-each>

想想普通编程语言中的命名函数。 <xsl:call-template> 是函数调用的直接模拟。是否值得将某段代码移动到一个单独的函数中 - 这是编码风格、代码重复次数和其他 "fuzzy" 考虑因素的问题。在这种特殊情况下,作者可能希望确保每个部分都将被统一转换。也许,在以前的文件修订版中,函数体不那么琐碎。

什么是命名模板?

在 XSLT 样式表中,xsl:call-template:

<xsl:call-template name="construct-header"/>

表示调用所谓的 命名模板 - 具有 name 属性的 xsl:template 元素:

<xsl:template name="construct-header">

与匹配输入节点并因此具有 match 属性的模板相反:

<xsl:template match="book">

由于命名模板永远不会与输入节点匹配,因此使用 xsl:call-template 显式调用它们是执行其中代码的唯一方法。调用命名模板后,将在不更改上下文的情况下评估代码 (broadly speaking, at least)。所以,一个非常合理的问题是

为什么一般使用命名模板?

使用命名模板

  • 在 XSLT 中实现递归算法。一个众所周知的例子是 mimicking the tokenize() function in XSLT 1.0,它需要一个递归的命名模板。
  • 在多个地方重用代码块以避免重复
  • 将您的样式表组织成有意义的部分。这也可以通过模块化您的代码到几个样式表中来完成,这些样式表由主样式表包含或导入。

在您的特定情况下使用命名模板

如果代码真的像您显示的那样短,我认为没有理由在这里使用命名模板。命名模板中没有递归处理。但也许您在此处发布之前已经大大缩短了它,或者命名模板在样式表的其他地方重复使用。两者都是保留命名模板的充分理由。 (如果您想对此有更清晰的指导,请出示完整的样式表。)

如果您决定将代码缩减为 xsl:for-each,那么还要去掉 ./,因为它是多余的,而且根据经验,我认为不应该有// 路径表达式前面:

<xsl:for-each select="select1/sel_details">
     <xsl:value-of select="type" />
</xsl:for-each>

在我看来,这段代码好像是由尚未掌握 XSLT 的应用模板习惯用法的人编写的。我想更有经验的 XSLT 程序员可能会写这样的东西:

<xsl:template match="/">
  ...
  <xsl:apply-templates select="//select1"/>
  ...
</xsl:template>

<xsl:template match="select1">
     <xsl:apply-templates select="sel_details" />
     <xsl:apply-templates select="....." />
</xsl:template>

<xsl:template match="sel_details">
     <xsl:value-of select="type" />
</xsl:template>

其中 xsl:for-each 和 xsl:call-template 和 xsl:choose 是主要控制结构的样式表通常建议程序员对 XSLT 习惯用法还不满意。经验丰富的 XSLT 编码人员使用匹配模板和 xsl:apply-模板。