【问题标题】:How to deal with presence or not of xml namespaces using xslt如何使用 xslt 处理是否存在 xml 命名空间
【发布时间】:2010-04-16 11:52:46
【问题描述】:

我有一些 XML/TEI 文档,我正在编写一个 XSLT 2.0 来提取它们的内容。

几乎所有 TEI 文档都没有命名空间,但有一个具有默认命名空间 (xmlns="http://www.tei-c.org/ns/1.0")。 因此,所有文档都具有相同的方面,带有<TEI><teiHeader> 之类的未限定标签,但是如果我尝试提取内容,则所有文档都适用于“非命名空间文档”,但没有(当然)从命名空间文档。

所以我使用了属性xpath-default-namespace="http://www.tei-c.org/ns/1.0",现在(当然)唯一有效的文档是命名空间的。

我根本无法编辑文档,所以我要问的是是否有一种方法可以动态更改 xpath-default-namespace 以使 xpath 像 //teiHeader 一样具有命名空间和非命名空间文档

【问题讨论】:

  • 好问题 (+1)。请参阅我的答案以获得更实用的解决方案。 :)

标签: xslt namespaces xml-namespaces


【解决方案1】:

如果您使用的是 XSLT 2.0,那么您可以选择在节点测试中为命名空间进行通配符匹配。

例如//*:teiHeader

http://www.w3.org/TR/xpath20/#node-tests

节点测试也可以有以下形式 *:NC 名称。在这种情况下,节点测试对于主体的任何节点都为真 其局部的步进轴的节点类型 name 匹配给定的 NCName, 无论其命名空间或缺乏 命名空间。

这在功能上等同于 Dimitre Novatchev 的示例,但更短/更易于键入。

但是,这只适用于 XSLT/XPATH 2.0

【讨论】:

    【解决方案2】:

    没有一种干净的方法可以准确地完成您的要求。但是,有可用的解决方法。你可以使用一个两阶段的过程,如果它存在的话,你从文档中去除命名空间,然后将它传递给所有内容的相同模板。

    DocBook XSLT 中有一个很好的例子(在 XSLT 1 中)。看看 html/docbook.xsl 和 common/stripns.xsl

    基本上,您需要将剥离命名空间的结果分配给一个变量,然后调用您现有的模板(对于非命名空间)内容但选择该变量。

    【讨论】:

      【解决方案3】:

      它很丑,但这会给你你想要的

      //*[name()='teiHeader']
      

      如果您对任何 XPath 表达式中的所有定位步骤都使用此样式,则 XPath 表达式将仅按名称选择元素,而不管元素是否属于任何命名空间。

      【讨论】:

        猜你喜欢
        • 2013-04-11
        • 2011-09-05
        • 2011-05-14
        • 2010-12-16
        • 1970-01-01
        • 2010-12-22
        • 2018-02-08
        • 2011-07-07
        • 2014-05-31
        相关资源
        最近更新 更多