I'm fairly new to XSLT, I've been trying to piece some of the other examples posted on this topic but I still can't quite get it right
This is an example of my XML
<?xml version="1.0" encoding="UTF-8"?>
<customers>
<customer>
<customerID>1234</customerID>
<invoiceNo>5698</invoiceNo>
<amount>1000.00</amount>
</customer>
<customer>
<customerID>7755</customerID>
<invoiceNo>7864</invoiceNo>
<amount>1500.00</amount>
</customer>
<customer>
<customerID>1234</customerID>
<invoiceNo>3697</invoiceNo>
<amount>800.00</amount>
</customer>
</customers>
The result I'm looking for is this
<?xml version="1.0"?>
<customers>
<customer>
<customerID>1234</customerID>
<totalAmount>1800</totalAmount>
</customer>
<customer>
<customerID>7755</customerID>
<totalAmount>1500</totalAmount>
</customer>
</customers>
This is my current XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="kCustomer" match="customer" use="customerID" />
<xsl:template match="customers">
<customers>
<xsl:apply-templates select="customer[generate-id()=generate-id(key('kCustomer',customerID[1])]"/>
</customers>
</xsl:template>
<xsl:template match="customer" >
<customer>
<xsl:for-each select="key('kCustomer', customerID)">
<customerID><xsl:value-of select="key('kCustomer',customerID)/customerID"/></customerID>
<totalAmount><xsl:value-of select="sum(key('kCustomer', customerID)/amount)" /></totalAmount>
</xsl:for-each>
</customer>
</xsl:template>
</xsl:stylesheet>`
It's giving me the SUM value but it's printing duplicates based on the numbers of invoices.
<?xml version="1.0"?>
<customers>
<customer>
<customerID>1234</customerID>
<totalAmount>1800</totalAmount>
<customerID>1234</customerID>
<totalAmount>1800</totalAmount>
</customer>
<customer>
<customerID>7755</customerID>
<totalAmount>1500</totalAmount>
</customer>
</customers>
Any pointers would be appreciated
CodePudding user response:
Change:
<xsl:template match="customer" >
<customer>
<xsl:for-each select="key('kCustomer', customerID)">
<customerID><xsl:value-of select="key('kCustomer',customerID)/customerID"/></customerID>
<totalAmount><xsl:value-of select="sum(key('kCustomer', customerID)/amount)" /></totalAmount>
</xsl:for-each>
</customer>
</xsl:template>
to:
<xsl:template match="customer">
<customer>
<xsl:copy-of select="customerID"/>
<totalAmount><xsl:value-of select="sum(key('kCustomer', customerID)/amount)" /></totalAmount>
</customer>
</xsl:template>
For better understanding, read the original article: http://www.jenitennison.com/xslt/grouping/muenchian.html
P.S. Indentation improves readability.
CodePudding user response:
This is a grouping query: a search for "XSLT grouping" will give you lots of information. Grouping becomes very easy in XSLT 2.0 using the xsl:for-each-group
instruction, but in 1.0 you need to use an obscure workaround called "Muenchian grouping" (after its inventor, Steve Muench) - @michael.hor257k has shown you an example using this approach.
But it's best to move to XSLT 2.0 or 3.0 if you can - lots of things become easier.