如何用XSLT保留首个空<d>节点并移除末尾空<d>节点?
解决XML中保留指定空节点并移除末尾空节点的XSLT方案
问题场景
给定XML结构如下:
<c> <d> <d1></d1> <d2></d2> </d> <d>有内容的节点1</d> <d>有内容的节点2</d> <d></d> <!-- 需要移除的末尾空节点 --> </c>
需求:
- 保留第一个
<d>节点及其空的<d1>、<d2>子节点,且不能将第一个<d>压缩为自闭合标签(如<d/>) - 移除最后一个无内容的空
<d>节点
解决方案XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 输出设置:确保空节点以完整标签形式呈现,而非自闭合 --> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <!-- 身份模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 移除<c>下最后一个无内容的<d>节点 --> <xsl:template match="c/d[last() and not(* or normalize-space(text()))]"> <!-- 匹配到的节点不输出,实现移除 --> </xsl:template> </xsl:stylesheet>
代码说明
- 输出设置:
<xsl:output>指定XML输出格式,indent="yes"保证排版美观,同时确保有子节点的<d>和空的<d1>、<d2>以完整开放/闭合标签形式输出,不会被压缩为自闭合标签。 - 身份模板:负责复制XML中绝大多数节点和属性,保证原有结构和内容不变。
- 移除末尾空节点的模板:精准匹配
<c>下的最后一个<d>节点,且该节点满足两个条件:- 没有子元素(
not(*)) - 文本内容去除前后空白后为空(
normalize-space(text())为空)
匹配到的这类节点不生成输出,直接移除。
- 没有子元素(
转换后输出结果
<c> <d> <d1></d1> <d2></d2> </d> <d>有内容的节点1</d> <d>有内容的节点2</d> </c>
内容的提问来源于stack exchange,提问作者Sajan Alex
相关产品推荐
相关产品推荐

