代码之家  ›  专栏  ›  技术社区  ›  knipknap

忽略/剥离辅助文档中的命名空间

  •  1
  • knipknap  · 技术社区  · 16 年前

    我正在编写一个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()来剥离导入的节点集的命名空间(或者用另一种方法实现相同的效果)?

    2 回复  |  直到 16 年前
        1
  •  2
  •   Tomalak    16 年前

    本质上,具有名称空间的节点是 完全不同的动物 比具有另一个名称空间的节点-即使它们恰好共享相同的本地名称。(这与名称空间在其他任何地方的工作方式基本相同—实际上不存在“忽略”名称空间的简单方法。当引用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上。你挑吧。

        2
  •  3
  •   Evan Lenz    16 年前

    在xpath/xslt 1.0中,若要按名称选择命名空间限定元素,必须使用前缀。在XSLT2.0中,可以使用 xpath-default-namespace 特性,它允许您为xpath表达式设置默认命名空间,因此您不再需要使用前缀。参见 XSLT 2.0: xpath-default-namespace 了解更多详细信息。您可以在样式表中的任何元素上使用此属性,除非被重写,否则它将对所有子代元素生效。(当您想将其放在非xslt元素(即文本结果元素)上时,请使用xsl:

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

    推荐文章