XSLT substracting Amount

73 views Asked by At

Please help in xslt 1.0. Here we are trying to settle the total amount value with child amount values. if the TotalAmount is settled with first or second iterations then no need to go to 3rd iterations keep values as it is.

The TotalAmount value from header needs to be adjusted with childAmounts until TotalAmount becomes zero.

Logic:

condition1:

if (childAmount1>0 and TotalAmount>0)
{

if TotalAmount>=childAmount1
{
TotalAmount=TotalAmount-childAmount1
childAmount1=0
 }
 else
 {
 childAmount1=childAmount1 - TotalAmount
 TotalAmount=0
 exit the loop
 }
 }
 else exit loop

condition2:

if (childAmount2>0 and TotalAmount>0)
{

if TotalAmount>=childAmount2
{
TotalAmount=TotalAmount - childAmount2
 childAmount2=0
 }
 else
 {
 childAmount2=childAmount2 - TotalAmount
 TotalAmount=0
 exit the loop
 }
 }
 else exit loop

input:

<header>
<TotalAmount>60</TotalAmount>
<List>
<info>
<serialNo>1</serialNo>
<childAmount1>20</childAmount1>..20 substracted from 60 then it will become zero remaining TotalAmount 40
<childAmount2>10</childAmount2> 10 is substracted from 40 remaining TotalAmount 30
</info>
<info>
<serialNo>2</serialNo>
<childAmount1>20</childAmount1> 20 is substracted from TotalAmount 30 remaining Total amount 10
<childAmount2>10</childAmount2>10 is substarcted from TotalAmount 10 become zero so exit from here no need to continued other iterations
</info>
<info>
<serialNo>3</serialNo>
<childAmount1>20</childAmount1>
<childAmount2>10</childAmount2>
</info>
</List>
</header>

Output:

<header>
<TotalAmount>60</TotalAmount>
<List>
<info>
<serialNo>1</serialNo>
<childAmount1>0</childAmount1>.
<childAmount2>0</childAmount2>
</info>
<info>
<serialNo>2</serialNo>
<childAmount1>0</childAmount1>
<childAmount2>0</childAmount2>
</info>
<info>
<serialNo>3</serialNo>
<childAmount1>20</childAmount1>
<childAmount2>10</childAmount2>
</info>
</List>
</header>
1

There are 1 answers

2
y.arazim On

This is a very inconvenient format to work with. Try perhaps something like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="header">
    <xsl:copy>
        <xsl:copy-of select="TotalAmount"/>
        <List>
            <xsl:call-template name="process">
                <xsl:with-param name="infos" select="List/info"/>
            </xsl:call-template>
        </List>
    </xsl:copy>
</xsl:template>

<xsl:template name="process">
    <xsl:param name="infos"/>
    <xsl:param name="balance" select="TotalAmount"/>
    <xsl:if test="$infos">
        <xsl:variable name="info" select="$infos[1]" />
        <xsl:variable name="balance1" select="$balance - $info/childAmount1" />
        <xsl:variable name="balance2" select="$balance1 - $info/childAmount2" />
        <info>
            <xsl:copy-of select="$info/serialNo"/>
            <childAmount1>
                <xsl:choose>
                    <xsl:when test="$balance1 > 0">
                        <xsl:value-of select="$balance1"/>
                    </xsl:when>
                    <xsl:otherwise>0</xsl:otherwise>
                </xsl:choose>
            </childAmount1>
            <childAmount2>
                <xsl:choose>
                    <xsl:when test="$balance2 > 0">
                        <xsl:value-of select="$balance2"/>
                    </xsl:when>
                    <xsl:otherwise>0</xsl:otherwise>
                </xsl:choose>
            </childAmount2>
        </info>
        <xsl:call-template name="process">
            <xsl:with-param name="infos" select="$infos[position() > 1]"/>
            <xsl:with-param name="balance" select="$balance2"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

The logic I used and my result are slightly different from yours, but it makes more sense to me this way. And it shouldn't be too difficult to make the necessary adjustments, if required.