XSLT 2.0多元素分组问题:按CC_code与Customer_ID分组失效
按Customer_ID和CC_code对XML数据分组并去重
我需要对给定的XML数据按Customer_ID和CC_code的组合进行分组,但当前逻辑仅按CC_code分组,无法区分不同的Customer_ID。
示例XML数据
<?xml version='1.0' encoding='UTF-8'?> <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <wd:Report_Data xmlns:wd="fin_file"> <wd:Report_Entry> <wd:Customers> <wd:Customer_ID>144122</wd:Customer_ID> </wd:Customers> <wd:Invoice_Lines> <wd:Cost_Center wd:Descriptor="Appraisal Mgmt"> </wd:Cost_Center> <wd:CC_code>22110</wd:CC_code> <wd:Company_code>AT-12</wd:Company_code> <wd:Currency>GBP</wd:Currency> </wd:Invoice_Lines> <wd:Invoice_Lines> <wd:Cost_Center wd:Descriptor="Tax Other Cost Ctr"> </wd:Cost_Center> <wd:CC_code>52600</wd:CC_code> <wd:Company_code>AT-12</wd:Company_code> <wd:Currency>GBP</wd:Currency> </wd:Invoice_Lines> <wd:Invoice_Lines> <wd:Cost_Center wd:Descriptor="Appraisal"> </wd:Cost_Center> <wd:CC_code>22110</wd:CC_code> <wd:Company_code>AT-12</wd:Company_code> <wd:Currency>GBP</wd:Currency> </wd:Invoice_Lines> </wd:Report_Entry> <wd:Report_Entry> <wd:Customers> <wd:Customer_ID>144133</wd:Customer_ID> </wd:Customers> <wd:Invoice_Lines> <wd:Cost_Center wd:Descriptor="Appraisal Mgmt"> </wd:Cost_Center> <wd:CC_code>22110</wd:CC_code> <wd:Company_code>AT-12</wd:Company_code> <wd:Currency>GBP</wd:Currency> </wd:Invoice_Lines> <wd:Invoice_Lines> <wd:Cost_Center wd:Descriptor="Appraisal Mgmt"> </wd:Cost_Center> <wd:CC_code>22110</wd:CC_code> <wd:Company_code>AT-12</wd:Company_code> <wd:Currency>GBP</wd:Currency> </wd:Invoice_Lines> </wd:Report_Entry> </wd:Report_Data> </env:Body> </env:Envelope>
期望输出格式
144122/22110|Appraisal Mgmt|AT-12|GBP 144122/52600|Tax Other Cost Ctr|AT-12|GBP 144133/22110|Appraisal Mgmt|AT-12|GBP
解决方案(XSLT实现)
使用XSLT 2.0的分组功能,按Customer_ID和CC_code的组合作为分组键,实现分组去重:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="fin_file" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <xsl:output method="text" encoding="UTF-8"/> <xsl:template match="/"> <!-- 遍历每个客户条目 --> <xsl:for-each select="env:Envelope/env:Body/wd:Report_Data/wd:Report_Entry"> <xsl:variable name="currentCustomer" select="wd:Customers/wd:Customer_ID"/> <!-- 按CC_code分组当前客户下的发票行 --> <xsl:for-each-group select="wd:Invoice_Lines" group-by="wd:CC_code"> <!-- 取分组内第一条数据的字段值 --> <xsl:value-of select="concat($currentCustomer, '/', current-grouping-key(), '|', wd:Cost_Center/@wd:Descriptor, '|', wd:Company_code, '|', wd:Currency)"/> <xsl:text> </xsl:text> </xsl:for-each-group> </xsl:for-each> </xsl:template> </xsl:stylesheet>
逻辑说明
- 遍历每个
wd:Report_Entry(对应单个客户的所有发票数据),保存当前客户的Customer_ID; - 对当前客户下的所有
wd:Invoice_Lines按CC_code分组; - 每个分组仅输出一条结果,拼接
Customer_ID/CC_code作为唯一标识,同时提取对应的成本中心描述、公司代码和货币信息; - 最终输出符合要求的文本格式,每条结果占一行。
内容的提问来源于stack exchange,提问作者Harshit Singh
相关产品推荐
相关产品推荐

