运行 XSLT 中计算和舍入变量的总数
Running Total of Calculated And Rounded Variable in XSLT
我试图在我的 XSLT 1.0 样式表中保留 运行 计算值的总和(我收入的 10%,四舍五入到最接近的 10 美分),但四舍五入的错误使我不准确结果。我知道我现在的代码是错误的,但我不知道如何更正它。
我试过用这个求和:
<xsl:value-of select="format-number(ceiling(sum(./bsk:Date/@income) div 10), '$#.00')" />
这引入了我提到的舍入误差。
我试过使用这些求和:
<xsl:value-of select="format-number(sum(ceiling(./bsk:Date/@income div 10)), '$#.00')" />
<xsl:value-of select="format-number(sum(ceiling(./bsk:Date/@income div 10)), '$#.00')" /></td>
我收到错误:"Error during XSLT transformation: An XPath expression was expected to return a NodeSet."
下面是我正在使用的代码。
<!-- The XML: -->
<Month name="June">
<Date num="28" day="Friday">
<Expense amount="62.50" for="Business License" />
</Date>
<Date num="29" day="Saturday" income="61.30" tithe="paid" />
<Date num="30" day="Sunday" income="108.45" />
</Month>
<!-- The XSLT -->
<xsl:for-each select="./bsk:Month"><table>
<tbody>
<xsl:for-each select="./bsk:Date">
<xsl:variable name="income"><xsl:choose>
<xsl:when test="@income"><xsl:value-of select="@income" /></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose></xsl:variable>
<xsl:variable name="tithe" select="ceiling($income) div 10" />
<xsl:variable name="expenses"><xsl:choose>
<xsl:when test="./bsk:Expense"><xsl:value-of select="sum(./bsk:Expense/@amount)" /></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose></xsl:variable>
<xsl:variable name="rowspan"><xsl:choose>
<xsl:when test="count(./bsk:Expense) > 1"><xsl:value-of select="count(./bsk:Expense)" /></xsl:when>
<xsl:otherwise><xsl:value-of select="1" /></xsl:otherwise>
</xsl:choose></xsl:variable>
<tr>
<td>
<xsl:attribute name="rowspan"><xsl:value-of select="$rowspan" /></xsl:attribute>
<xsl:choose>
<xsl:when test="@income">
<xsl:text>$</xsl:text>
<xsl:value-of select="$income" />
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="class">null</xsl:attribute>
<xsl:text> - </xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:attribute name="rowspan"><xsl:value-of select="$rowspan" /></xsl:attribute>
<xsl:choose>
<xsl:when test="@income">
<xsl:if test="@tithe='paid'"><xsl:attribute name="class">tithe_paid</xsl:attribute></xsl:if>
<xsl:value-of select="format-number($tithe, '$#.00')" />
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="class">null</xsl:attribute>
<xsl:text> - </xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<xsl:choose>
<xsl:when test="./bsk:Expense">
<td><xsl:value-of select="./bsk:Expense/@for" /></td>
<td><xsl:value-of select="format-number(./bsk:Expense[1]/@amount, '$#.00')" /></td>
</xsl:when>
<xsl:otherwise><td colspan="2" class="null"> - </td></xsl:otherwise>
</xsl:choose>
<td>
<xsl:attribute name="rowspan"><xsl:value-of select="$rowspan" /></xsl:attribute>
<xsl:if test="($income - $expenses) < 0"><xsl:attribute name="class">hole</xsl:attribute></xsl:if>
<xsl:value-of select="format-number($income - $expenses - $tithe, '$#.00')" />
</td>
</tr>
<xsl:for-each select="./bsk:Expense[position() > 1]">
<tr>
<td><xsl:value-of select="@for" /></td>
<td><xsl:value-of select="format-number(@amount, '$#.00')" /></td>
</tr>
</xsl:for-each>
</xsl:for-each>
</tbody>
<tfoot><tr>
<th>Totals</th>
<td headers="Income"><xsl:value-of select="format-number(sum(./bsk:Date/@income), '$#.00')" /></td>
<td headers="Tithe"><xsl:value-of select="format-number(ceiling(sum(./bsk:Date/@income) div 10), '$#.00')" /></td>
<td colspan="2" headers="Exp_Amount"><xsl:value-of select="format-number(sum(./bsk:Date/bsk:Expense/@amount), '$#.00')" /></td>
<td headers="Exp_Net">
<xsl:if test="(sum(./bsk:Date/@income) - sum(./bsk:Date/bsk:Expense/@amount)) < 0"><xsl:attribute name="class">hole</xsl:attribute></xsl:if>
<xsl:value-of select="format-number(sum(./bsk:Date/@income) - sum(./bsk:Date/bsk:Expense/@amount), '$#.00')" />
</td>
</tr></tfoot>
</table></xsl:for-each>
六月份的什一奉献是 6.20 美元和 10.90 美元,加起来应该是 17.10 美元。但是因为我那个月的总收入是 169.75,所以四舍五入到只有 17.00 美元。因此,我的净价本应为 90.15 美元,但显示为 90.25 美元,太高了 10 美分。
考虑以下简化示例:
XML
<input>
<entry date="2019-07-01" amount="61.30"/>
<entry date="2019-07-02" amount="108.45"/>
</input>
XSLT 1.0 (+ EXSLT node-set())
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- first pass -->
<xsl:template match="/input" >
<!-- first pass -->
<xsl:variable name="pre-process-entries">
<xsl:for-each select="entry">
<entry date="{@date}" amount="{@amount}" tithe="{ceiling(@amount) div 10}"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="entries" select="exsl:node-set($pre-process-entries)/entry"/>
<!-- output -->
<table border="1">
<tr>
<th>Date</th>
<th>Amount</th>
<th>Tithe</th>
</tr>
<xsl:for-each select="$entries">
<tr>
<td>
<xsl:value-of select="@date"/>
</td>
<td>
<xsl:value-of select="format-number(@amount, '$#.00')"/>
</td>
<td>
<xsl:value-of select="format-number(@tithe, '$#.00')"/>
</td>
</tr>
</xsl:for-each>
<tr>
<th>TOTAL</th>
<th>
<xsl:value-of select="format-number(sum($entries/@amount), '$#.00')"/>
</th>
<th>
<xsl:value-of select="format-number(sum($entries/@tithe), '$#.00')"/>
</th>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="utf-8"?>
<table border="1">
<tr>
<th>Date</th>
<th>Amount</th>
<th>Tithe</th>
</tr>
<tr>
<td>2019-07-01</td>
<td>.30</td>
<td>.20</td>
</tr>
<tr>
<td>2019-07-02</td>
<td>8.45</td>
<td>.90</td>
</tr>
<tr>
<th>TOTAL</th>
<th>9.75</th>
<th>.10</th>
</tr>
</table>
已渲染
我试图在我的 XSLT 1.0 样式表中保留 运行 计算值的总和(我收入的 10%,四舍五入到最接近的 10 美分),但四舍五入的错误使我不准确结果。我知道我现在的代码是错误的,但我不知道如何更正它。
我试过用这个求和:
<xsl:value-of select="format-number(ceiling(sum(./bsk:Date/@income) div 10), '$#.00')" />
这引入了我提到的舍入误差。
我试过使用这些求和:
<xsl:value-of select="format-number(sum(ceiling(./bsk:Date/@income div 10)), '$#.00')" />
<xsl:value-of select="format-number(sum(ceiling(./bsk:Date/@income div 10)), '$#.00')" /></td>
我收到错误:"Error during XSLT transformation: An XPath expression was expected to return a NodeSet."
下面是我正在使用的代码。
<!-- The XML: -->
<Month name="June">
<Date num="28" day="Friday">
<Expense amount="62.50" for="Business License" />
</Date>
<Date num="29" day="Saturday" income="61.30" tithe="paid" />
<Date num="30" day="Sunday" income="108.45" />
</Month>
<!-- The XSLT -->
<xsl:for-each select="./bsk:Month"><table>
<tbody>
<xsl:for-each select="./bsk:Date">
<xsl:variable name="income"><xsl:choose>
<xsl:when test="@income"><xsl:value-of select="@income" /></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose></xsl:variable>
<xsl:variable name="tithe" select="ceiling($income) div 10" />
<xsl:variable name="expenses"><xsl:choose>
<xsl:when test="./bsk:Expense"><xsl:value-of select="sum(./bsk:Expense/@amount)" /></xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose></xsl:variable>
<xsl:variable name="rowspan"><xsl:choose>
<xsl:when test="count(./bsk:Expense) > 1"><xsl:value-of select="count(./bsk:Expense)" /></xsl:when>
<xsl:otherwise><xsl:value-of select="1" /></xsl:otherwise>
</xsl:choose></xsl:variable>
<tr>
<td>
<xsl:attribute name="rowspan"><xsl:value-of select="$rowspan" /></xsl:attribute>
<xsl:choose>
<xsl:when test="@income">
<xsl:text>$</xsl:text>
<xsl:value-of select="$income" />
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="class">null</xsl:attribute>
<xsl:text> - </xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:attribute name="rowspan"><xsl:value-of select="$rowspan" /></xsl:attribute>
<xsl:choose>
<xsl:when test="@income">
<xsl:if test="@tithe='paid'"><xsl:attribute name="class">tithe_paid</xsl:attribute></xsl:if>
<xsl:value-of select="format-number($tithe, '$#.00')" />
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="class">null</xsl:attribute>
<xsl:text> - </xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<xsl:choose>
<xsl:when test="./bsk:Expense">
<td><xsl:value-of select="./bsk:Expense/@for" /></td>
<td><xsl:value-of select="format-number(./bsk:Expense[1]/@amount, '$#.00')" /></td>
</xsl:when>
<xsl:otherwise><td colspan="2" class="null"> - </td></xsl:otherwise>
</xsl:choose>
<td>
<xsl:attribute name="rowspan"><xsl:value-of select="$rowspan" /></xsl:attribute>
<xsl:if test="($income - $expenses) < 0"><xsl:attribute name="class">hole</xsl:attribute></xsl:if>
<xsl:value-of select="format-number($income - $expenses - $tithe, '$#.00')" />
</td>
</tr>
<xsl:for-each select="./bsk:Expense[position() > 1]">
<tr>
<td><xsl:value-of select="@for" /></td>
<td><xsl:value-of select="format-number(@amount, '$#.00')" /></td>
</tr>
</xsl:for-each>
</xsl:for-each>
</tbody>
<tfoot><tr>
<th>Totals</th>
<td headers="Income"><xsl:value-of select="format-number(sum(./bsk:Date/@income), '$#.00')" /></td>
<td headers="Tithe"><xsl:value-of select="format-number(ceiling(sum(./bsk:Date/@income) div 10), '$#.00')" /></td>
<td colspan="2" headers="Exp_Amount"><xsl:value-of select="format-number(sum(./bsk:Date/bsk:Expense/@amount), '$#.00')" /></td>
<td headers="Exp_Net">
<xsl:if test="(sum(./bsk:Date/@income) - sum(./bsk:Date/bsk:Expense/@amount)) < 0"><xsl:attribute name="class">hole</xsl:attribute></xsl:if>
<xsl:value-of select="format-number(sum(./bsk:Date/@income) - sum(./bsk:Date/bsk:Expense/@amount), '$#.00')" />
</td>
</tr></tfoot>
</table></xsl:for-each>
六月份的什一奉献是 6.20 美元和 10.90 美元,加起来应该是 17.10 美元。但是因为我那个月的总收入是 169.75,所以四舍五入到只有 17.00 美元。因此,我的净价本应为 90.15 美元,但显示为 90.25 美元,太高了 10 美分。
考虑以下简化示例:
XML
<input>
<entry date="2019-07-01" amount="61.30"/>
<entry date="2019-07-02" amount="108.45"/>
</input>
XSLT 1.0 (+ EXSLT node-set())
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- first pass -->
<xsl:template match="/input" >
<!-- first pass -->
<xsl:variable name="pre-process-entries">
<xsl:for-each select="entry">
<entry date="{@date}" amount="{@amount}" tithe="{ceiling(@amount) div 10}"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="entries" select="exsl:node-set($pre-process-entries)/entry"/>
<!-- output -->
<table border="1">
<tr>
<th>Date</th>
<th>Amount</th>
<th>Tithe</th>
</tr>
<xsl:for-each select="$entries">
<tr>
<td>
<xsl:value-of select="@date"/>
</td>
<td>
<xsl:value-of select="format-number(@amount, '$#.00')"/>
</td>
<td>
<xsl:value-of select="format-number(@tithe, '$#.00')"/>
</td>
</tr>
</xsl:for-each>
<tr>
<th>TOTAL</th>
<th>
<xsl:value-of select="format-number(sum($entries/@amount), '$#.00')"/>
</th>
<th>
<xsl:value-of select="format-number(sum($entries/@tithe), '$#.00')"/>
</th>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="utf-8"?>
<table border="1">
<tr>
<th>Date</th>
<th>Amount</th>
<th>Tithe</th>
</tr>
<tr>
<td>2019-07-01</td>
<td>.30</td>
<td>.20</td>
</tr>
<tr>
<td>2019-07-02</td>
<td>8.45</td>
<td>.90</td>
</tr>
<tr>
<th>TOTAL</th>
<th>9.75</th>
<th>.10</th>
</tr>
</table>
已渲染