XSLT XML处理:合并G07节点下重复E2EDT43记录的技术问询
XSLT合并G07节点下重复E2EDT43记录解决方案
核心实现思路
采用XSLT标准的身份转换模板兜底复制所有原始内容,仅针对G07节点重载处理逻辑:对其下的E2EDT43节点按E2EDT43_VBELN和E2EDT43_POSNR分组,合并同组记录的数量字段,其他子节点及后续所有节点保持原样输出,完美解决上下文中断的问题。
完整XSLT代码
<xsl:stylesheet version="2.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> <!-- 专门处理G07节点,合并重复E2EDT43 --> <xsl:template match="G07"> <xsl:copy> <!-- 复制G07自身的所有属性 --> <xsl:apply-templates select="@*"/> <!-- 遍历G07的所有子节点,复制非E2EDT43节点 --> <xsl:copy-of select="node()[not(local-name()='E2EDT43')]"/> <!-- 对E2EDT43按VBELN和POSNR分组合并 --> <xsl:for-each-group select="E2EDT43" group-by="concat(E2EDT43_VBELN, '|', E2EDT43_POSNR)"> <xsl:copy> <!-- 复用组内第一条记录的属性和非数量子节点 --> <xsl:apply-templates select="current-group()[1]/@*"/> <xsl:for-each select="current-group()[1]/node()"> <xsl:choose> <!-- 替换数量字段为分组求和值 --> <xsl:when test="local-name()='E2EDT43_MENGE'"> <E2EDT43_MENGE> <xsl:value-of select="sum(current-group()/E2EDT43_MENGE)"/> </E2EDT43_MENGE> </xsl:when> <!-- 其他子节点直接复制 --> <xsl:otherwise> <xsl:copy-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:copy> </xsl:for-each-group> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- 身份转换模板:作为默认逻辑,确保所有未被专门匹配的节点(包括后续G07节点、其他业务节点)完全复制,100%保留原始XML结构。
- G07节点处理:
- 先复制G07自身属性和所有非E2EDT43子节点,保证原有结构不变。
- 用
xsl:for-each-group对E2EDT43按VBELN+POSNR的组合键分组(用|分隔避免键值冲突)。 - 每组生成一个新的E2EDT43节点:复用组内第一条记录的属性和非数量字段,将数量字段替换为组内所有记录的数量求和值。
- 字段适配:如果你的数量字段不是
E2EDT43_MENGE,或者VBELN/POSNR是属性而非子节点,只需修改对应节点/属性名即可(比如@E2EDT43_VBELN表示属性)。
关键优势
- 仅修改目标重复记录,其余内容完全与输入一致。
- 处理完G07节点后,后续节点仍由身份模板正常处理,不会出现上下文中断问题。
- 支持XSLT 2.0及以上版本(主流XSLT处理器如Saxon、Altova均支持)。
内容的提问来源于stack exchange,提问作者Asolarski
相关产品推荐
相关产品推荐

