You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求协助实现XSLT 1.0中总金额与子金额的冲抵逻辑

XSLT 1.0 金额冲抵逻辑实现

需要实现XSLT 1.0中的金额冲抵逻辑:利用<header>节点的TotalAmount值,依次冲抵<List>下每个<info>节点的childAmount1、childAmount2,当TotalAmount变为0时立即终止后续处理,未被处理的节点金额保持原值。

具体冲抵规则

规则1(处理childAmount1)

if (childAmount1>0 and TotalAmount>0)
{
    if TotalAmount>=childAmount1
    {
        TotalAmount=TotalAmount-childAmount1
        childAmount1=0
    }
    else
    {
        childAmount1=childAmount1 - TotalAmount
        TotalAmount=0
        exit the loop
    }
}
else exit loop

规则2(处理childAmount2)

if (childAmount2>0 and TotalAmount>0)
{
    if TotalAmount>=childAmount2
    {
        TotalAmount=TotalAmount - childAmount2
        childAmount2=0
    }
    else
    {
        childAmount2=childAmount2 - TotalAmount
        TotalAmount=0
        exit the loop
    }
}
else exit loop

输入示例

<header>
<TotalAmount>60</TotalAmount>
<List>
<info>
<serialNo>1</serialNo>
<childAmount1>20</childAmount1>
<childAmount2>10</childAmount2>
</info>
<info>
<serialNo>2</serialNo>
<childAmount1>20</childAmount1>
<childAmount2>10</childAmount2>
</info>
<info>
<serialNo>3</serialNo>
<childAmount1>20</childAmount1>
<childAmount2>10</childAmount2>
</info>
</List>
</header>

输出示例

<header>
<TotalAmount>60</TotalAmount>
<List>
<info>
<serialNo>1</serialNo>
<childAmount1>0</childAmount1>
<childAmount2>0</childAmount2>
</info>
<info>
<serialNo>2</serialNo>
<childAmount1>0</childAmount1>
<childAmount2>0</childAmount2>
</info>
<info>
<serialNo>3</serialNo>
<childAmount1>20</childAmount1>
<childAmount2>10</childAmount2>
</info>
</List>
</header>

实现代码

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

    <!-- 匹配根节点,初始化剩余金额 -->
    <xsl:template match="/header">
        <header>
            <xsl:copy-of select="TotalAmount"/>
            <List>
                <xsl:call-template name="process-info">
                    <xsl:with-param name="remaining-amount" select="number(TotalAmount)"/>
                    <xsl:with-param name="info-nodes" select="List/info"/>
                </xsl:call-template>
            </List>
        </header>
    </xsl:template>

    <!-- 递归处理info节点的模板 -->
    <xsl:template name="process-info">
        <xsl:param name="remaining-amount"/>
        <xsl:param name="info-nodes"/>

        <xsl:if test="$info-nodes and $remaining-amount > 0">
            <xsl:variable name="current-info" select="$info-nodes[1]"/>
            <xsl:variable name="ca1" select="number($current-info/childAmount1)"/>
            <xsl:variable name="ca2" select="number($current-info/childAmount2)"/>

            <!-- 处理childAmount1 -->
            <xsl:variable name="after-ca1-amount">
                <xsl:choose>
                    <xsl:when test="$ca1 > 0 and $remaining-amount > 0">
                        <xsl:choose>
                            <xsl:when test="$remaining-amount >= $ca1">
                                <xsl:value-of select="$remaining-amount - $ca1"/>
                            </xsl:when>
                            <xsl:otherwise>0</xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise><xsl:value-of select="$remaining-amount"/></xsl:otherwise>
                </xsl:choose>
            </xsl:variable>

            <xsl:variable name="new-ca1">
                <xsl:choose>
                    <xsl:when test="$ca1 > 0 and $remaining-amount > 0">
                        <xsl:choose>
                            <xsl:when test="$remaining-amount >= $ca1">0</xsl:when>
                            <xsl:otherwise><xsl:value-of select="$ca1 - $remaining-amount"/></xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise><xsl:value-of select="$ca1"/></xsl:otherwise>
                </xsl:choose>
            </xsl:variable>

            <!-- 处理childAmount2,仅当处理完ca1后剩余金额仍大于0时 -->
            <xsl:variable name="after-ca2-amount">
                <xsl:choose>
                    <xsl:when test="$after-ca1-amount > 0 and $ca2 > 0">
                        <xsl:choose>
                            <xsl:when test="$after-ca1-amount >= $ca2">
                                <xsl:value-of select="$after-ca1-amount - $ca2"/>
                            </xsl:when>
                            <xsl:otherwise>0</xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise><xsl:value-of select="$after-ca1-amount"/></xsl:otherwise>
                </xsl:choose>
            </xsl:variable>

            <xsl:variable name="new-ca2">
                <xsl:choose>
                    <xsl:when test="$after-ca1-amount > 0 and $ca2 > 0">
                        <xsl:choose>
                            <xsl:when test="$after-ca1-amount >= $ca2">0</xsl:when>
                            <xsl:otherwise><xsl:value-of select="$ca2 - $after-ca1-amount"/></xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise><xsl:value-of select="$ca2"/></xsl:otherwise>
                </xsl:choose>
            </xsl:variable>

            <!-- 输出当前处理后的info节点 -->
            <info>
                <xsl:copy-of select="$current-info/serialNo"/>
                <childAmount1><xsl:value-of select="$new-ca1"/></childAmount1>
                <childAmount2><xsl:value-of select="$new-ca2"/></childAmount2>
            </info>

            <!-- 递归处理下一个info节点,传递剩余金额 -->
            <xsl:call-template name="process-info">
                <xsl:with-param name="remaining-amount" select="$after-ca2-amount"/>
                <xsl:with-param name="info-nodes" select="$info-nodes[position() > 1]"/>
            </xsl:call-template>
        </xsl:if>

        <!-- 输出未处理的info节点(当剩余金额为0时) -->
        <xsl:if test="$info-nodes and $remaining-amount <= 0">
            <xsl:copy-of select="$info-nodes"/>
        </xsl:if>
    </xsl:template>

    <!-- 复制其他未匹配的节点(如果有) -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. 递归模板核心:通过process-info递归模板传递剩余金额remaining-amount,逐个处理<info>节点,直到金额耗尽或节点处理完毕。
  2. 金额计算逻辑:严格按照规则先处理childAmount1,再处理childAmount2,分别计算处理后的金额和剩余金额。
  3. 终止条件:当剩余金额remaining-amount≤0时,直接复制剩余未处理的<info>节点,不再进行冲抵计算。
  4. 节点复制:使用<xsl:copy-of>保留无需修改的节点(如serialNo),确保输出结构与输入一致。

内容的提问来源于stack exchange,提问作者sum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:01:05