Reputation: 3
I have a requirement where I need to omit duplicate records. Consider sample below
Following is the input
<ExchangeRates>
<Rate> <!--The exchange rates -->
<SourceCurrency>INR</SourceCurrency>
<TargetCurrency>USD</TargetCurrency>
<ConversionFactor>60.2</ConversionFactor>
</Rate>
<Rate>
<SourceCurrency>INR</SourceCurrency>
<TargetCurrency>USD</TargetCurrency>
<ConversionFactor>58.2</ConversionFactor>
</Rate>
<Rate>
<SourceCurrency>YEN</SourceCurrency>
<TargetCurrency>INR</TargetCurrency>
<ConversionFactor>.52</ConversionFactor>
</Rate>
<Rate>
<SourceCurrency>SAR</SourceCurrency>
<TargetCurrency>INR</TargetCurrency>
<ConversionFactor>16.50</ConversionFactor>
</Rate>
<Rate>
<SourceCurrency>SAR</SourceCurrency>
<TargetCurrency>INR</TargetCurrency>
<ConversionFactor>16.50</ConversionFactor>
</Rate>
</ExchangeRates>
Now what i wanna do is remove all duplicates. As well as if there is same pair of Source and TargetCurrency , I want to send ahead the first record and drop others.
Output shud be like
<ExchangeRates>
<Rate>
<SourceCurrency>INR</SourceCurrency>
<TargetCurrency>USD</TargetCurrency>
<ConversionFactor>60.2</ConversionFactor>
</Rate>
<Rate>
<SourceCurrency>YEN</SourceCurrency>
<TargetCurrency>INR</TargetCurrency>
<ConversionFactor>.52</ConversionFactor>
</Rate>
<Rate>
<SourceCurrency>SAR</SourceCurrency>
<TargetCurrency>INR</TargetCurrency>
<ConversionFactor>16.50</ConversionFactor>
</Rate>
</ExchangeRates>
I found that following XSLT removes duplicates. ie. if inner elements are exactly same. The below code helps me easily avoid duplicates. It identifies the duplicates based on contents inside the outer tag.
But I want to xslt to remove records if exchange rates come for same pair of currencies but multiple ConversionFactors.
<?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="yes"/>
<xsl:template match="@*|node()">
<xsl:if test="not(node()) or not(preceding-sibling::node()[.=string(current())])">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
I need to drop Rates with USD->INR if it occurs multiple times. And forward only the first exchange rate.
Can I get some help in achieving this.
Cheers
Reji
Upvotes: 0
Views: 3061
Reputation: 5432
You need to group Rate
s based on SourceCurrency
and TargetCurrency
. An efficient way is using Muenchian's grouping that uses key:
<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="yes"/>
<xsl:key name="currencyPair" match="Rate" use="concat(SourceCurrency,' ',TargetCurrency)"/>
<xsl:template match="ExchangeRates">
<xsl:copy>
<xsl:for-each select="Rate[count(. | key('currencyPair',concat(SourceCurrency,' ',TargetCurrency))[1]) = 1]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2