xslt sum / group

<orderform id="1">
    <Items quantity="1" productid="AAA" cy_lineitem_total="72" >
       <saved_orderlevel_discounts_applied cy_discount_amount="30" discount_name="MVP Discount" discount_id="243"/>
       <saved_orderlevel_discounts_applied cy_discount_amount="10" discount_name="VIP Discount" discount_id="2"/>
    </Items>
    <Items quantity="1" productid="AAB" cy_lineitem_total="100.2" >
       <saved_orderlevel_discounts_applied cy_discount_amount="20" discount_name="MVP Discount" discount_id="243"/>
    </Items>
</orderform>

how can i transform the above xml into  the fragment below?
Notice that the saved_orderlevel_discounts_applied nodes have been grouped by discount_id and the cy_discount_amount has been summed.  
I need to do it in xslt, I am open to using the msxml extensions (? node-set() ?) but I can't use inline functions.

<orderform id="1">
    <Items quantity="1" productid="AAA" cy_lineitem_total="72" />
    <Items quantity="1" productid="AAB" cy_lineitem_total="100.2" />
       <saved_orderlevel_discounts_applied cy_discount_amount="50" discount_name="MVP Discount" discount_id="243" />
       <saved_orderlevel_discounts_applied cy_discount_amount="10" discount_name="VIP Discount" discount_id="2"/>
</orderform>
lunkyAsked:
Who is Participating?
 
ThogekConnect With a Mentor Commented:
0
 
ThogekCommented:
In your XMLs above, it appears that the saved_orderlevel_discounts_applied elements are grouped regardless of which Items element each originally belonged to.  Is this intentional?  (Or should they be grouped within each Items element?)
0
 
b1xml2Connect With a Mentor Commented:
XML
===
<?xml version="1.0" encoding="utf-8" ?>
<root>
<orderform id="1">
    <Items quantity="1" productid="AAA" cy_lineitem_total="72" >
       <saved_orderlevel_discounts_applied cy_discount_amount="30" discount_name="MVP Discount" discount_id="243"/>
       <saved_orderlevel_discounts_applied cy_discount_amount="10" discount_name="VIP Discount" discount_id="2"/>
    </Items>
    <Items quantity="1" productid="AAB" cy_lineitem_total="100.2" >
       <saved_orderlevel_discounts_applied cy_discount_amount="20" discount_name="MVP Discount" discount_id="243"/>
    </Items>
</orderform>
<orderform id="2">
    <Items quantity="3" productid="AAA" cy_lineitem_total="72" >
       <saved_orderlevel_discounts_applied cy_discount_amount="50" discount_name="MVP Discount 2" discount_id="242"/>
       <saved_orderlevel_discounts_applied cy_discount_amount="10" discount_name="VIP Discount 2" discount_id="1"/>
    </Items>
    <Items quantity="1" productid="AAB" cy_lineitem_total="100.2" >
       <saved_orderlevel_discounts_applied cy_discount_amount="40" discount_name="MVP Discount 2" discount_id="242"/>
    </Items>
</orderform>
</root>


XSLT
====
<?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" version="1.0" encoding="UTF-8" indent="no" />
<xsl:key name="saved" match="saved_orderlevel_discounts_applied" use="concat(@discount_id,':',ancestor::orderform/@id)" />
<xsl:template match="@* | node()">
<xsl:copy><xsl:apply-templates select="@* | node()" /></xsl:copy>
</xsl:template>

<xsl:template match="orderform">
<xsl:variable name="id" select="string(@id)" />
<orderform>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="Items" />
<xsl:apply-templates select="descendant::saved_orderlevel_discounts_applied[count(.|key('saved',concat(@discount_id,':',$id))[1]) = 1]" mode="group"/>
</orderform>
</xsl:template>

<!-- dont process elements inside Items -->
<xsl:template match="Items/*" />

<!-- processing the descendant accordingly -->
<xsl:template match="saved_orderlevel_discounts_applied" mode="group">
<saved_orderlevel_discounts_applied><xsl:apply-templates select="@*" /></saved_orderlevel_discounts_applied>
</xsl:template>

<!-- process the sum attribute -->
<xsl:template match="saved_orderlevel_discounts_applied/@cy_discount_amount">
<xsl:attribute name="cy_discount_amount"><xsl:value-of select="sum(key('saved',concat(../@discount_id,':',ancestor::orderform/@id))/@cy_discount_amount)" /></xsl:attribute>
</xsl:template>

</xsl:stylesheet>

 
Output
=====
<?xml version="1.0" encoding="utf-8"?>
<root>
      <orderform id="1">\
            <Items quantity="1" productid="AAA" cy_lineitem_total="72"></Items>
            <Items quantity="1" productid="AAB" cy_lineitem_total="100.2"></Items>
            <saved_orderlevel_discounts_applied cy_discount_amount="50" discount_name="MVP Discount" discount_id="243"></saved_orderlevel_discounts_applied>
            <saved_orderlevel_discounts_applied cy_discount_amount="10" discount_name="VIP Discount" discount_id="2"></saved_orderlevel_discounts_applied>
      </orderform>
      <orderform id="2">
            <Items quantity="3" productid="AAA" cy_lineitem_total="72"></Items>
            <Items quantity="1" productid="AAB" cy_lineitem_total="100.2"></Items>
            <saved_orderlevel_discounts_applied cy_discount_amount="90" discount_name="MVP Discount 2" discount_id="242"></saved_orderlevel_discounts_applied>
            <saved_orderlevel_discounts_applied cy_discount_amount="10" discount_name="VIP Discount 2" discount_id="1"></saved_orderlevel_discounts_applied>
      </orderform>
</root>
0
 
b1xml2Commented:
*knock* *knock* anybody home?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.