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

使用XSLT筛选非空customer_number公共值并按组生成Record标签

问题修正:按customer_number分组生成独立Record节点

需求说明

基于XML的<customer_number>字段进行分组输出:

  • 非空重复值对应的所有<Customer>节点统一放入一个<Record>
  • 单个非空值、空值的每个<Customer>节点各自单独放入一个<Record>

输入Payload

<?xml version='1.0' encoding='UTF-8'?>
    <CustomerRecord>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>GARY</chargename>
            <customer_number>EP10025</customer_number>
        </Customer>
        <Customer>
            <chargeto>XYZ</chargeto>
            <chargename>DAV</chargename>
            <customer_number></customer_number>
        </Customer>
        <Customer>
            <chargeto>CDE</chargeto>
            <chargename>GARY DAVIS</chargename>
            <customer_number></customer_number>
        </Customer>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>DAV</chargename>
            <customer_number>EP10024</customer_number>
        </Customer>
        <Customer>
            <chargeto>CDE</chargeto>
            <chargename>GARY DAVIS</chargename>
            <customer_number>EP10025</customer_number>
        </Customer>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>DAV</chargename>
            <customer_number>EP10022</customer_number>
        </Customer>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>XYZ</chargename>
            <customer_number>EP10023</customer_number>
        </Customer>
        <Customer>
            <chargeto>CDE</chargeto>
            <chargename>GARY DAVIS</chargename>
            <customer_number>EP10025</customer_number>
        </Customer>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>DAV</chargename>
            <customer_number>EP10023</customer_number>
        </Customer>
    </CustomerRecord>

预期输出

<?xml version="1.0" encoding="UTF-8"?>
<Root>
    <Record>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>GARY</chargename>
            <customer_number>EP10025</customer_number>
        </Customer>
        <Customer>
            <chargeto>CDE</chargeto>
            <chargename>GARY DAVIS</chargename>
            <customer_number>EP10025</customer_number>
        </Customer>
        <Customer>
            <chargeto>CDE</chargeto>
            <chargename>GARY DAVIS</chargename>
            <customer_number>EP10025</customer_number>
        </Customer>
    </Record>
    <Record>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>DAV</chargename>
            <customer_number>EP10023</customer_number>
        </Customer>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>XYZ</chargename>
            <customer_number>EP10023</customer_number>
        </Customer>
    </Record>
    <Record>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>DAV</chargename>
            <customer_number>EP10024</customer_number>
        </Customer>
    </Record>
    <Record>
        <Customer>
            <chargeto>ABC</chargeto>
            <chargename>DAV</chargename>
            <customer_number>EP10022</customer_number>
        </Customer>
    </Record>
    <Record>
        <Customer>
            <chargeto>XYZ</chargeto>
            <chargename>DAV</chargename>
            <customer_number/>
        </Customer>
    </Record>
    <Record>
        <Customer>
            <chargeto>CDE</chargeto>
            <chargename>GARY DAVIS</chargename>
            <customer_number/>
        </Customer>
    </Record>
</Root>

现有XSLT代码问题

当前XSLT将所有单个节点放入同一个<Record>,不符合每个单个节点各占一个<Record>的要求:

<xsl:stylesheet version="2.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="/CustomerRecord">
        <xsl:variable name="groups">
            <xsl:for-each-group select="Customer" group-by="customer_number">
                <group size="{count(current-group())}">
                    <xsl:copy-of select="current-group()"/>
                </group>
            </xsl:for-each-group>
        </xsl:variable>
        <Root>
            <xsl:for-each select="$groups/group[@size > 1]">
                <Record>
                    <xsl:copy-of select="Customer"/>
                </Record>
            </xsl:for-each>
            <Record>
                <xsl:copy-of select="$groups/group[@size = 1]/Customer"/>
            </Record>
        </Root>
    </xsl:template>
    
</xsl:stylesheet>

修正后的XSLT代码

<xsl:stylesheet version="2.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="/CustomerRecord">
        <Root>
            <!-- 处理重复值分组:每个分组生成一个Record -->
            <xsl:for-each-group select="Customer" group-by="customer_number">
                <xsl:if test="count(current-group()) > 1">
                    <Record>
                        <xsl:copy-of select="current-group()"/>
                    </Record>
                </xsl:if>
            </xsl:for-each-group>
            
            <!-- 处理单个值:每个Customer单独生成一个Record -->
            <xsl:for-each-group select="Customer" group-by="customer_number">
                <xsl:if test="count(current-group()) = 1">
                    <Record>
                        <xsl:copy-of select="current-group()"/>
                    </Record>
                </xsl:if>
            </xsl:for-each-group>
        </Root>
    </xsl:template>
    
</xsl:stylesheet>

修正说明

  1. 移除了中间变量groups,直接通过两次<xsl:for-each-group>完成逻辑:
    • 第一次遍历分组,筛选成员数大于1的分组,每个分组生成一个<Record>,包含该组所有<Customer>节点
    • 第二次遍历分组,筛选成员数等于1的分组,每个分组生成独立<Record>,仅包含该组唯一的<Customer>节点
  2. 该逻辑既满足重复值组合并入单个Record的要求,也保证单个值(包括空值)每个都独立生成Record,完全匹配预期输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:24:23