【发布时间】:2011-12-06 16:29:45
【问题描述】:
我想删除只包含空格/换行符/制表符的标签,如下所示:
<p> </p>
您将如何使用 xpath 函数和 xslt 模板来做到这一点?
【问题讨论】:
-
好问题,+1。使用最基本和最强大的 XSLT 设计模式——覆盖身份规则,可以正确地产生想要的结果。
我想删除只包含空格/换行符/制表符的标签,如下所示:
<p> </p>
您将如何使用 xpath 函数和 xslt 模板来做到这一点?
【问题讨论】:
这个转换(覆盖identity rule):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*) and not(text()[normalize-space()])]"/>
</xsl:stylesheet>
应用于以下 XML 文档时:
<t>
<a>
<b>
<c/>
</b>
</a>
<p></p>
<p> </p>
<p>Text</p>
</t>
正确产生想要的结果:
<t>
<a>
<b/>
</a>
<p>Text</p>
</t>
记住:使用和覆盖标识规则/模板是最基本和最强大的 XSLT 设计模式。对于大部分节点原封不动地复制,只有部分特定节点需要更改、删除、重命名、...等的各种问题,它是正确的选择。
注意:@Abel 在他的评论中建议该解决方案的某些部分需要进一步解释:
对于初学者或好奇者:
not(*)表示:没有孩子 元素;not(text()[normalize-space()])表示:没有文本节点 带有非纯空白文本。
【讨论】:
not(*) 表示:没有子元素; not(text()[normalize-space()]) 表示:没有带有文本的文本节点。