Reputation: 3
I wanted to extract the unique values with a function like select distinct. Eventually I ended up using the xsl:key combination with for-each. I've managed to get the unique value of model, but I can't extract the style that belongs to that model.
I've tried to put together a sample XML.
<PLAYER>
<ALBUM>
<MODEL>AA</MODEL>
<STYLE>BB</STYLE>
<NUMBER>1</NUMBER>
</ALBUM>
<ALBUM>
<MODEL>FF</MODEL>
<STYLE>GG</STYLE>
<NUMBER>2</NUMBER>
</ALBUM>
<ALBUM>
<MODEL>AA</MODEL>
<STYLE>BB</STYLE>
<NUMBER>3</NUMBER>
</ALBUM>
<ALBUM>
<MODEL>FF</MODEL>
<STYLE>GG</STYLE>
<NUMBER>4</NUMBER>
</ALBUM>
<ALBUM>
<MODEL>HH</MODEL>
<STYLE>JJ</STYLE>
<NUMBER>5</NUMBER>
</ALBUM>
</PLAYER>
I need to extract the unique value of MODEL with it's matching STYLE.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:key name="model" match="/player/album/model/text()" use="." />
<xsl:template match="/">
<xsl:for-each select="/player/album/model/text()[generate-id()
= generate-id(key('model',.)[1])]">
<li>
<xsl:value-of select="model"/>
</li>
<li>
<xsl:value-of select="style"/>
</li>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Wanted result:
<MODEL>AA</MODEL>
<STYLE>BB</STYLE>
<MODEL>FF</MODEL>
<STYLE>GG</STYLE>
<MODEL>HH</MODEL>
<STYLE>JJ</STYLE>
Is it possible to extract these unique value-pairs?
Upvotes: 0
Views: 2255
Reputation: 70648
XML (and indeed XSLT) is case-sensitive, so player
in the xpath in your XSLT will not match PLAYER
in your XML (and similar for the other nodes).
Additionally, your xsl:for-each
is selecting text nodes, so doing <xsl:value-of select="model"/>
is looking for a child node, called model
of that text node, which obviously doesn't exist.
You could change the expression to <xsl:value-of select="../../MODEL"/>
, but it might be better to simply change the key to match ALBUM
nodes instead.
Try this XSLT....
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:key name="model" match="/PLAYER/ALBUM" use="MODEL" />
<xsl:template match="/">
<xsl:for-each select="/PLAYER/ALBUM[generate-id() = generate-id(key('model',MODEL)[1])]">
<li>
<xsl:value-of select="MODEL"/>
</li>
<li>
<xsl:value-of select="STYLE"/>
</li>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I am not quite sure if you what your exact wanted result is, as the question shows <MODEL>AA</MODEL><STYLE>BB</STYLE>
as the wanted result, but the XSLT is outputting LI
tags instead, but it is easy enough to adapt.
Upvotes: 1