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