Need a help w/ the following: Has a XML with this:
<group>
<S9>
<ByAddress>
<Receipts>
<ID>10</ID>
<PaymentAmt>232.23</PaymentAmt>
<Tax>0.16</Tax>
</Receipts>
<Receipts>
<ID>20</RecID>
<PaymentAmt>232.23</PaymentAmt>
<Tax>0.16</Tax>
</Receipts>
<Receipts>
<ID>30</RecID>
<PaymentAmt>109.04</PaymentAmt>
<Tax>0.16</Tax>
</Receipts>
<Receipts>
<ID>40</RecID>
<PaymentAmt>232.23</PaymentAmt>
<Tax>0.16</Tax>
</Receipts>
</ByAddress>
</S9>
</group>
In the current XSL I can convert using only
format-number(Sum(group/S9/ByAddress/Receipts/PaymentAmt div (1 group/S9/ByAddress/Receipts/Tax)),'0.00')
in order to have it as NET Amount, besides the Gross Amount (as PaymentAmt) for each line, since the final XML needs to print both by Line a Total Amount. So, each line has the format-number(PaymentAmt div (1 Tax),'0.00')
. The issue is generated as a rounding issue since the target system is calculating the Total by line. In this sample:
> Line1 200.20
> Line2 94.00
> Line3 200.20
> Line4 200.20
> Total 694.60
But the Total by the formula in the schema is 694.59 (0.01 dif) - while the calculation is not printed the results ends with all decimals precision (694.594827) and results always in 0.01 to 0.03 UP/DOWN (for multiple cases).
Question: Is it possible to keep the results from the lines (used in the for-each node) or add those results in a Totalization? XSLT is somehow this for lines:
<Items>
<xsl:for-each select="Group/S9/ByAddress/Receipts">
<xsl:attribute name="TaxableAmt">
<xsl:value-of select="format-number(abs((PaymentAmt div (1 Tax))),'0.00')"></xsl:value-of>
</xsl:attribute>
<xsl:attribute name="TaxRate">
<xsl:value-of select="format-number(abs(Tax),'0.00')"></xsl:value-of>
</xsl:attribute>
<xsl:attribute name="TaxAmt">
<xsl:value-of select="format-number(abs((PaymentAmt * (Tax))),'0.00')"></xsl:value-of>
</xsl:attribute>
</xsl:for-each>
</Items>
Total -->
<Total>
<Taxes>
<xsl:attribute name="TaxableAmt">
<xsl:value-of select="format-number(abs(sum(group/S9/ByAddress/Receipts/PaymentAmt) div (1 group/S9/ByAddress/Receipts/Tax))),'0.00')"></xsl:value-of>
</xsl:attribute>
<xsl:attribute name="TaxRate">
<xsl:value-of select="format-number(abs(group/S9/ByAddress/Receipts/Tax),'0.00')"></xsl:value-of>
</xsl:attribute>
<xsl:attribute name="TaxAmt">
<xsl:value-of select="format-number(abs(sum(PaymentAmt * (Tax))),'0.00')"></xsl:value-of>
</xsl:attribute>
</Taxes>
</Total>
CodePudding user response:
Consider the following simplified example:
XML (corrected to be well-formed!!)
<group>
<S9>
<ByAddress>
<Receipts>
<ID>10</ID>
<PaymentAmt>232.23</PaymentAmt>
<Tax>0.16</Tax>
</Receipts>
<Receipts>
<ID>20</ID>
<PaymentAmt>232.23</PaymentAmt>
<Tax>0.16</Tax>
</Receipts>
<Receipts>
<ID>30</ID>
<PaymentAmt>109.04</PaymentAmt>
<Tax>0.16</Tax>
</Receipts>
<Receipts>
<ID>40</ID>
<PaymentAmt>232.23</PaymentAmt>
<Tax>0.16</Tax>
</Receipts>
</ByAddress>
</S9>
</group>
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/group">
<xsl:variable name="items">
<xsl:for-each select="S9/ByAddress/Receipts">
<xsl:variable name="taxable" select="format-number(PaymentAmt div (1 Tax), '0.00')" />
<Item
TaxableAmt="{$taxable}"
TaxRate="{Tax}"
TaxAmt="{format-number(PaymentAmt - xs:decimal($taxable), '0.00')}"/>
</xsl:for-each>
</xsl:variable>
<!-- output -->
<Output>
<Items>
<xsl:copy-of select="$items/Item"/>
</Items>
<Total
TaxableAmt="{format-number(sum($items/Item/@TaxableAmt), '0.00')}"
TaxAmt="{sum($items/Item/@TaxAmt)}"/>
</Output>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<Output>
<Items>
<Item TaxableAmt="200.20" TaxRate="0.16" TaxAmt="32.03"/>
<Item TaxableAmt="200.20" TaxRate="0.16" TaxAmt="32.03"/>
<Item TaxableAmt="94.00" TaxRate="0.16" TaxAmt="15.04"/>
<Item TaxableAmt="200.20" TaxRate="0.16" TaxAmt="32.03"/>
</Items>
<Total TaxableAmt="694.60" TaxAmt="111.13"/>
</Output>