Итоговая сумма вычисленной и округленной переменной в XSLT - PullRequest
0 голосов
/ 04 июля 2019

Я пытаюсь сохранить промежуточную сумму вычисленного значения (10% моего дохода, округленного до ближайших 10 центов) в моей таблице стилей XSLT 1.0, но ошибка округления дает мне неточные результаты.Я знаю, что мой текущий код неверен, но я не знаю, как его исправить.

Я пробовал сумму, используя это:

<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>

Я получил ошибку: «Ошибкаво время преобразования XSLT: ожидалось, что выражение XPath вернет 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) &gt; 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) &lt; 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() &gt; 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)) &lt; 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 долл., Что на десять центов выше.

1 Ответ

0 голосов
/ 05 июля 2019

Рассмотрим следующий упрощенный пример:

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>$61.30</td>
    <td>$6.20</td>
  </tr>
  <tr>
    <td>2019-07-02</td>
    <td>$108.45</td>
    <td>$10.90</td>
  </tr>
  <tr>
    <th>TOTAL</th>
    <th>$169.75</th>
    <th>$17.10</th>
  </tr>
</table>

Оказано

enter image description here

...