2011-07-22 22 views
3

我想知道是否有方法循環遍歷XSL中指定的值,而不是來自XML。循環遍歷XSL樣式表中指定的硬編碼值,而不是XML

比方說,我有3個可能的複選框,來自XML的「當前」值。我有一個XML文檔一樣

<rootNode> 
    <val>bar</val> 
</rootNode> 

和XSL代碼像

<input id="foo" type="checkbox" name="myvar" value="foo"> 
    <xsl:if test="val='foo'"> 
     <xsl:attribute name="checked">checked</xsl:attribute> 
    </xsl:if> 
</input> <label for="foo">foo</label> 

<input id="bar" type="checkbox" name="myvar" value="bar"> 
    <xsl:if test="val='bar'"> 
     <xsl:attribute name="checked">checked</xsl:attribute> 
    </xsl:if> 
</input> <label for="bar">bar</label> 

<input id="baz" type="checkbox" name="myvar" value="baz"> 
    <xsl:if test="val='baz'"> 
     <xsl:attribute name="checked">checked</xsl:attribute> 
    </xsl:if> 
</input> <label for="baz">baz</label> 

這工作,但XSL是非常詳細。我希望能夠做這樣的事情:

<!-- this syntax doesn't work, is there something similar that does? --> 
<xsl:variable name="boxNames" select="'foo','bar','baz'"/> 
<xsl:for-each select="name in $boxNames"> 
    <input id="{$name}" type="checkbox" name="myvar" value="{$name}"> 
     <xsl:if test="val=$name"> 
      <xsl:attribute name="checked">checked</xsl:attribute> 
     </xsl:if> 
    </input> <label for="{$name}"><xsl:value-of select="$name"/></label> 
</xsl:for-each> 

我可以種通過將在模板的代碼,並使用多個<call-template><with-param>電話得到這個,但是這並沒有保存過多少空間原版的。

有沒有簡潔的方式來做到這一點與XSL?我絕對不能把所有的複選框名稱放在XML輸出中,這是一個很大的列表,並且不必要地膨脹了XML。

回答

3

是的,您可以通過調用document('')函數獲得XSL的源代碼(!),然後您可以將它用作節點數據源。

<xsl:template name="boxNames"> <!-- not used as template --> 
    <name>foo</name> 
    <name>bar</name> 
    <name>baz</name> 
</xsl:template> 

[...]

<xsl:variable name="boxNames" select="document('')/xsl:stylesheet/xsl:template[@name='boxNames']/name" /> 
+1

除了將數據放入未使用的模板中,它可以作爲頂級元素放置,只要它使用的不是XSLT名稱空間的其他名稱空間。 XSLT處理器將忽略這樣的頂級元素。 –

+0

完美,這正是我所希望的!我同意Jukka,我將使用一個單獨的命名空間來強化它實際上不是模板。 –

0

模板匹配有效地用於每個循環。

<xsl:template match="/"> 
    <xsl:apply-templates match="namespace:ItemName"/> 
</xsl:template> 

<xsl:template match="namespace:ItemName"> 
    <input> 
     <xsl:attribute name="id"><xsl:value-of select="."></xsl:attribute> 
     <xsl:attribute name="type">checkbox</xsl:attribute> 
     <xsl:attribute name="name">myvar</xsl:attribute> 
     <xsl:attribute name="value"><xsl:value-of select="."></xsl:attribute> 
     <xsl:value-of select="."> 
    </input> 
    <label> 
     <xsl:attribute name="for"><xsl:value-of select="." /></xsl:attribute> 
     <xsl:value-of select="."/> 
    </label> 
</xsl:template> 

這應該減少它。

+0

但是,這是拉的所有可能的值,'命名空間:ItemName',從XML,正確的?我特別不希望在每個XML輸出中包含所有可能的值,只有「當前」值在XML中。 –

3

試試這個,這是非常接近你的建議代碼:

<xsl:variable name="boxNames" select="'foo','bar','baz'"/> 
<xsl:variable name="val" select="val"/> 
<xsl:for-each select="$boxNames"> 
    <input id="{.}" type="checkbox" name="myvar" value="{.}"> 
     <xsl:if test="$val=."> 
      <xsl:attribute name="checked">checked</xsl:attribute> 
     </xsl:if> 
    </input> <label for="{.}"><xsl:value-of select="."/></label> 
</xsl:for-each> 

這雖然需要一個XSLT 2.0處理器。

+0

我猜想XSLT 2.0會讓我的夢想成真。 :)不幸的是我必須支持XSLT 1.0。不過很高興知道,謝謝! –