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

时间:2015-01-05 03:03:53

标签: xml xslt

我有一个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>

3 个答案:

答案 0 :(得分:1)

什么是命名模板?

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

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

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

<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,那么也要摆脱./,因为它是多余的,而且,根据经验,我会说不应该有{{1} 1}}在路径表达式前面:

//

答案 1 :(得分:1)

代码看起来好像是由那些尚未掌握XSLT的apply-templates惯用语的人编写的。我想一个更有经验的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-templates代替。

答案 2 :(得分:0)

用普通的编程语言思考命名函数。 <xsl:call-template>是函数调用的直接模拟。将某段代码移动到单独的函数是否值得 - 这是编码风格,代码重复次数和其他“模糊”考虑因素的问题。在这种特殊情况下,作者可能希望确保每个部分都能均匀地变换。也许,在该文件的先前版本中,函数的主体不那么简单。