xmlxsltxslt-2.0

Need to fetch the amount from the different rates


I need to fetch the particular amount from the multiple rates using the same band values

Input xml I'm having:

<Rates>
    <Rate>
        <Code>2000</Code>
        <Type>Life</Type>
        <GRates>
            <GRate>
                <band>&lt;25</band>
                <amount>0.04</amount>
            </GRate>
            <GRate>
                <band>25-29</band>
                <amount>0.05</amount>
            </GRate>
            <GRate>
                <band>30-34</band>
                <amount>0.06</amount>
            </GRate>
        </GRates>
    </Rate>
    <Rate>
        <Code>2000</Code>
        <Type>Add</Type>
        <GRates>
            <GRate>
                <band>&lt;25</band>
                <amount>0.08</amount>
            </GRate>
            <GRate>
                <band>25-29</band>
                <amount>0.10</amount>
            </GRate>
            <GRate>
                <band>30-34</band>
                <amount>0.12</amount>
            </GRate>
        </GRates>
    </Rate>
    <Rate>
        <Code>2000</Code>
        <Type>Sub</Type>
        <GRates>
            <GRate>
                <band>40-45</band>
                <amount>0.02</amount>
            </GRate>
            <GRate>
                <band>46-50</band>
                <amount>0.03</amount>
            </GRate>
            <GRate>
                <band>51-55</band>
                <amount>0.01</amount>
            </GRate>
        </GRates>
    </Rate>
</Rates>

XSL I have tried the below:

<xsl:template match="Rates">
    <xsl:param name="Group" as="element()" tunnel="yes"/>
    <xsl:for-each select="($Group//Rates/Rate[descendant::GRate][Type='Life'])[1]//GRate">
        <row>
            <entry align="center" colsep="1">
                <xsl:value-of select="band"/>
            </entry>
            <xsl:for-each select="$Group//Rates/Rate[Type='Life']">
                <entry>
                    <p>
                        $<xsl:value-of select="amount"/>
                    </p>
                </entry>
                <entry>
                    <p>
                        $<xsl:value-of select="$Group//Rates/Rate[Type='Add']/amount"/>
                    </p>
                </entry>
            </xsl:for-each>
        </row>
    </xsl:for-each>
</xsl:template>

Output I getting as twice and fetching from 'Life' Rate

<row>
    <entry align="center" colsep="1">&lt;25</entry>
    <entry>
        <p>$0.04</p>
    </entry>
    <entry>
        <p>$0.04</p>
    </entry>
</row>
<row>
    <entry align="center" colsep="1">25-29</entry>
    <entry>
        <p>$0.05</p>
    </entry>
    <entry>
        <p>$0.05</p>
    </entry>
</row>
<row>
    <entry align="center" colsep="1">30-34</entry>
    <entry>
        <p>$0.06</p>
    </entry>
    <entry>
        <p>$0.06</p>
    </entry>
</row>

Expected output:

<row>
    <entry align="center" colsep="1">&lt;25</entry>
    <entry>
        <p>$0.04</p>
    </entry>
    <entry>
        <p>$0.08</p>
    </entry>
</row>
<row>
    <entry align="center" colsep="1">25-29</entry>
    <entry>
        <p>$0.05</p>
    </entry>
    <entry>
        <p>$0.10</p>
    </entry>
</row>
<row>
    <entry align="center" colsep="1">30-34</entry>
    <entry>
        <p>$0.06</p>
    </entry>
    <entry>
        <p>$0.12</p>
    </entry>
</row>

The band value is common for both "Life" and "Add" rates, But the amount is differing. So I have used the xsl:for-each. Due to that 'Add' rates are not picking and 'Life' rates are coming twice.


Solution

  • The question is confusing because your code seems to want to include only rates of type Life, but the expected output shows those of type Add too.

    The correct way to get such output would be:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/Rates">
        <xsl:for-each-group select="Rate[Type=('Life', 'Add')]/GRates/GRate" group-by="band">
            <row>
                <entry align="center" colsep="1">
                    <xsl:value-of select="band"/>
                </entry>
                <xsl:for-each select="current-group()">
                    <entry>
                        <p>
                            <xsl:value-of select="format-number(amount, '$0.00')"/>
                        </p>
                    </entry>
                </xsl:for-each>
            </row>
        </xsl:for-each-group>
    </xsl:template>
    
    </xsl:stylesheet>