Reputation: 1813
I found this post on Muenchian grouping XSLT 1.0 Group By, and got part way with what I want to do, but I can't work out how to group my sub-nodes.
My XML looks a little like this:
<NewDataSet>
<Vehicle>
<ManufacturerId>53</ManufacturerId>
<ManufacturerName>VAUXHALL</ManufacturerName>
<Model>Corsa</Model>
</vehicle>
<Vehicle>
<ManufacturerId>53</ManufacturerId>
<ManufacturerName>VAUXHALL</ManufacturerName>
<Model>Astra</Model>
</vehicle>
<Vehicle>
<ManufacturerId>53</ManufacturerId>
<ManufacturerName>VAUXHALL</ManufacturerName>
<Model>Corsa</Model>
</vehicle>
<Vehicle>
<ManufacturerId>54</ManufacturerId>
<ManufacturerName>FORD</ManufacturerName>
<Model>KA</Model>
</vehicle>
<Vehicle>
<ManufacturerId>54</ManufacturerId>
<ManufacturerName>FORD</ManufacturerName>
<Model>Focus</Model>
</vehicle>
<Vehicle>
<ManufacturerId>54</ManufacturerId>
<ManufacturerName>FORD</ManufacturerName>
<Model>KA</Model>
</vehicle>
<Vehicle>
<ManufacturerId>55</ManufacturerId>
<ManufacturerName>CITROEN</ManufacturerName>
<Model>C4</Model>
</vehicle>
<NewDataSet>
This is the code I have thus far
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" />
<xsl:key name="groups" match="/NewDataSet/Vehicle" use="ManufacturerName" />
<xsl:template match="/NewDataSet">
<xsl:apply-templates select="Vehicle[generate-id() = generate-id(key('groups', ManufacturerName)[1])]"/>
</xsl:template>
<xsl:template match="Vehicle">
<div class="makeLnk">
<a href="/stocklist/?ManufacturerId={ManufacturerId}"><xsl:value-of select="ManufacturerName"/></a>
<xsl:for-each select="key('groups', ManufacturerName)">
<div class="modelLnk"><xsl:value-of select="Model"/></div>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
This groups together the ManufacturerNames and lists all the models under. But I would now like to group the models as well, thus removing duplicate names. But can't work out the syntax.
Would appreciate any help.
Thanks.
Upvotes: 1
Views: 248
Reputation: 167716
Use a second key composed of the ManufacturerName
of the Vehicle
and the value of the Model
:
<xsl:key name="model" match="Vehicle/Model" use="concat(../ManufacturerName, '|', .)"/>
then replace
<xsl:template match="Vehicle">
<div class="makeLnk">
<a href="/stocklist/?ManufacturerId={ManufacturerId}"><xsl:value-of select="ManufacturerName"/></a>
<xsl:for-each select="key('groups', ManufacturerName)">
<div class="modelLnk"><xsl:value-of select="Model"/></div>
</xsl:for-each>
</div>
</xsl:template>
with
<xsl:template match="Vehicle">
<div class="makeLnk">
<a href="/stocklist/?ManufacturerId={ManufacturerId}"><xsl:value-of select="ManufacturerName"/></a>
<xsl:for-each select="key('groups', ManufacturerName)/Model[generate-id() =
generate-id(key('model', concat(../ManufacturerName, '|', .))[1])]">
<div class="modelLnk"><xsl:value-of select="."/></div>
</xsl:for-each>
</div>
</xsl:template>
Upvotes: 1