Reputation: 35
Simply put I have XML similar to (trimmed a lot):
<Event>
<Parameter>
<Name>#ID</Name>
<Value>3</Value>
</Parameter>
<Parameter>
<Name>AMT</Name>
<Value>911</Value>
</Parameter>
</Event>
<Event>
<Parameter>
<Name>#ID</Name>
<Value>3</Value>
</Parameter>
<Parameter>
<Name>AMT</Name>
<Value>10</Value>
</Parameter>
</Event>
<Event>
<Parameter>
<Name>#ID</Name>
<Value>4</Value>
</Parameter>
<Parameter>
<Name>AMT</Name>
<Value>11</Value>
</Parameter>
</Event>
From this I want to process all Event elements that have the same "Value" for the Parameter that has a Name of "#ID". So the sample output might be:
<Result>
<ID>3</ID>
<AMT>10</AMT>
<AMT>11</AMT>
<Result>
<Result>
<ID>4</ID>
<AMT>11</AMT>
<Result>
It is a little more complicated than that but hopefully an answer to this will be sufficient to get me unstuck. My main problem is I don't know how to collect and process together all of the Event elements that have the same Value in a Parameter with a Name of #ID.
Thanks.
Upvotes: 2
Views: 1683
Reputation: 70598
As you are using XSLT2.0, you can use xsl:for-each-group to group your event elements by their ID in the parameter element
<xsl:for-each-group select="Event" group-by="Parameter[Name='#ID']/Value">
I am not sure if you wanted to total the "AMT" elements, or output them individually, but to output them individually, you would do this (with a separate matching template to output them)
<xsl:apply-templates select="current-group()/Parameter[Name='AMT']"/>
And to total them up you would do this
<xsl:value-of select="sum(current-group()/Parameter[Name='AMT']/Value)"/>
Here is the full XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:for-each-group select="Event" group-by="Parameter[Name='#ID']/Value">
<Result>
<ID>
<!-- <xsl:value-of select="Parameter[Name='#ID']/Value"/> -->
<xsl:value-of select="current-grouping-key()" />
</ID>
<xsl:apply-templates select="current-group()/Parameter[Name='AMT']"/>
<TOTAL_AMT>
<xsl:value-of select="sum(current-group()/Parameter[Name='AMT']/Value)"/>
</TOTAL_AMT>
</Result>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="Parameter[Name='AMT']">
<AMT>
<xsl:value-of select="Value"/>
</AMT>
</xsl:template>
</xsl:stylesheet>
When applied to the following XML
<Events>
<Event>
<Parameter>
<Name>#ID</Name>
<Value>3</Value>
</Parameter>
<Parameter>
<Name>AMT</Name>
<Value>911</Value>
</Parameter>
</Event>
<Event>
<Parameter>
<Name>#ID</Name>
<Value>3</Value>
</Parameter>
<Parameter>
<Name>AMT</Name>
<Value>10</Value>
</Parameter>
</Event>
<Event>
<Parameter>
<Name>#ID</Name>
<Value>4</Value>
</Parameter>
<Parameter>
<Name>AMT</Name>
<Value>11</Value>
</Parameter>
</Event>
</Events>
The following is output
<Result>
<ID>3</ID>
<AMT>911</AMT>
<AMT>10</AMT>
<TOTAL_AMT>921</TOTAL_AMT>
</Result>
<Result>
<ID>4</ID>
<AMT>11</AMT>
<TOTAL_AMT>11</TOTAL_AMT>
</Result>
Upvotes: 1