请求修改XSL样式表:仅为空节点(无属性)添加xsi:nil="true"
解决XSL误将带属性的空节点标记为xsi:nil的问题
我来帮你搞定这个问题!你的核心需求是只给**完全空的节点(既没有属性也没有子节点/文本内容)**加上xsi:nil="true",而不是所有空节点——之前的XSL模板没区分「带属性的空节点」和「完全空的节点」,所以才会误删原有属性。
关键修改:添加属性存在性判断
你只需要在匹配空节点的模板里,额外加上not(@*)条件,就能排除所有带有属性的节点。下面是完整的修正后的XSL示例:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- 默认身份模板:复制所有节点、属性和文本,确保其他内容不受影响 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 仅匹配完全空的节点:无属性 + 无子节点/文本 --> <xsl:template match="*[not(node()) and not(@*)]"> <xsl:copy> <xsl:attribute name="xsi:nil">true</xsl:attribute> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
not(node()):判断节点是否没有任何子节点(包括文本节点),也就是空标签的状态。not(@*):新增的条件,判断节点是否没有任何属性。只有同时满足这两个条件的节点,才会被添加xsi:nil="true"属性。- 身份模板是基础,确保所有不匹配特殊规则的节点、属性都被原样复制,不会丢失原有内容。
测试示例
假设你的输入XML是这样的:
<root> <test/> <!-- 完全空的节点,会被添加xsi:nil --> <test s:id="121"/> <!-- 带属性的空节点,保留原有属性 --> <test>Hello</test> <!-- 有内容的节点,不受影响 --> </root>
经过上述XSL转换后,输出会是:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <test xsi:nil="true"/> <test s:id="121"/> <test>Hello</test> </root>
这样就完美实现了你想要的效果:只有完全无属性的空节点才会被标记为xsi:nil="true",带属性的空节点会保留原有属性不受影响。
内容的提问来源于stack exchange,提问作者user7071176
相关产品推荐
相关产品推荐

