循环使用XSL样式表中指定的硬编码值,而不是XML

时间:2011-07-22 15:40:13

标签: xslt

我想知道是否有办法循环遍历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 个答案:

答案 0 :(得分: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 :(得分: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处理器。

答案 2 :(得分: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>

应该减少它。