2012-01-13 55 views
1

我正在寫一個「擴展」模板的模板,但它有一些問題。如何編寫一個捕獲所有XSL模板,並通過所有參數?

<xsl:template match="*[@condition]" mode="#all"> 
<xsl:element name="condition"> 
    <xsl:attribute name="name"> 
    <xsl:value-of select="@condition"></xsl:value-of> 
    </xsl:attribute> 
    <xsl:apply-imports> 
    </xsl:apply-imports> 
</xsl:element> 

這個問題是使用模板<xsl:apply-imports>缺少參數。 參數列表未知,因爲此模板試圖擴展許多不同的模板(因此mode="#all")。

有沒有一個很好的解決方法呢?


附加例如:

考慮兩個最終模板(只讀):

<xsl:template match="*" mode="mode1"> 
    <param name="p1"/> 
</xsl:template> 

<xsl:template match="*" mode="mode2"> 
    <param name="p2"/> 
</xsl:template> 

他們被地方稱爲(只讀):

<xsl:apply-templates mode="mode1"> 
    <xsl:with-param name="mode1" select="$mode1"/> 
</xsl:apply-templates> 

<xsl:apply-templates mode="mode2"> 
    <xsl:with-param name="mode2" select="$mode2"/> 
</xsl:apply-templates> 

可能存在是mode1,mode2,mode3,mode4 ...的100s,名稱沒有模式。

我想有一個全局模板,包裹最終模板的附加信息。例如:

<xsl:template match="*" mode="#all"> 
    <xsl:next-match/> 
</xsl:element> 

問題是上述全局模板沒有將參數傳遞給模板。

回答

1

如果您的問題是當您撥打<xsl:apply-imports>時它不包含傳遞給當前模板的參數,則可以使用隧道參數。在模板要擴展標記您的參數是這樣的:

<xsl:param name="foo" tunnel="yes"/> 

此外,當您傳遞的參數:

<xsl:with-param name="foo" tunnel="yes"/> 

我還建議您使用的<xsl:next-match>代替<xsl:apply-imports>

+0

感謝您的回答。這部分是問題。還有另一個問題 - 參數的名稱也是未知的,也就是說,名稱=「foo」是未知的,並且存在各種模板,它們會採用各種參數。無法找到每個模板並列出所有參數。 – Jason 2012-01-13 14:37:53

+0

@Jason:無需在每個模板中聲明隧道參數,就在您使用它們時。 – 2012-01-13 18:07:50

+0

我剛剛添加了另一個更完整的示例。我希望這能說明我在找什麼。關鍵是模板是隻讀的,調用者文件也是隻讀的。我只能以某種方式擴展模板。 – Jason 2012-01-13 19:41:17

1

您可以使用Max Toro建議的隧道參數,或者您可以傳遞一個參數,其子項是不同模板需要並將識別的參數。

事情是這樣的

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:param name="pComposite" as="element()*"> 
    <param for="templateX" name="pA"> 
    12 
    </param> 
    <param for="templateY" name="pB"> 
    Some String 
    </param> 
</xsl:param> 

<xsl:template match="*[@condition]"> 
    <condition name="{@condition}"> 
    <xsl:apply-imports> 
    <xsl:with-param name="pComposite" 
     select="$pComposite"/> 
    </xsl:apply-imports> 
    </condition> 
</xsl:template> 
</xsl:stylesheet> 
+0

謝謝Dimitre的回答。這很有幫助。如果有許多參數很多的模板,我是否必須在pComposite參數中迭代所有參數?我希望params可以以更透明的方式傳遞給其他模板。 - Jason – Jason 2012-01-13 14:41:15

+0

@Jason:沒有必要迭代。每個模板都獲得帶有XPath表達式的參數,例如:「$ pComposite/myName」 - 我覺得這很方便有用。 – 2012-01-13 14:49:38

+0

在這種情況下,我是否需要修改所有其他模板並引入新參數pComposite? – Jason 2012-01-13 15:52:07