【问题标题】:XSLT to transform a XHTML documentXSLT 转换 XHTML 文档
【发布时间】:2010-07-31 22:59:37
【问题描述】:

我是 XSLT 的新手,但有人建议我将它作为完成特定任务的一种方式。我有一堆 xhtml 文件,我想从中删除边栏。侧边栏包含在

元素中。

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

有人可以解释从身份转换中删除

及其所有子项的正确方法吗?

【问题讨论】:

  • 好问题 (+1)。请参阅我的答案以获取详细的解决方案和解释。

标签: xslt


【解决方案1】:

您的问题很可能是由于源 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']"匹配的节点的身份规则。第二个模板是空的(没有主体),这意味着匹配的节点和以它为根的子树根本不被处理(忽略),因此不会出现在输出中。

【讨论】:

  • 您的代码有效,但为什么这无效:
  • 我最终使用了两个样式表:一个用于剥离元素,另一个用于添加正确的 DTD 语句。
  • @jbtx:为什么,这对我不利。我得到了输出的开头:&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;。也许您的 XSLT 处理器有问题?我的结果是由 Saxon 6.5.4、MSXML 3-6、AltovaXML (XML-SPY)、Saxon 9.1.07 和 XML-SPY-XSLT2.0 生成的。如果您使用两个可用的 .NET XSLT 处理器之一,则必须微调作为参数传递给 Transform() 方法的 XmlWriter 的设置。阅读您的文档。
猜你喜欢
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
  • 2011-12-13
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 2013-11-09
相关资源
最近更新 更多