Reputation: 617
I'm having an issue selecting distinct values for each group. The result just doesn't display on screen. The desired result is shown below:
<xsl:for-each-group select="Items/Item" group-by="ProviderName">
<xsl:sort select="current-grouping-key()"/>
<tr>
<th>
<xsl:value-of select="current-grouping-key()"/>
</th>
</tr>
<tr>
<td>
<xsl:text>Item Number</xsl:text>
</td>
<td>
<xsl:text>Quantity</xsl:text>
</td>
<td>
<xsl:text>Unit Price</xsl:text>
</td>
<td>
<xsl:text>Total</xsl:text>
</td>
</tr>
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
What I intend to do is to select distinct values for current-group()
in the apply-templates
tag which is like this
<xsl:template match="Item">
<xsl:value-of select="distinct-values(./ItemName)"/>
</xsl:template>
I've read several samples on the net and the most optimum way to do so is to employ the generate-id()
function with the for-each-group
loop. But I have tried and get no positive result. This is the source XML:
<Items>
<Item ItemNumber="1148087">
<ProductName>Dolby Metal-Black-Matte</ProductName>
<ProviderName>Vestal Watches</ProviderName>
<Quantity>4</Quantity>
<UnitPrice>67.99</UnitPrice>
</Item>
<Item ItemNumber="1150197">
<ProductName>Vercilli Blk-Tan</ProductName>
<ProviderName>Boston Babes</ProviderName>
<Quantity>1</Quantity>
<UnitPrice>23.99</UnitPrice>
</Item>
<Item ItemNumber="1151464">
<ProductName>Spritz Grape Seat and Extra Seat</ProductName>
<ProviderName>Bambeano</ProviderName>
<Quantity>1</Quantity>
<UnitPrice>56.99</UnitPrice>
</Item>
<Item ItemNumber="1148087">
<ProductName>Dolby Metal-Black-Matte</ProductName>
<ProviderName>Vestal Watches</ProviderName>
<Quantity>2</Quantity>
<UnitPrice>67.99</UnitPrice>
</Item>
<Item ItemNumber="1150197">
<ProductName>Vercilli Blk-Tan</ProductName>
<ProviderName>Boston Babes</ProviderName>
<Quantity>2</Quantity>
<UnitPrice>23.99</UnitPrice>
</Item>
<Item ItemNumber="1150173">
<ProductName>Lucille Tan</ProductName>
<ProviderName>Boston Babes</ProviderName>
<Quantity>1</Quantity>
<UnitPrice>24.99</UnitPrice>
</Item>
<Item ItemNumber="1151464">
<ProductName>Spritz Grape Seat and Extra Seat</ProductName>
<ProviderName>Bambeano</ProviderName>
<Quantity>1</Quantity>
<UnitPrice>56.99</UnitPrice>
</Item>
<Item ItemNumber="1148089">
<ProductName>Plexi Leather-Silver-Black</ProductName>
<ProviderName>Vestal Watches</ProviderName>
<Quantity>1</Quantity>
<UnitPrice>189.99</UnitPrice>
</Item>
</Items>
Notice that the source XML contains several same ProductName
elements with different ItemNumber
attributes. What I desire is to group all the Item
elements with similar ItemNumber
and do a summation of the quantity. Thanks for the help guys. Really appreciate it.
The example output would be:
Upvotes: 2
Views: 18010
Reputation: 167696
I think you simply want to nest two for-each-group
:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="html" version="5.0" indent="yes"/>
<xsl:template match="Items">
<table>
<xsl:for-each-group select="Item" group-by="ProviderName">
<tbody>
<tr>
<th colspan="4">Provider: <xsl:value-of select="current-grouping-key()"/></th>
</tr>
<tr>
<th>Item Number</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</tbody>
<tbody>
<xsl:for-each-group select="current-group()" group-by="@ItemNumber">
<tr>
<td><xsl:value-of select="current-grouping-key()"/></td>
<td><xsl:value-of select="sum(current-group()/Quantity)"/></td>
<td><xsl:value-of select="UnitPrice"/></td>
<td><xsl:value-of select="format-number(sum(current-group()/(Quantity * UnitPrice)), '0.00')"/></td>
</tr>
</xsl:for-each-group>
</tbody>
<tbody>
<tr>
<th colspan="3">Subtotal</th>
<td><xsl:value-of select="format-number(sum(current-group()/(Quantity * UnitPrice)), '0.00')"/></td>
</tr>
</tbody>
</xsl:for-each-group>
<tbody>
<tr>
<th colspan="3">Total</th>
<td><xsl:value-of select="format-number(sum(Item/(Quantity * UnitPrice)), '0.00')"/></td>
</tr>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 3138
Please have a look with modified version of your XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="/">
<table>
<thead>
<tr>
<th>
<xsl:text>Item Number</xsl:text>
</th>
<th>
<xsl:text>Quantity</xsl:text>
</th>
<th>
<xsl:text>Unit Price</xsl:text>
</th>
<th>
<xsl:text>Total</xsl:text>
</th>
</tr>
</thead>
<tbody>
<xsl:for-each-group select="Items/Item" group-by="@ItemNumber">
<xsl:sort select="current-grouping-key()"/>
<tr>
<td>
<xsl:value-of select="current-grouping-key()"/>
</td>
<td>
<xsl:value-of select="sum(current-group()/Quantity)"/>
</td>
<td>
<xsl:value-of select="current-group()/UnitPrice"/>
</td>
<td>
<xsl:value-of
select="sum(for $x in current-group() return $x/UnitPrice * $x/Quantity)"/>
</td>
</tr>
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</tbody>
</table>
</xsl:template>
<xsl:template match="Item">
<xsl:value-of select="distinct-values(./ItemName)"/>
</xsl:template>
</xsl:stylesheet>
Output:
<table>
<thead>
<tr>
<th>Item Number</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>1148087</td>
<td>6</td>
<td>67.99</td>
<td>407.93999999999994</td>
</tr>
<tr>
<td>1148089</td>
<td>1</td>
<td>189.99</td>
<td>189.99</td>
</tr>
<tr>
<td>1150173</td>
<td>1</td>
<td>24.99</td>
<td>24.99</td>
</tr>
<tr>
<td>1150197</td>
<td>3</td>
<td>23.99</td>
<td>71.97</td>
</tr>
<tr>
<td>1151464</td>
<td>2</td>
<td>56.99</td>
<td>113.98</td>
</tr>
</tbody>
</table>
Upvotes: 3