Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping over hard-coded values in specified in XSL stylesheet, not in XML

Tags:

xslt

I'm wondering if there's a way to loop over a values specified in the XSL, rather than coming from the XML.

Let's say I have 3 possible checkboxes, with a "current" value that comes from the XML. I'd have an XML doc like

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

and XSL code like

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

This works, but the XSL is very verbose. I'd LIKE to be able to do something like this:

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

I can KIND OF get this by putting the code in a template and using multiple <call-template> <with-param> calls, but that's doesn't save much space over the original.

Is there any concise way to do this with XSL? I definitely can't put all the checkbox names in the XML output, it's a large list and unnecessarily bloats the XML.

like image 584
Jason Viers Avatar asked Dec 13 '25 00:12

Jason Viers


1 Answers

Yes, you can get the source (!) of the XSL by calling the document('') function, which you can then use as node datasource.

<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" />
like image 171
Lucero Avatar answered Dec 14 '25 20:12

Lucero