XSLT新手求助:按唯一字段分组并聚合Quote节点
XSLT分组聚合实现方案
先明确输入输出示例
假设你的输入XML结构如下:
<Records> <Record> <Fund_Id>123</Fund_Id> <FundData>ABC</FundData> <ValueDate2>2024-01-01</ValueDate2> <Value>100.0</Value> </Record> <Record> <Fund_Id>123</Fund_Id> <FundData>ABC</FundData> <ValueDate2>2024-01-02</ValueDate2> <Value>101.5</Value> </Record> <Record> <Fund_Id>123</Fund_Id> <FundData>ABC</FundData> <ValueDate2>2024-01-03</ValueDate2> <Value>102.2</Value> </Record> </Records>
目标输出XML结构:
<Funds> <Fund> <Fund_Id>123</Fund_Id> <FundData>ABC</FundData> <Quotes> <Quote> <ValueDate2>2024-01-01</ValueDate2> <Value>100.0</Value> </Quote> <Quote> <ValueDate2>2024-01-02</ValueDate2> <Value>101.5</Value> </Quote> <Quote> <ValueDate2>2024-01-03</ValueDate2> <Value>102.2</Value> </Quote> </Quotes> </Fund> </Funds>
方案1:XSLT 2.0及以上(语法简洁,推荐)
用xsl:for-each-group直接按公共字段组合分组:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <Funds> <!-- 按Fund_Id+FundData的组合键分组,多字段用|分隔避免冲突 --> <xsl:for-each-group select="Records/Record" group-by="concat(Fund_Id, '|', FundData)"> <Fund> <!-- 输出公共字段,取分组内第一条记录的值即可 --> <Fund_Id><xsl:value-of select="current-group()[1]/Fund_Id"/></Fund_Id> <FundData><xsl:value-of select="current-group()[1]/FundData"/></FundData> <Quotes> <!-- 遍历分组内所有记录,生成Quote列表 --> <xsl:for-each select="current-group()"> <Quote> <ValueDate2><xsl:value-of select="ValueDate2"/></ValueDate2> <Value><xsl:value-of select="Value"/></Value> </Quote> </xsl:for-each> </Quotes> </Fund> </xsl:for-each-group> </Funds> </xsl:template> </xsl:stylesheet>
方案2:XSLT 1.0(兼容旧环境,Muenchian分组法)
XSLT 1.0没有原生分组语法,需要通过定义键实现:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 定义分组键:基于Fund_Id和FundData的组合 --> <xsl:key name="fundGroup" match="Record" use="concat(Fund_Id, '|', FundData)"/> <xsl:template match="/"> <Funds> <!-- 只处理每个分组的第一条记录,避免重复生成Fund节点 --> <xsl:for-each select="Records/Record[generate-id() = generate-id(key('fundGroup', concat(Fund_Id, '|', FundData))[1])]"> <Fund> <Fund_Id><xsl:value-of select="Fund_Id"/></Fund_Id> <FundData><xsl:value-of select="FundData"/></FundData> <Quotes> <!-- 遍历当前分组下的所有记录 --> <xsl:for-each select="key('fundGroup', concat(Fund_Id, '|', FundData))"> <Quote> <ValueDate2><xsl:value-of select="ValueDate2"/></ValueDate2> <Value><xsl:value-of select="Value"/></Value> </Quote> </xsl:for-each> </Quotes> </Fund> </xsl:for-each> </Funds> </xsl:template> </xsl:stylesheet>
注意事项
- 如果有更多公共字段需要分组,只需在
concat里追加字段,比如concat(Fund_Id, '|', FundData, '|', FundType),确保组合键唯一即可。 - 若输出节点名称或结构有调整,直接修改对应的XML元素标签即可。
内容的提问来源于stack exchange,提问作者TrineG
相关产品推荐
相关产品推荐

