XSLT处理XML:删除节点、修改元素名及添加DOCKEY元素求助
XSLT解决方案
原代码问题分析
- 仅匹配
TMSG元素,无法处理深层嵌套的IDS.LIST(如DOC或DTL.LIST内部的实例)。 - 使用
copy-of select="* except (IDS.LIST,DTL.LIST)"会直接删除所有DTL.LIST,不符合保留并处理该元素的需求。 - 未覆盖元素名称去点和添加
DOCKEY的核心需求。
满足所有需求的XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 身份转换模板:默认复制所有节点,除非被其他模板覆盖 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 删除所有IDS.LIST元素及其子节点 --> <xsl:template match="IDS.LIST"/> <!-- 处理元素名称(移除点号)+ 为指定列表添加DOCKEY --> <xsl:template match="*[not(self::IDS.LIST)]"> <xsl:element name="{replace(local-name(), '\.', '')}"> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="node()"/> <!-- 为有子元素的原DTL.LIST添加DOCKEY --> <xsl:if test="local-name() = 'DTL.LIST' and node()"> <DOCKEY> <xsl:value-of select="../DOCKEY"/> </DOCKEY> </xsl:if> <!-- 为有子元素的原BA.LIST添加DOCKEY --> <xsl:if test="local-name() = 'BA.LIST' and node()"> <DOCKEY> <xsl:value-of select="../../DOCKEY"/> </DOCKEY> </xsl:if> </xsl:element> </xsl:template> </xsl:stylesheet>
代码说明
- 身份转换模板:作为基础逻辑,确保所有未被特殊处理的节点(属性、文本、注释等)都被原样复制。
- 删除IDS.LIST:通过匹配
IDS.LIST元素且不输出任何内容,直接删除所有该元素及其子节点。 - 元素名称处理:使用
replace(local-name(), '\.', '')移除元素名称中的所有点号,生成新的元素名称。 - 添加DOCKEY:
- 对于原
DTL.LIST元素,若包含子节点,则从父节点DOC中获取DOCKEY值并添加新的DOCKEY元素。 - 对于原
BA.LIST元素,若包含子节点,则从祖父节点DOC中获取DOCKEY值并添加新的DOCKEY元素。
- 对于原
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

