您的问题很可能是由于源 XHTML 文件中存在默认 (xhtml) 命名空间(您没有向我们展示,所以这充其量只是猜测)。
谁能解释一下正确的方法
删除及其所有
身份转换的孩子?
下面是在存在默认命名空间的情况下如何执行此操作:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<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="xhtml:div[@class='foo']"/>
</xsl:stylesheet>
当此转换应用于以下 XHTML 文档时:
<html xmlns="http://www.w3.org/1999/xhtml">
<div class="class1">
<p>Text1</p>
</div>
<div class="foo">
<p>Text foo</p>
</div>
<div class="class2">
<p>Text2</p>
</div>
</html>
产生想要的正确结果:
<html xmlns="http://www.w3.org/1999/xhtml">
<div class="class1">
<p>Text1</p>
</div>
<div class="class2">
<p>Text2</p>
</div>
</html>
必须在模板的匹配表达式中使用命名空间前缀,因为 XPath 会考虑“无命名空间”中的任何无前缀名称,而具有无前缀名称的匹配表达式不会匹配任何节点,因为它在“no namspace”中指定了节点,但源文档的所有节点都在 XHTML 命名空间中。
如果源文档中没有默认命名空间,可以简化转换:
当此转换应用于以下 XML 文档时(请注意,它没有定义默认命名空间):
<html>
<div class="class1">
<p>Text1</p>
</div>
<div class="foo">
<p>Text foo</p>
</div>
<div class="class2">
<p>Text2</p>
</div>
</html>
产生想要的正确结果:
<html>
<div class="class1">
<p>Text1</p>
</div>
<div class="class2">
<p>Text2</p>
</div>
</html>
两种转换都使用身份规则复制文档的任何节点和另一个模板,这会覆盖与"div[@class='foo']"匹配的节点的身份规则。第二个模板是空的(没有主体),这意味着匹配的节点和以它为根的子树根本不被处理(忽略),因此不会出现在输出中。