为模板匹配命名模板参数为XPath

  • 本文关键字:参数 XPath xslt xpath xslt-1.0
  • 更新时间 :
  • 英文 :


是否可以将命名模板的参数指定为另一个模板中的匹配模式?

在这里,如果我尝试调用'摘录'模板并传入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中,在匹配模式的任何地方使用变量引用是错误的。

相关内容

  • 没有找到相关文章

最新更新