2013-01-19 63 views
1

是否可以將指定模板的參數指定爲另一個模板中的匹配模式?將模板參數命名爲用於模板匹配的XPath

在這裏,如果我嘗試調用「摘錄」模板,並在XPath傳遞的「路徑」 PARAM,我得到一個錯誤:

<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> 
+0

你能提供一個例子,說明如何使用for-each來完成你想要的任務嗎? – JLRishe

+0

感謝您的額外細節。你能否提供一個調用該模板的例子? – JLRishe

回答

1

感謝附加信息。在這裏做出的一個澄清是,在那裏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> 

但是,如果命名模板僅用於調用匹配模板,那麼您根本不需要命名模板。你可以只用直接匹配模板:

<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> 

和適當的人會在每種情況下使用。你可以閱讀更多關於模式here

node() | @*是一個通用的XPath,任何節點或屬性相匹配,因此,如果你在一個模板的match屬性使用它,你可以做一個模板,將您在apply-templates使用幾乎所有的東西匹配(只要有ISN另一個具有更高優先級的模板)。通過與mode結合使用,您可以創建一個模板,您可以在任何節點上調用該模板,並且只在需要的特定時間調用該模板。在你的榜樣,那樣子你會用這個模板的使用將永遠是相同的元素,所以它很可能是更好的做法是明確指定:

<xsl:template match="ExportItem" mode="excerptItem"> 
+0

謝謝,JLRishe - 的確,它的功能就像是一種魅力。我從來沒有見過類似match =「node()| @ *」mode =「exportItem」'的匹配,你能簡單地解釋一下這是如何工作的(和/或指向我的某個方向準備就緒關於它)? – davidpmccormick

+0

上面添加了解釋。 – JLRishe

+0

令人驚歎。再次感謝。 – davidpmccormick

0

Is it possible to get a parameter of a named template to act as the match path in another template?

不,XSLT 2。0模板的匹配模式只能包含變量引用作爲id()函數的參數。

參見XSLT 2.0 W3C Specificification用於將圖案

http://www.w3.org/TR/xslt20/#pattern-syntax

在XSLT 1.0的完整語法它是一個錯誤爲具有可變基準的匹配圖案內的任何地方。