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

如何编写XSLT实现Account_Number去重分组并关联Payment输出?

问题描述

需要编写XSLT将指定XML按Account_Number分组,相同账号仅输出一次账号标题,下方列出该账号关联的所有支付记录,转换为目标文本格式。

输入XML

<Data>
    <Payment>
        <PayeeName>Jim</PayeeName>
        <CheckNumber>1</CheckNumber>
        <Account_group>
            <Account_Number>123456789</Account_Number>
        </Account_group>
    </Payment>
    <Payment>
        <PayeeName>Alex</PayeeName>
        <CheckNumber>2</CheckNumber>
        <Account_group>
            <Account_Number>123456789</Account_Number>
        </Account_group>
    </Payment>
    <Payment>
        <PayeeName>Zach</PayeeName>
        <CheckNumber>3</CheckNumber>
        <Account_group>
            <Account_Number>555566666</Account_Number>
        </Account_group>
    </Payment>
</Data>

期望输出

Account 123456789
CheckNumber 1 Jim
CheckNumber 2 Alex

Account 555566666
CheckNumber 3 Zach

现有代码问题

你当前的XSLT逻辑存在以下问题:

  • 在Data模板中循环每个Payment,导致每条支付记录都会单独调用账号标题和明细模板,重复输出账号标题
  • AccountHeader模板仅对单个Account_group分组,无法实现全局按账号聚合的效果
  • DetailRecord模板中尝试循环Payment,但当前上下文是单个Payment节点,无法获取同账号的所有关联支付记录

正确实现方案

使用XSLT 2.0+的xsl:for-each-group对所有Payment节点按Account_group/Account_Number分组,即可实现相同账号只输出一次标题,再遍历分组内的支付记录输出明细:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 定义换行变量,适配不同系统换行符 -->
    <xsl:variable name="linefeed" select="'&#10;'"/>

    <xsl:template match="/Data">
        <!-- 按Account_Number对Payment节点全局分组 -->
        <xsl:for-each-group select="Payment" group-by="Account_group/Account_Number">
            <!-- 输出账号标题 -->
            <text>Account </text>
            <xsl:value-of select="current-grouping-key()"/>
            <xsl:value-of select="$linefeed"/>
            
            <!-- 遍历当前分组内的所有Payment,输出明细 -->
            <xsl:for-each select="current-group()">
                <text>CheckNumber </text>
                <xsl:value-of select="CheckNumber"/>
                <text> </text>
                <xsl:value-of select="PayeeName"/>
                <xsl:value-of select="$linefeed"/>
            </xsl:for-each>
            
            <!-- 账号之间添加空行,避免末尾出现多余空行 -->
            <xsl:if test="position() != last()">
                <xsl:value-of select="$linefeed"/>
            </xsl:if>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

代码说明

  • xsl:for-each-group select="Payment" group-by="Account_group/Account_Number":对所有Payment节点按账号值分组,相同账号的支付记录会被归为同一组
  • current-grouping-key():获取当前分组的账号值,用于输出账号标题
  • current-group():获取当前分组内的所有Payment节点,遍历输出每条记录的支票号和收款人名称
  • 通过position() != last()控制仅在账号分组之间添加空行,避免最终输出末尾出现多余空行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:35:36