我是XSLT的新手,但我建议将其作为完成特定任务的一种方式。我有一堆xhtml文件,我想删除侧边栏。侧边栏包含在< div class =“foo”>中。元件。
我可以使用此答案中的说明成功执行身份转换:How to remove elements from xml using xslt with stylesheet and xsltproc?但我似乎无法匹配我想删除的元素。也许这是因为它们不是顶级元素,就像我在这个设计模式的每个例子中都找到的那样?
有人可以解释删除< div class =“foo”>的正确方法吗?以及来自身份变换的所有孩子?
答案 0 :(得分:4)
由于源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 namespace”中考虑任何未加前缀的名称,而带有非加前缀名称的匹配表达式与任何节点都不匹配,因为它在“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']"
的节点的标识规则。第二个模板为空(没有主体),这意味着匹配的节点和根植于其中的子树根本不被处理(被忽略),因此不会出现在输出中。