XML节点分组合并需求咨询:K18与TP1节点合并处理
解决方案:XML节点分组合并的XSLT实现
核心处理逻辑
- 对
K18节点按ALF+OND的组合值分组,合并后保留一组的ALF/OND字段,将所有组内的P04Y/P04Z/P04/P03子节点归集到合并后的K18下 - 对每个
P01下的TP1节点按ID+RAS的组合值分组,合并后保留一组的ID/RAS字段,将所有组内的PT2子节点归集到合并后的TP1下
完整XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <!-- 复制根节点结构,触发后续模板处理 --> <xsl:template match="/"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <!-- 通用复制模板:保留未特殊处理的节点和属性 --> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <!-- 处理K18节点的分组合并 --> <xsl:template match="*[K18]"> <xsl:copy> <xsl:apply-templates select="@*"/> <!-- 按ALF和OND的组合值分组 --> <xsl:for-each-group select="K18" group-by="concat(ALF, '|', OND)"> <K18> <!-- 保留分组内第一个K18的ALF、OND字段 --> <xsl:copy-of select="current-group()[1]/ALF | current-group()[1]/OND"/> <!-- 归集所有组内的目标子节点 --> <xsl:copy-of select="current-group()/P04Y | current-group()/P04Z | current-group()/P04 | current-group()/P03"/> <!-- 处理P01下的TP1分组 --> <xsl:apply-templates select="current-group()[1]/P01"/> </K18> </xsl:for-each-group> </xsl:copy> </xsl:template> <!-- 处理P01下TP1节点的分组合并 --> <xsl:template match="P01"> <P01> <xsl:apply-templates select="@*"/> <!-- 按ID和RAS的组合值分组 --> <xsl:for-each-group select="TP1" group-by="concat(ID, '|', RAS)"> <TP1> <!-- 保留分组内第一个TP1的ID、RAS字段 --> <xsl:copy-of select="current-group()[1]/ID | current-group()[1]/RAS"/> <!-- 归集所有组内的PT2子节点 --> <xsl:copy-of select="current-group()/PT2"/> </TP1> </xsl:for-each-group> </P01> </xsl:template> </xsl:stylesheet>
关键细节说明
- 分组键设计:用
concat(字段1, '|', 字段2)作为分组键,避免单一字段重复导致的错误分组(比如ALF相同但OND不同的场景)。 - 版本兼容性:依赖XSLT 2.0及以上的
xsl:for-each-group功能,若使用XSLT 3.0,只需修改stylesheet的version属性即可兼容。 - 节点保留规则:分组后保留组内第一个节点的标识字段(如ALF/OND、ID/RAS),确保合并后的节点标识唯一且正确。
示例验证
输入XML
<Root> <K18> <ALF>A1</ALF> <OND>O1</OND> <P04Y>Y1</P04Y> <P01> <TP1> <ID>T1</ID> <RAS>R1</RAS> <PT2>PT2-1</PT2> </TP1> </P01> </K18> <K18> <ALF>A1</ALF> <OND>O1</OND> <P04Z>Z1</P04Z> <P01> <TP1> <ID>T1</ID> <RAS>R1</RAS> <PT2>PT2-2</PT2> </TP1> </P01> </K18> </Root>
输出XML
<Root> <K18> <ALF>A1</ALF> <OND>O1</OND> <P04Y>Y1</P04Y> <P04Z>Z1</P04Z> <P01> <TP1> <ID>T1</ID> <RAS>R1</RAS> <PT2>PT2-1</PT2> <PT2>PT2-2</PT2> </TP1> </P01> </K18> </Root>
内容的提问来源于stack exchange,提问作者CHAR
相关产品推荐
相关产品推荐

