如何使用XSLT合并XML中同类节点的值
合并XML中重复E2节点的内容(XSLT实现)
需求说明
给定如下源XML:
<Root> <E1 SEGMENT="1"> <Node1>SomeValue</Node1> <Node2>I</Node2> <Node3>IT</Node3> <E2 SEGMENT="1"> <TLINE>Val1</TLINE> <TF>*</TF> </E2> <E2 SEGMENT="1"> <TLINE>Val2</TLINE> <TF>*</TF> </E2> <E2 SEGMENT="1"> <TLINE>Val3</TLINE> <TF>*</TF> </E2> <!-- 可能存在更多E2节点 --> </E1> </Root>
需要转换为以下输出:将所有E2节点合并为单个E2节点,其中TLINE的值用|分隔拼接,TF的值用;分隔拼接成对应数量的*序列:
<Root> <E1 SEGMENT="1"> <Node1>SomeValue</Node1> <Node2>I</Node2> <Node3>IT</Node3> <E2 SEGMENT="1"> <TLINE>Val1 | Val2 | Val3 |...</TLINE> <TF>*;*;*</TF> </E2> </E1> </Root>
XSLT解决方案
以下是实现该需求的XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配E1节点,处理其下的E2子节点 --> <xsl:template match="E1"> <xsl:copy> <xsl:apply-templates select="@*|node()[not(self::E2)]"/> <!-- 生成单个E2节点 --> <E2 SEGMENT="1"> <!-- 合并所有E2/TLINE的值,用|分隔 --> <TLINE> <xsl:for-each select="E2/TLINE"> <xsl:if test="position() > 1"> | </xsl:if> <xsl:value-of select="."/> </xsl:for-each> </TLINE> <!-- 合并所有E2/TF的值,用;分隔 --> <TF> <xsl:for-each select="E2/TF"> <xsl:if test="position() > 1">;</xsl:if> <xsl:value-of select="."/> </xsl:for-each> </TF> </E2> </xsl:copy> </xsl:template> <!-- 移除原有的E2节点,避免被身份模板复制 --> <xsl:template match="E2"/> </xsl:stylesheet>
代码说明
- 身份模板:负责复制除了被特殊模板匹配之外的所有节点和属性,保证原XML中其他内容(如Node1、Node2等)保持不变。
- E1节点模板:在复制E1的属性和非E2子节点后,生成一个新的E2节点。通过
xsl:for-each遍历所有原E2下的TLINE和TF节点,分别用|和;拼接值。 - E2节点模板:匹配原有的E2节点并忽略,避免它们被复制到输出中。
内容的提问来源于stack exchange,提问作者Subbaiah Donepudi
相关产品推荐
相关产品推荐

