XSLT节点过滤问题:空CMR元素无法移除及代码优化需求
SAP SHPMNT05 IDOC XML处理问题及解决方案
问题原因
你的XSLT代码保留空<CMR/>元素,是因为处理CMR节点时,仅对其子节点E1EDL20做了过滤,但没有判断过滤后CMR是否还有有效子节点。即使所有E1EDL20都被移除,模板仍然会输出空的CMR标签,缺少“仅当存在有效子节点时才保留CMR”的判断逻辑。
优化后的简洁XSLT实现
以下代码严格遵循你的5条处理规则,同时避免空节点残留:
<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> <!-- 过滤E1EDL24:仅保留LGORT值为1033或1035的条目 --> <xsl:template match="E1EDL24[not(E1EDL24-LGORT='1033' or E1EDL24-LGORT='1035')]"/> <!-- 移除无有效E1EDL24子节点的E1EDL20 --> <xsl:template match="E1EDL20[not(E1EDL24)]"/> <!-- 移除无有效E1EDL20子节点的CMR --> <xsl:template match="CMR[not(E1EDL20)]"/> <!-- 移除无有效CMR子节点的STOP --> <xsl:template match="STOP[not(CMR)]"/> <!-- 若无STOP节点,直接输出空内容 --> <xsl:template match="/"> <xsl:if test="//STOP"> <xsl:apply-templates/> </xsl:if> </xsl:template> </xsl:stylesheet>
代码说明
- 采用身份模板作为基础逻辑,默认复制所有节点,仅通过针对性模板覆盖需要过滤/移除的节点,逻辑清晰易维护。
- 从最底层节点到上层节点逐层过滤:
- 先筛除不符合条件的E1EDL24;
- 移除没有剩余E1EDL24的E1EDL20;
- 移除没有剩余E1EDL20的CMR;
- 移除没有剩余CMR的STOP;
- 根节点模板做最终判断:如果没有任何STOP节点,直接输出空内容,满足SAP PO生成0kb文件的要求。
内容的提问来源于stack exchange,提问作者Mike Dole
相关产品推荐
相关产品推荐

