views:

3704

answers:

2

My requirement is -using XSLT- to show a dropdown list with the US states and print 'selected' on one specific that is declared in the XML which will use my style sheet.

I was thinking on declare an array with the states and iterate it but I don't know how to do it.

NOTE: More ideas are welcome ;)

+1  A: 

Ideally you would store the list of states in your XML file and just use XSLT to iterate them.

Update: If you can't edit the XML, you could look at using the document function to load data from a second data file:

apathetic
I can't change the XML, it is provided by another system
victor hugo
You still could access another static XML document containing the states list using the document function, right?
Elijah
+4  A: 

One way to do this is to embed the state data into the stylesheet itself, and access the stylesheet document using document(''), as follows:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:my="whatever"
  exclude-result-prefixes="my">

  <xsl:output indent="yes"/>

  <!-- The value of the state you want to select, supplied in the input XML -->
  <xsl:variable name="selected-state" select="/xpath/to/state/value"/>

  <!-- You have to use a namespace, or the XSLT processor will complain -->
  <my:states>
    <option>Alabama</option>
    <option>Alaska</option>
    <!-- ... -->
    <option>Wisconsin</option>
    <option>Wyoming</option>
  </my:states>

  <xsl:template match="/">
    <!-- rest of HTML -->
    <select name="state">
      <!-- Access the embedded document as an internal "config" file -->
      <xsl:apply-templates select="document('')/*/my:states/option"/>
    </select>
    <!-- rest of HTML -->
  </xsl:template>

          <!-- Copy each option -->
          <xsl:template match="option">
            <xsl:copy>
              <!-- Add selected="selected" if this is the one -->
              <xsl:if test=". = $selected-state">
                <xsl:attribute name="selected">selected</xsl:attribute>
              </xsl:if>
              <xsl:value-of select="."/>
            </xsl:copy>
          </xsl:template>

</xsl:stylesheet>

Let me know if you have any questions.

Evan Lenz
Wouldn't it also be possible to put the my:states node inside a variable declaration and use this variable in the select expression?
0xA3
In XSLT 2.0, yes. In XSLT 1.0, you'd need to use an extension function, such as exsl:node-set() or msxsl:node-set(). The document('') solution requires neither.
Evan Lenz