XSLT转换XHTML文档

时间:2010-07-31 22:59:38

标签: xslt

我是XSLT的新手,但我建议将其作为完成特定任务的一种方式。我有一堆xhtml文件,我想删除侧边栏。侧边栏包含在< div class =“foo”>中。元件。

我可以使用此答案中的说明成功执行身份转换:How to remove elements from xml using xslt with stylesheet and xsltproc?但我似乎无法匹配我想删除的元素。也许这是因为它们不是顶级元素,就像我在这个设计模式的每个例子中都找到的那样?

有人可以解释删除< div class =“foo”>的正确方法吗?以及来自身份变换的所有孩子?

1 个答案:

答案 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']" 的节点的标识规则。第二个模板为空(没有主体),这意味着匹配的节点和根植于其中的子树根本不被处理(被忽略),因此不会出现在输出中。