sirwebber
sirwebber

Reputation: 157

Using <xsl:key> to identify unique values of all nodes of a particular type

I am using <xsl:key> to identify unique values amongst a set of nodes. However, some of my nodes are nested, and my current implementation is not picking up those values.

Say I have the following XML structure:

<Concepts>
<Concept>
    <Type>A</Type>
</Concept>

<Concept>
    <Type>B</Type>
</Concept>

<Concept>
    <OR>
        <Type>C</Type>
    </OR>
    <OR>
        <Type>D</Type>
    </OR>
</Concept>
</Concepts>

I currently am using the following XSLT1.0 code:

<xsl:key name="types" match="Concepts/Concept" use="Type"/>
<xsl:template match="/">
    <ul>
        <xsl:for-each select="//Concept[generate-id() = generate-id(key('types',Type)[1])]">
            <li><xsl:value-of select="Type"/></li>
        </xsl:for-each>
    </ul>
</xsl:template>

and the result is:

However, I would like the result to be:

Is there any easy solution, or will I have to restructure my XML?

Upvotes: 1

Views: 106

Answers (1)

Tim C
Tim C

Reputation: 70618

Try changing your key to this:

<xsl:key name="types" match="Type" use="."/>

And then your xsl:for-each to this...

<xsl:for-each select="//Type[generate-id() = generate-id(key('types',. )[1])]">

This should give you distinct types. You'd also have to change your <xsl:value-of select="Type"/> to xsl:value-of select="."/>

Note, if you had other Type elements in your XML, but you only wanted ones within Concept elements, you could also do this....

<xsl:key name="types" match="Type[ancestor::Concept]" use="."/>

Upvotes: 2

Related Questions