基于XSLT 2.0/3.0实现逗号分隔节点去重分组生成XML
XSLT 2.0/3.0 实现按拆分后的Internal Value分组External Value
需求说明
需要将源XML中所有wd:External_Value_Data/wd:Text字段,按每个拆分后的唯一Internal Value(即wd:Internal_Value_Data/wd:Text中逗号分隔的单个值)进行分组,生成结构清晰的目标XML。
源XML示例
<wd:root xmlns:wd="http://your-actual-namespace.com"> <wd:Integration_Map_Value_Data> <wd:Internal_Value_Data> <wd:Text>A1</wd:Text> </wd:Internal_Value_Data> <wd:External_Value_Data> <wd:Text>3402948659753553924</wd:Text> </wd:External_Value_Data> </wd:Integration_Map_Value_Data> <wd:Integration_Map_Value_Data> <wd:Internal_Value_Data> <wd:Text>A1,A2</wd:Text> </wd:Internal_Value_Data> <wd:External_Value_Data> <wd:Text>3402949092169519108</wd:Text> </wd:External_Value_Data> </wd:Integration_Map_Value_Data> <wd:Integration_Map_Value_Data> <wd:Internal_Value_Data> <wd:Text>A1,A2</wd:Text> </wd:Internal_Value_Data> <wd:External_Value_Data> <wd:Text>3402949293873597442</wd:Text> </wd:External_Value_Data> </wd:Integration_Map_Value_Data> <wd:Integration_Map_Value_Data> <wd:Internal_Value_Data> <wd:Text>A1,A2,A3</wd:Text> </wd:Internal_Value_Data> <wd:External_Value_Data> <wd:Text>3402949293873597654977</wd:Text> </wd:External_Value_Data> </wd:Integration_Map_Value_Data> </wd:root>
期望输出XML
<root> <record> <type>A1</type> <document>3402948659753553924</document> <document>3402949092169519108</document> <document>3402949293873597442</document> <document>3402949293873597654977</document> </record> <record> <type>A2</type> <document>3402949092169519108</document> <document>3402949293873597442</document> <document>3402949293873597654977</document> </record> <record> <type>A3</type> <document>3402949293873597654977</document> </record> </root>
XSLT 3.0 解决方案
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="http://your-actual-namespace.com" exclude-result-prefixes="wd"> <xsl:output method="xml" indent="yes"/> <!-- 生成所有(type, document)的关联项 --> <xsl:variable name="type-document-pairs"> <xsl:for-each select="//wd:Integration_Map_Value_Data"> <xsl:variable name="current-doc" select="wd:External_Value_Data/wd:Text"/> <xsl:for-each select="tokenize(wd:Internal_Value_Data/wd:Text, ',')"> <pair> <type><xsl:value-of select="normalize-space(.)"/></type> <document><xsl:value-of select="$current-doc"/></document> </pair> </xsl:for-each> </xsl:for-each> </xsl:variable> <!-- 主模板 --> <xsl:template match="/"> <root> <!-- 按type分组 --> <xsl:for-each-group select="$type-document-pairs/pair" group-by="type"> <record> <type><xsl:value-of select="current-grouping-key()"/></type> <!-- 输出当前组内所有document --> <xsl:copy-of select="current-group()/document"/> </record> </xsl:for-each-group> </root> </xsl:template> </xsl:stylesheet>
XSLT 2.0 兼容写法
如果使用XSLT 2.0,仅需将代码中的version="3.0"改为version="2.0",其余代码完全兼容。
关键说明
- 命名空间处理:务必将代码中的
http://your-actual-namespace.com替换为源XML中wd前缀对应的实际命名空间,否则无法正确匹配节点。 - 拆分逻辑:使用
tokenize()函数将逗号分隔的Internal Value拆分为单个type值,normalize-space()用于处理可能存在的空格(如果源数据有空格的话)。 - 分组逻辑:通过
xsl:for-each-group按type分组,current-grouping-key()获取当前组的type值,current-group()获取组内所有关联的document节点。
内容的提问来源于stack exchange,提问作者TurboLag06
相关产品推荐
相关产品推荐

