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

基于子节点Category/ID去重Total节点并合计指定字段的XSLT实现问题

需求说明

以//Category/ID作为唯一值,对其父节点Total进行去重,删除重复的Total节点,将被删除节点的TotalAmount、Tax字段值累加至保留的对应同ID节点中。例如示例中Category/ID为"S"的两个Total节点需合并,TotalAmount合计为250.00、Tax合计为40.00。原有编写的XSLT无法正常实现该功能。

输入示例

<root>
    <Total>
      <TotalAmount currencyID="EUR">100.00</TotalAmount>
      <Tax currencyID="EUR">20.00</Tax>
      <Category>
        <ID>S</ID>
        <Percent>21.000</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
    <Total>
      <TotalAmount currencyID="EUR">150.00</TotalAmount>
      <Tax currencyID="EUR">20.00</Tax>
      <Category>
        <ID>S</ID>
        <Percent>21.000</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
    <Total>
      <TotalAmount currencyID="EUR">200.00</TotalAmount>
      <Tax currencyID="EUR">0</Tax>
      <Category>
        <ID>O</ID>
        <Percent>0</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
</root>

原有问题XSLT代码

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kByP" match="Category" use="ID"/>

 <xsl:template match="node()|@*">
  <xsl:param name="pNewValue"/>
     <xsl:copy>
       <xsl:apply-templates select="node()|@*">
         <xsl:with-param name="pNewValue" select="$pNewValue"/>
       </xsl:apply-templates>
     </xsl:copy>
 </xsl:template>

 <xsl:template match=
   "Category[generate-id()
           =
            generate-id(key('kByP', ID)[1])
           ]">
  <xsl:copy>
      <xsl:apply-templates select="node()|@*">
         <xsl:with-param name="pNewValue" select=
         "sum(key('kByP', ID)/TotalAmount)"/>
      </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="Total"/>

 <xsl:template match="TotalAmount/text()">
  <xsl:param name="pNewValue"/>
  <xsl:value-of select="$pNewValue"/>
 </xsl:template>
</xsl:stylesheet>

期望输出

<root>
    <Total>
      <TotalAmount currencyID="EUR">250.00</TotalAmount>
      <Tax currencyID="EUR">40.00</Tax>
      <Category>
        <ID>S</ID>
        <Percent>21.000</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
    <Total>
      <TotalAmount currencyID="EUR">200.00</TotalAmount>
      <Tax currencyID="EUR">0</Tax>
      <Category>
        <ID>O</ID>
        <Percent>0</Percent>
        <Description>
          <ID>Note</ID>
        </Description>
      </Category>
    </Total>
</root>

修复方案

原有代码的核心问题有三个:

  1. 分组key匹配的是Category节点,但计算金额时错误尝试直接从Category节点下找TotalAmount,实际TotalAmount是Category的兄弟节点,父节点为Total
  2. 直接匹配所有Total节点输出空,导致没有输出Total结构
  3. 只做了TotalAmount的累加逻辑,没有处理Tax字段的累加

以下是修复后的XSLT代码:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <!-- 按Total下的Category/ID对Total节点分组 -->
 <xsl:key name="totalByCatId" match="Total" use="Category/ID"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <!-- 只处理每个分组的第一个Total节点 -->
 <xsl:template match="Total[generate-id() = generate-id(key('totalByCatId', Category/ID)[1])]">
  <xsl:copy>
    <!-- 复制TotalAmount,替换值为同分组所有Total的TotalAmount总和 -->
    <TotalAmount currencyID="{TotalAmount/@currencyID}">
      <xsl:value-of select="sum(key('totalByCatId', Category/ID)/TotalAmount)"/>
    </TotalAmount>
    <!-- 复制Tax,替换值为同分组所有Total的Tax总和 -->
    <Tax currencyID="{Tax/@currencyID}">
      <xsl:value-of select="sum(key('totalByCatId', Category/ID)/Tax)"/>
    </Tax>
    <!-- 原样复制Category节点 -->
    <xsl:apply-templates select="Category"/>
  </xsl:copy>
 </xsl:template>

 <!-- 跳过同分组的其他重复Total节点 -->
 <xsl:template match="Total[generate-id() != generate-id(key('totalByCatId', Category/ID)[1])]"/>

</xsl:stylesheet>

该代码使用Muenchian分组法对Total节点按Category/ID分组,仅保留每个分组的第一个Total节点,将同分组所有节点的TotalAmount和Tax分别累加后写入保留节点,其余结构完全保留,输出结果与预期一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:24:05