【问题标题】:XSL: Ignoring/stripping namespaces in secondary documentsXSL:忽略/剥离辅助文档中的命名空间
【发布时间】:2010-01-12 09:17:27
【问题描述】:

我正在编写一个 XSL 模板,该模板从许多二级来源中提取数据。辅助文档示例如下所示:

<toplevel xmlns:foo1="http://foo1">
 <path xmlns="http://foo1">
   <mytag>bar</mytag>
  </path>
</toplevel>

在 XSL 中,我这样做:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:foo1="http://foo1"
 exclude-result-prefixes="foo1">
  <xsl:variable name="secondary1" select="document('secondary1.xml')/toplevel"/>
  <foo>
    <xsl:value-of select="$secondary1//foo1:path/foo1:mytag"/>
  </foo>
</xsl:stylesheet>

由于有很多次要资源,每个资源都使用不同的命名空间,给每个标签添加前缀很乏味,而且这么多重复也不是正确的做法。有没有办法使用 document() 使得导入的节点集的命名空间被剥离(或以另一种方式达到相同的效果)?

【问题讨论】:

  • 我假设您打算在第一个文档中包含默认命名空间声明: xmlns="http:// foo1" 现在的方式是,元素不在命名空间中。 (对不起,命名空间 URI 中的多余空间;我不知道如何防止 SO 将其呈现为“foo1”链接。)
  • 抱歉,是的,我就是这个意思。我已经相应地编辑了问题。

标签: xslt namespaces document strip


【解决方案1】:

在 XPath/XSLT 1.0 中,要按名称选择名称空间限定的元素,您必须使用前缀。在 XSLT 2.0 中,您可以使用 xpath-default-namespace 功能,它允许您为 XPath 表达式设置默认名称空间,因此您不必再使用前缀。有关详细信息,请参阅XSLT 2.0: xpath-default-namespace。您可以在样式表中的任何元素上使用此属性,并且除非被覆盖,否则它将对所有后代元素生效。 (使用 xsl 对其进行限定:当您想将其放在非 XSLT 元素上时,即文字结果元素。)

在 XPath 1.0 中,您还可以使用本地名称来选择元素,例如 *[local-name() = 'path']/*[local-name() = 'mytag']。在 XPath 2.0 中,为了更加简洁,您可以使用命名空间通配符,如 *:path/*:mytagas described here。这是一个有争议的补充,因为它似乎鼓励和/或证明您的系统显然正在使用同样可疑的命名空间。

【讨论】:

    【解决方案2】:

    本质上,具有命名空间的节点与具有另一个命名空间的节点完全不同 - 即使它们碰巧共享相同的本地名称。 (这与命名空间在其他任何地方的工作方式大致相同 - 实际上没有简单的“忽略”命名空间的方法。在 C# 中引用类时考虑忽略命名空间。)

    干净的方法是提及您在 XSLT 中可能遇到的每个命名空间并使用前缀,即使它看起来重复。

    不太干净的方法是这样的:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >
      <xsl:variable name="secondary1" select="document('secondary1.xml')"/>
    
      <xsl:template match="/">
        <foo source="1">
          <xsl:value-of select="
            $secondary1//*[local-name() = 'path']/*[local-name() = 'mytag']
          "/>
        </foo>
      </xsl:template>
    </xsl:stylesheet>
    

    这并不比使用前缀更令人赏心悦目,它更长更难阅读,它是模棱两可的,最后但并非最不重要的一点 - 因为引擎必须测试一个XPath 上每一步的谓词。任君挑选。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 2010-09-21
      相关资源
      最近更新 更多