首页 > 解决方案 > 使用计算出的 xsl:variables 运行 Total?

问题描述

我的会计 XML 包含两个单独的元素,一个仅用于正数,另一个用于负货币值。我想使用 XSL 为传入和传出的传输创建一个 HTML 表,加上每一行的运行总计。sum(preceding-sibling::Buchungszeile/Betrag) + Betrag)如果所有元素都包含数字,我发现which 工作正常。不幸的是,对于正值,负元素不是 0,而是空的,反之亦然。

<Buchungszeile>
  <Buchungstag>2019-12-05</Buchungstag>
  <Soll-Betrag>100</Soll-Betrag>
  <Haben-Betrag></Haben-Betrag>
</Buchungszeile>
<Buchungszeile>
  <Buchungstag>2019-12-06</Buchungstag>
  <Soll-Betrag></Soll-Betrag>
  <Haben-Betrag>155</Haben-Betrag>
</Buchungszeile>
<Buchungszeile>
  <Buchungstag>2019-12-07</Buchungstag>
  <Soll-Betrag>50</Soll-Betrag>
  <Haben-Betrag></Haben-Betrag>
</Buchungszeile>

问题 1:在 xsl:variable 的帮助下,$betrag我能够在一个 HTML 列中显示所有货币值,负值带有前导“-”。但是我没有找到一种方法来访问 Running Totalsum()函数的这个变量。

问题 2:我没有找到一种方法来生成一个新的 XML 元素,例如<Betrag>包含所有用于sum(preceding-sibling::Buchungszeile/Betrag) + Betrag)

问题 3:我找不到使用position().

这将是达到此结果的正确方法:

<table>
 <tr> <td>Buchungstag</td> <td>Betrag</td> <td>Running Total</td> </tr>
 <tr> <td> 2019-12-05</td> <td>  -100</td> <td>         -100</td> </tr>
 <tr> <td> 2019-12-06</td> <td>   155</td> <td>           55</td> </tr>
 <tr> <td> 2019-12-07</td> <td>   -50</td> <td>            5</td> </tr>
</table>

标签: xmlvariablesxslt

解决方案


我会建议一种完全不同的方法,它不仅可以处理空节点,还可以避免对以前的兄弟值进行昂贵的重复求和:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/*">
    <table>
        <tr> 
            <th>Buchungstag</th>
            <th>Betrag</th>
            <th>Running Total</th>
        </tr>
            <xsl:call-template name="generate-rows">
                <xsl:with-param name="nodes" select="Buchungszeile"/>
            </xsl:call-template>
    </table>
</xsl:template>

<xsl:template name="generate-rows">
    <xsl:param name="nodes"/>
    <xsl:param name="prev-balance" select="0"/>
    <xsl:if test="count($nodes)">
        <xsl:variable name="node" select="$nodes[1]"/>
        <xsl:variable name="amount" select="concat('0', $node/Haben-Betrag) - concat('0', $node/Soll-Betrag)"/>
        <xsl:variable name="balance" select="$prev-balance + $amount"/>
        <tr> 
            <td>
                <xsl:value-of select="$node/Buchungstag"/>
            </td>
            <td>
                <xsl:value-of select="$amount"/>
            </td>
            <td>
                <xsl:value-of select="$balance"/>
            </td>
        </tr>
        <!-- recursive call -->
        <xsl:call-template name="generate-rows">
            <xsl:with-param name="nodes" select="$nodes[position() > 1]"/>
            <xsl:with-param name="prev-balance" select="$balance"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

推荐阅读