如何在XSLT 1.0中按多元素分组并完成指定数据转换?
用XSLT 1.0实现多字段分组数据转换
由于OIC服务器不支持XSLT 2.0的current-group()方法,需基于XSLT 1.0完成以下XML数据转换:
- 分组规则:按源XML中的
date、customer_code、item三个字段对<record>节点分组 - 目标字段规则:
amount:分组内所有<amount>节点值的总和qty:取分组内linetype='LINE'的<record>节点的<qty>值unitprice:由分组总amount除以对应qty计算得到
源XML
<ReadResponse> <recset> <record> <date>date1</date> <customer_code>cc</customer_code> <item>it1</item> <uom></uom> <qty>5</qty> <amount>15</amount> <linetype>LINE</linetype> </record> <record> <date>date1</date> <customer_code>cc</customer_code> <item>it1</item> <uom></uom> <qty>10</qty> <amount>25</amount> <linetype>TAX</linetype> </record> <record> <date>date2</date> <customer_code>cc</customer_code> <item>it2</item> <uom></uom> <qty>70</qty> <amount>700</amount> <linetype>LINE</linetype> </record> </recset> </ReadResponse>
目标XML示例
<?xml version = '1.0' encoding = 'UTF-8'?> <targset> <targrec> <date>date1</date> <custcode>cc</custcode> <item>it1</item> <amount>40</amount> <qty>5</qty> <unitprice>8</unitprice> </targrec> <targrec> <date>date2</date> <custcode>cc</custcode> <item>it2</item> <amount>700</amount> <qty>70</qty> <unitprice>10</unitprice> </targrec> </targset>
XSLT 1.0实现代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- 定义Muenchian分组的键,组合三个分组字段 --> <xsl:key name="group-key" match="record" use="concat(date, '|', customer_code, '|', item)"/> <xsl:template match="/ReadResponse"> <targset> <!-- 匹配每个分组的第一个节点,作为分组的代表 --> <xsl:for-each select="recset/record[generate-id() = generate-id(key('group-key', concat(date, '|', customer_code, '|', item))[1])]"> <xsl:variable name="current-group" select="key('group-key', concat(date, '|', customer_code, '|', item))"/> <!-- 获取分组内linetype为LINE的qty值 --> <xsl:variable name="line-qty" select="$current-group[linetype='LINE']/qty"/> <!-- 计算分组总amount --> <xsl:variable name="total-amount" select="sum($current-group/amount)"/> <targrec> <date><xsl:value-of select="date"/></date> <custcode><xsl:value-of select="customer_code"/></custcode> <item><xsl:value-of select="item"/></item> <amount><xsl:value-of select="$total-amount"/></amount> <qty><xsl:value-of select="$line-qty"/></qty> <!-- 计算单价,避免除以0的情况(这里假设每个分组至少有一个LINE类型记录) --> <unitprice><xsl:value-of select="$total-amount div $line-qty"/></unitprice> </targrec> </xsl:for-each> </targset> </xsl:template> </xsl:stylesheet>
代码说明
- Muenchian分组:通过
<xsl:key>定义组合键,将date、customer_code、item用分隔符拼接,确保唯一标识每个分组 - 分组匹配:使用
generate-id()判断当前节点是否为分组的第一个节点,避免重复处理 - 数值计算:
- 用
sum()函数计算分组内所有amount的总和 - 通过过滤
linetype='LINE'的节点获取对应的qty - 用
div运算符计算单价,若需处理qty为0的异常场景,可添加判断逻辑
- 用
内容的提问来源于stack exchange,提问作者Balaganesh Mohanavel
相关产品推荐
相关产品推荐

