XSLT 1.0合并子节点与拼接元素的优化技术问询
XSLT合并同名子节点解决方案(优先1.0)
针对你需要合并ns0:LOOPLin下所有ns0:FTX_5节点,将每个FTX_5内C10801-C10805值拼接为单个C10801的需求,以下是满足你三个问题的实现方案:
XSLT 1.0 实现
核心用身份转换模板配合Muenchian分组,全程不用copy-of select="./*[not(self::ns0:FTX_5)]",同时保留节点原位置、不生成空节点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="你的命名空间URI"> <!-- 按LOOPLin分组FTX_5节点 --> <xsl:key name="ftx-by-loop" match="ns0:FTX_5" use="generate-id(..)" /> <!-- 身份转换:复制所有未被特殊处理的节点 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <!-- 处理LOOPLin节点,遍历子节点并处理FTX_5 --> <xsl:template match="ns0:LOOPLin"> <xsl:copy> <xsl:apply-templates select="@*" /> <xsl:variable name="current-loop" select="." /> <xsl:for-each select="node()"> <xsl:choose> <!-- 仅在第一个FTX_5位置生成合并后的节点 --> <xsl:when test="self::ns0:FTX_5 and generate-id() = generate-id(key('ftx-by-loop', generate-id($current-loop))[1])"> <ns0:FTX_5> <ns0:C10801> <!-- 拼接当前LOOPLin下所有FTX_5的C10801-C10805值 --> <xsl:for-each select="key('ftx-by-loop', generate-id($current-loop))"> <xsl:value-of select="concat(ns0:C10801, ns0:C10802, ns0:C10803, ns0:C10804, ns0:C10805)" /> <!-- 如需分隔符,可添加:<xsl:if test="position() != last()">|</xsl:if> --> </xsl:for-each> </ns0:C10801> </ns0:FTX_5> </xsl:when> <!-- 跳过后续的FTX_5节点 --> <xsl:when test="self::ns0:FTX_5" /> <!-- 处理其他所有节点,保留原顺序和位置 --> <xsl:otherwise> <xsl:apply-templates select="." /> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:copy> </xsl:template> </xsl:stylesheet>
对应你的三个问题:
- 可以不用指定排除FTX_5的copy-of:通过遍历
LOOPLin的子节点,逐个判断处理,跳过重复的FTX_5,无需用排除式拷贝。 - FTX_5保留原位置:在第一个
FTX_5的原有位置生成合并后的节点,其余FTX_5直接跳过,其他节点按原顺序输出,完全保留结构位置。 - 无FTX_5时不生成空节点:只有当
LOOPLin下存在FTX_5时,才会触发合并节点的生成逻辑,没有FTX_5的LOOPLin会正常复制所有子节点,不会额外生成空节点。
XSLT 2.0/3.0 简化实现
利用for-each-group语法,代码更简洁,同样满足所有要求:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="你的命名空间URI"> <!-- 默认复制所有节点 --> <xsl:mode on-no-match="shallow-copy" /> <!-- 处理LOOPLin节点,分组处理FTX_5 --> <xsl:template match="ns0:LOOPLin"> <xsl:copy> <xsl:apply-templates select="@*" /> <xsl:for-each-group select="node()" group-adjacent="boolean(self::ns0:FTX_5)"> <xsl:choose> <xsl:when test="current-grouping-key()"> <!-- 合并当前组内所有FTX_5的内容 --> <ns0:FTX_5> <ns0:C10801> <xsl:value-of select="current-group()/(ns0:C10801, ns0:C10802, ns0:C10803, ns0:C10804, ns0:C10805)" separator="" /> </ns0:C10801> </ns0:FTX_5> </xsl:when> <xsl:otherwise> <!-- 输出非FTX_5的节点组 --> <xsl:apply-templates select="current-group()" /> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:copy> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者MichaelMS
相关产品推荐
相关产品推荐

