Search code examples
xsltxslt-2.0

Check each sequence of element


I need to check each occurrence of <Record> if the value of attribute currencyID should always have the same value. If one of the attribute has different value it should output the value of '1' in new element <Value> else '0'. My XSLT is this:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" version="1.0"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="Amount">
    <Value>
       <xsl:value-of select="if (not((./@currencyID)[1] != ./@currencyID)) then '1' else '0'"/>
    </Value>
</xsl:template>
</xsl:stylesheet>

My xml file is:

<Data>
<Record>
    <Amount currencyID="EUR">1.00</Amount>
    <ID>111</ID>
</Record>
<Record>
    <Amount currencyID="EUR">2.00</Amount>
    <ID>222</ID>
</Record>
<Record>
    <Amount currencyID="GBP">3.00</Amount>
    <ID>333</ID>
</Record>
</Data>

GENERATED OUTPUT:

<Data>
<Record>
    <Value>1</Value>
    <ID>111</ID>
</Record>
<Record>
    <Value>1</Value>
    <ID>222</ID>
</Record>
<Record>
    <Value>1</Value>
    <ID>333</ID>
</Record>
</Data>

The generated output is correct, however, if I change the value of currencyID in the 3rd occurrence to 'EUR', the value generated should be '0'. But, currently I get the same output. Is there something wrong in my condition?

Thank you.


Solution

  • What you could do, is use a global variable to check if all the currencies are the same or not, and then just use that output the value.

    Try this XSLT

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" version="1.0"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:variable name="curr" select="if (/Data/Record[1]/Amount/@currencyID != /Data/Record/Amount/@currencyID) then '1' else '0'" />
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Amount">
        <Value>
           <xsl:value-of select="$curr"/>
        </Value>
    </xsl:template>
    </xsl:stylesheet>