XSLT排序E1EDL20时如何保留父级E1EDT20元素
XSLT转换丢失E1EDT20节点问题修复方案
问题根因
匹配E1EDT20的模板中仅编写了子节点的输出逻辑,没有显式创建当前E1EDT20元素本身。XSLT不会自动为匹配到的节点生成输出标签,因此子节点会直接被输出到上层IDOC节点下,造成父节点丢失。
修复写法
在<xsl:template match="E1EDT20">语句后,首先补充当前节点的复制逻辑,完整模板结构参考如下:
<xsl:template match="E1EDT20"> <!-- 新增:复制当前E1EDT20节点本身,自动继承原有命名空间、节点类型 --> <xsl:copy> <!-- 新增:复制E1EDT20节点上的所有原有属性、命名空间声明 --> <xsl:apply-templates select="@* | namespace::*"/> <!-- 原有逻辑:复制所有非E1EDL20类型的子节点 --> <xsl:apply-templates select="node()[not(self::E1EDL20)]"/> <!-- 原有逻辑:按VKORG字段排序后输出E1EDL20节点 --> <xsl:for-each select="E1EDL20"> <xsl:sort select="VKORG" data-type="text" order="ascending"/> <!-- 若E1EDL20节点下有自定义转换规则,将copy-of替换为<xsl:apply-templates select="."/>即可触发全局模板 --> <xsl:copy-of select="."/> </xsl:for-each> <!-- 新增:闭合E1EDT20元素标签 --> </xsl:copy> </xsl:template>
注意事项
- 优先使用
<xsl:copy>而非硬编码<xsl:element name="E1EDT20">创建节点,前者会自动适配SAP IDOC报文的命名空间前缀,避免出现命名空间不匹配、前缀错乱的问题。 - 复制子节点时使用
node()匹配而非仅匹配*,可以一并保留节点下的文本、注释等非元素节点,和全局身份复制模板的行为保持一致。 - 若后续需要对E1EDT20新增属性、或修改节点属性值,直接在
<xsl:copy>标签下补充对应属性逻辑即可,不需要调整整体结构。
内容的提问来源于stack exchange,提问作者Mike Dole
相关产品推荐
相关产品推荐

