是否可以将命名模板的参数指定为另一个模板中的匹配模式?
在这里,如果我尝试调用'摘录'模板并传入XPath作为'path'参数,我会得到一个错误:
<xsl:template name="excerpt">
<xsl:param name="path" select="''" />
<xsl:apply-templates select="$path" />
</xsl:template>
<xsl:template match="$path">
<article class="newsarticle">
<h2><a href="{$root}/news/view/{title/@handle}"><xsl:value-of select="title" /></a></h2>
<xsl:copy-of select="excerpt/node()" />
</article>
</xsl:template>
我可以用<xsl:for-each>
完成它,但我想知道是否有一个很好的解决方案,使用类似于上面的方法。
编辑:这就是我想要完成的,使用<xsl:for-each>
:
<xsl:template name="excerpt">
<xsl:param name="path" select="''" />
<xsl:for-each select="$path">
<article class="newsarticle">
<h2><a href="{$root}/news/view/{title/@handle}"><xsl:value-of select="title" /></a></h2>
<xsl:copy-of select="excerpt/node()" />
</article>
</xsl:for-each>
</xsl:template>
编辑:一个调用模板的例子:
<xsl:call-template name="excerpt">
<xsl:with-param name="path" select="path/to/nodeset" />
</xsl:call-template>
感谢您提供的额外信息。这里需要澄清的是,在call-template
中,您传递的是节点集,而不是路径。如果没有复杂的解析逻辑或扩展函数,路径的字符串值在XSLT 1.0中几乎没有价值。
有一种方法可以做你想做的事,只是方式与你想象的略有不同。您只需要使用一个具有通用match
值和mode
值的模板,如下所示。
<xsl:template name="excerpt">
<xsl:param name="items" select="''" />
<xsl:apply-templates select="$items" mode="excerptItem" />
</xsl:template>
<xsl:template match="node() | @*" mode="excerptItem">
<article class="newsarticle">
<h2>
<a href="{$root}/news/view/{title/@handle}">
<xsl:value-of select="title" />
</a>
</h2>
<xsl:copy-of select="excerpt/node()" />
</article>
</xsl:template>
但是,如果命名模板只用于调用匹配模板,那么您根本不需要命名模板。你可以直接使用match模板:
<xsl:apply-templates select="path/to/nodeset" mode="excerptItem" />
mode
属性的目的是当您在apply-templates
中指定mode
时,XSLT将只考虑具有相同mode
值的模板。因此,您可以定义两个不同的模板,以不同的方式处理相同的元素:
<xsl:template match="Item" mode="header">
Item in header: <xsl:value-of select="." />
</xsl:template>
<xsl:template match="Item" mode="body">
Item in body: <xsl:value-of select="." />
</xsl:template>
然后你可以指定你想在不同的时间使用哪一个:
<div id="header">
<xsl:apply-templates match="/root/Items/Item" mode="header" />
</div>
<div id="body">
<xsl:apply-templates match="/root/Items/Item" mode="body" />
</div>
,并在每种情况下使用适当的一个。你可以在这里阅读更多关于模式的信息。
node() | @*
是匹配任何节点或属性的通用XPath,因此如果在模板的match
属性中使用它,则可以创建一个几乎匹配apply-templates
中使用的任何内容的模板(只要没有其他具有更高优先级的模板)。将它与mode
结合使用,您可以制作一个模板,您可以在任何节点上调用该模板,并且仅在您想要的特定时间调用该模板。在您的示例中,看起来您将与此模板一起使用的元素将始终是相同的,因此显式指定它可能是更好的实践:
<xsl:template match="ExportItem" mode="excerptItem">
是否有可能使命名模板的参数充当在另一个模板中匹配路径?
不,在XSLT 2.0中,模板的匹配模式只能包含一个变量引用作为id()
函数的参数。
有关模式的完整语法,请参阅XSLT 2.0 W3C规范
http://www.w3.org/TR/xslt20/模式语法
在XSLT 1.0中,在匹配模式的任何地方使用变量引用是错误的。