使用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>
修正说明
- 移除了中间变量
groups,直接通过两次<xsl:for-each-group>完成逻辑:- 第一次遍历分组,筛选成员数大于1的分组,每个分组生成一个
<Record>,包含该组所有<Customer>节点 - 第二次遍历分组,筛选成员数等于1的分组,每个分组生成独立
<Record>,仅包含该组唯一的<Customer>节点
- 第一次遍历分组,筛选成员数大于1的分组,每个分组生成一个
- 该逻辑既满足重复值组合并入单个Record的要求,也保证单个值(包括空值)每个都独立生成Record,完全匹配预期输出。
内容的提问来源于stack exchange,提问作者ABC
相关产品推荐
相关产品推荐

