0

Below is my XSLT structure and I am trying to add the (EARNEDINCOMEAMOUNT * PAYMENTFREQUENCYTYPE) for each EARNEDINCOME node.

XSLT structure:

<EMPLOYMENT CUSTOMERNUMBER="1001349" CUSTOMERVERSIONNUMBER="31"  EMPLOYMENTSEQUENCENUMBER="2" EMPLOYMENTSTATUS="110" >  
  <EARNEDINCOME CUSTOMERNUMBER="1001349" CUSTOMERVERSIONNUMBER="31" EMPLOYMENTSEQUENCENUMBER="2" EARNEDINCOMESEQUENCENUMBER="1" EARNEDINCOMEAMOUNT="1142" PAYMENTFREQUENCYTYPE="12" PAYMENTFREQUENCYTYPE_TEXT="Monthly" />  
  <EARNEDINCOME CUSTOMERNUMBER="1001349" CUSTOMERVERSIONNUMBER="31" EMPLOYMENTSEQUENCENUMBER="2" EARNEDINCOMESEQUENCENUMBER="2" EARNEDINCOMEAMOUNT="4960" PAYMENTFREQUENCYTYPE="12" PAYMENTFREQUENCYTYPE_TEXT="Monthly" />
</EMPLOYMENT> 

What I have tried so far is.

<xsl:for-each select=".//EARNEDINCOME">
    <xsl:attribute name="GROSSINCOME">
    <xsl:value-of select="(EARNEDINCOME[@EMPLOYMENTSEQUENCENUMBER=$vSequenceNumber]/@EARNEDINCOMEAMOUNT * EARNEDINCOME[@EMPLOYMENTSEQUENCENUMBER=$vSequenceNumber]/@PAYMENTFREQUENCYTYPE)" />
    <xsl:value-of select="@EARNEDINCOMEAMOUNT*@PAYMENTFREQUENCYTYPE"/>
    </xsl:attribute>
</xsl:for-each>

What is get out of this is just multiplication of each node but I am not able to add it. Please help.

0

1 Answer 1

1

There are different ways to get the desired sum based on the XSLT version being used.

XSLT 2.0 allows using the XPath in the sum() function so the below code will provide the desired output.

<xsl:template match="EMPLOYMENT">
    <SOMENODE>
        <xsl:attribute name="GROSSINCOME">
            <xsl:value-of select="sum(EARNEDINCOME/(@EARNEDINCOMEAMOUNT * @PAYMENTFREQUENCYTYPE))" />
        </xsl:attribute>
    </SOMENODE>
</xsl:template>

XSLT 1.0 does not provide a simple way to achieve this. If using XSLT 1.0, you will have write a recursive template call which will do the product for every node and then keep on adding them for all the nodes.

<xsl:template match="EMPLOYMENT">
    <SOMENODE>
        <xsl:attribute name="GROSSINCOME">
            <xsl:call-template name="ProductSum">
                <xsl:with-param name="earnedIncome" select="*" />
            </xsl:call-template>
        </xsl:attribute>
    </SOMENODE>
</xsl:template>

<xsl:template name="ProductSum">
    <xsl:param name="earnedIncome" />
    <xsl:param name="sum" select="0" />

    <xsl:variable name="nodeStart" select="$earnedIncome[1]" />
    <xsl:variable name="nodeEnd" select="$earnedIncome[position() > 1]" />
    <xsl:variable name="currSum" select="$nodeStart/@EARNEDINCOMEAMOUNT * $nodeStart/@PAYMENTFREQUENCYTYPE" />
    <xsl:choose>
        <xsl:when test="not($nodeEnd)">
            <xsl:value-of select="$sum + $currSum" />
        </xsl:when>
        <xsl:otherwise>
            <!-- Recursive call to the same template -->
            <xsl:call-template name="ProductSum">
                <xsl:with-param name="earnedIncome" select="$nodeEnd" />
                <xsl:with-param name="sum" select="$sum + $currSum" />
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

Using EXSLT (Extension functions) - If using XSLT 1.0 and if you can use extension functions, the node-set() function can be used.

<xsl:template match="/EMPLOYMENT">
    <!-- create a variable to store the EARNEDINCOME nodes along 
         with a new attribute ANNUALINCOME that has the product 
         of the attributes -->
    <xsl:variable name="nodes">
        <xsl:for-each select="EARNEDINCOME">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <!-- add a new attribute to EARNEDINCOME node -->
                <xsl:attribute name="ANNUALINCOME">
                    <xsl:value-of select="@EARNEDINCOMEAMOUNT * @PAYMENTFREQUENCYTYPE" />
                </xsl:attribute>
            </xsl:copy>
        </xsl:for-each>
    </xsl:variable>
    <SOMENODE>
        <xsl:attribute name="GROSSINCOME">
            <!-- use the node-set function to compute the sum
                 of this new attribute from the above variable -->
            <xsl:value-of select="sum(exslt:node-set($nodes)/EARNEDINCOME/@ANNUALINCOME)" />
        </xsl:attribute>
    </SOMENODE>
</xsl:template>  

All the XSLTs will give the same output

<SOMENODE GROSSINCOME="73224"/>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.