xslt compare two different nodes and then combine -
i have requirement need show difference amount (<totalamount>) based on 2 different values in different section.the input xml below.
<txlife xmlns="http://acord.org/standards/life/2"> <txliferequest> <fundcode>ltrw00</fundcode> <accountnumber>34142</accountnumber> <reversalind>cr</reversalind> <totalamount>1600</totalamount> </txliferequest> <txliferequest> <fundcode>ltrw00</fundcode> <accountnumber>34142</accountnumber> <reversalind>dr</reversalind> <totalamount>350</totalamount> </txliferequest> <txliferequest> <fundcode>lul500</fundcode> <accountnumber>34142</accountnumber> <reversalind>cr</reversalind> <totalamount>500</totalamount> </txliferequest> <txliferequest> <fundcode>lul500</fundcode> <accountnumber>34142</accountnumber> <reversalind>dr</reversalind> <totalamount>800</totalamount> </txliferequest> </txlife> from above xml criteria find difference amount <fundcode> , <accountnumber>. if sections having same <fundcode> , <accountnumber> retrieve <totalamount> , find difference.
for example above xml:-
there 2 sections same <fundcode> , <accountnumber> ltrw00 , 34142. difference of <totalamount> 1250 (1600 - 250). need repeat logic on other sections also.
so final output xml should this:
<txlife xmlns="http://acord.org/standards/life/2"> <txliferequest> <fundcode>ltrw00</fundcode> <accountnumber>34142</accountnumber> <reversalind>cr</reversalind> <totalamount>1250</totalamount> </txliferequest> <txliferequest> <fundcode>lul500</fundcode> <accountnumber>34142</accountnumber> <reversalind>dr</reversalind> <totalamount>300</totalamount> </txliferequest> </txlife> and if observe <reversalind> cr/dr should identified based on highest totalamount value.
i have applied xslt below no output. ideas how implement in xslt 1.0. appreciated.
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0" xmlns:ns="http://acord.org/standards/life/2"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="/ns:txlife/ns:txliferequest"> <xsl:element name="txlife" namespace="http://acord.org/standards/life/2"> <xsl:call-template name="balance"> <xsl:with-param name="total" select="ns:totalamount"></xsl:with-param> </xsl:call-template> <xsl:copy-of select="."/> </xsl:element> </xsl:template> <xsl:template name="balance"> <xsl:param name="total"></xsl:param> <xsl:variable name="reminder" select="0"></xsl:variable> <xsl:variable name="val1"> <xsl:value-of select="$total[1]"/> </xsl:variable> <xsl:variable name="val2"> <xsl:value-of select="$total[position() > 1]"/> </xsl:variable> <xsl:if test="$val1 > $val2"> <remainingamount><xsl:value-of select="$val1 - $val2"/></remainingamount> </xsl:if> </xsl:template> </xsl:stylesheet>
try following solution based on muenchian grouping. txliferequest grouped fundcode , accountnumber.
it shout work if there more 2 entries in group. data group output (especial reversalind) 1 highest totalamount. value of totalamount difference of first (highest) totalamount , remaining ones.
it considers request: "and if observe cr/dr should identified based on highest totalamount value."
xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:ns="http://acord.org/standards/life/2"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="ktxliferequest" match="ns:txliferequest" use="concat(ns:fundcode,'#',ns:accountnumber)"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="/*"> <xsl:copy> <xsl:for-each select= "ns:txliferequest[generate-id() = generate-id(key('ktxliferequest',concat(ns:fundcode,'#',ns:accountnumber))[1])]" > <xsl:copy> <xsl:variable name="group" select="key('ktxliferequest',concat(current()/ns:fundcode,'#',current()/ns:accountnumber))" /> <xsl:for-each select= "$group" > <xsl:sort select="ns:totalamount" data-type="number" order="descending"/> <xsl:if test="position() = 1"> <xsl:apply-templates select="*[local-name() != 'totalamount']" /> <totalamount> <xsl:value-of select="ns:totalamount - sum($group/ns:totalamount)+ ns:totalamount" /> </totalamount> </xsl:if> </xsl:for-each> </xsl:copy> </xsl:for-each> </xsl:copy> </xsl:template> </xsl:stylesheet> which generate following output:
<txlife xmlns="http://acord.org/standards/life/2"> <txliferequest> <fundcode>ltrw00</fundcode> <accountnumber>34142</accountnumber> <reversalind>cr</reversalind> <totalamount xmlns="">1250</totalamount> </txliferequest> <txliferequest> <fundcode>lul500</fundcode> <accountnumber>34142</accountnumber> <reversalind>dr</reversalind> <totalamount xmlns="">300</totalamount> </txliferequest> </txlife> update additional request calculate grandtotal:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:ns="http://acord.org/standards/life/2"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="ktxliferequest" match="ns:txliferequest" use="concat(ns:fundcode,'#',ns:accountnumber)" /> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="/*"> <xsl:copy> <xsl:for-each select= "ns:txliferequest[generate-id() = generate-id(key('ktxliferequest',concat(ns:fundcode,'#',ns:accountnumber))[1])]" > <xsl:copy> <xsl:variable name="group" select="key('ktxliferequest',concat(current()/ns:fundcode,'#',current()/ns:accountnumber))" /> <xsl:for-each select= "$group" > <xsl:sort select="ns:totalamount" data-type="number" order="descending"/> <xsl:if test="position() = 1"> <xsl:apply-templates select="*[local-name() != 'totalamount']" /> <totalamount> <xsl:value-of select="ns:totalamount - sum($group/ns:totalamount)+ ns:totalamount" /> </totalamount> </xsl:if> </xsl:for-each> </xsl:copy> </xsl:for-each> <grandtotal> <xsl:call-template name="totalsum"> <xsl:with-param name="groups" select= "ns:txliferequest[generate-id() = generate-id(key('ktxliferequest',concat(ns:fundcode,'#',ns:accountnumber))[1])]" /> </xsl:call-template> </grandtotal> </xsl:copy> </xsl:template> <xsl:template name="totalsum"> <xsl:param name="groups" /> <xsl:param name="gpos" select="1"/> <xsl:param name="sum" select="0" /> <xsl:choose> <xsl:when test="$gpos <= count($groups)" > <xsl:variable name="group" select="key('ktxliferequest',concat($groups[$gpos]/ns:fundcode,'#',$groups[$gpos]/ns:accountnumber))" /> <xsl:for-each select= "$group" > <xsl:sort select="ns:totalamount" data-type="number" order="descending"/> <xsl:if test="position() = 1"> <xsl:variable name="acttotal" select="ns:totalamount - sum($group/ns:totalamount)+ ns:totalamount" /> <xsl:call-template name="totalsum"> <xsl:with-param name="groups" select="$groups" /> <xsl:with-param name ="gpos" select="$gpos + 1" /> <xsl:with-param name="sum" select="$sum + $acttotal" /> </xsl:call-template> </xsl:if> </xsl:for-each> </xsl:when> <xsl:otherwise> <xsl:value-of select="$sum"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
Comments
Post a Comment