很可能您的问题是由源XHTML文件中存在默认(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将任何未命名的名称视为“无命名空间”,而具有非前缀名称的匹配表达式不匹配任何节点,因为它指定了“无命名空间”的节点,但源文档的所有节点都在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']"
的节点的身份规则。这个第二个模板是空的(没有主体),这意味着匹配的节点和以它为根的子树根本没有被处理(被忽略),因此不会出现在输出中。