xsl-list
[Top] [All Lists]

[xsl] Writing a SELECT with each OPTION a unique value

2007-04-10 17:55:21
I'm fairly new to this whole XML/XSL(T) thing.  I've got this XML file.
It's painfully basic, I'm sure you've seen it somewhere online:

<?xml version="1.0" encoding="ISO8859-1" ?>
<CATALOG>
        <CD>
                <TITLE>Empire Burlesque</TITLE>
                <ARTIST>Bob Dylan</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>Columbia</COMPANY>
                <PRICE>10.90</PRICE>
                <YEAR>1985</YEAR>
        </CD>
        <CD>
                <TITLE>Hide your heart</TITLE>
                <ARTIST>Bonnie Tylor</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>CBS Records</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1988</YEAR>
        </CD>
</CATALOG>

What I want to do is write a SELECT with each OPTION being a unique
value, in particular for this XML file: COUNTRY.  As I see it, there's
two ways: using KEYs, using "preceding::" -- KEYs are far faster,
preceding is... well... arguably more straightforward.  I'd like to use
KEYs, but I've run into a bit of a wall.

<xsl:key name="KEY_COUNTRY" match="CD" use="COUNTRY" /> 
 -- indexes all the items based on country

<xsl:for-each select="key('KEY_COUNTRY', 'USA')">
        <xsl:value-of select="." /><br/>
</xsl:for-each>
 -- iterates though all items and spits out records where USA is the
country

<xsl:value-of select="key("KEY_COUNTRY", "USA")[1]" />
 -- returns bob dylan's record

Is there any way to get a list of the values, e.g.  USA, UK, etc... ?
 kinda like using the "key" function but without the second parameter?

I ended up writing a template like such -- which would return me a
SELECT with a series of options, each being unique:

<xsl:call-template name="selectField">
<xsl:with-param name="currentNode" select="CATALOG/CD/COUNTRY"/>
<xsl:with-param name="name" select="'COUNTRY'"/>
</xsl:call-template>

<xsl:template name="selectField">
        <xsl:param name="currentNode" select="."/>
        <xsl:param name="name" select="."/>

        <xsl:value-of select="$name"/>: 
        <select>
                <option selected="SELECTED" value=""></option>
                <xsl:for-each
select="$currentNode[not(.=preceding::*[local-name()=$name])]">
                        <option value="{.}"><xsl:value-of
select="."/></option>
                </xsl:for-each>
        </select>
</xsl:template>

But should I be kicking myself in the pants for using preceding?
  Isn't it going to be painfully slow for my users when I get to actual
datasets?

Thanks in advance

-Tyler Waters

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--