【问题标题】:Iterate through XML nodes that have xmlns attribute declared in a XSL遍历具有在 XSL 中声明的 xmlns 属性的 XML 节点
【发布时间】:2011-01-09 05:31:42
【问题描述】:

我正在创建一个 XSL 来格式化来自我正在集成的 API 的一些传入 XML。我收到的 xml 如下所示:

<items>
  <item xmlns="http://www.tempuri.org/Item.xsd">
    <key>value</key>
  </item>
  <item>
    <key>value</key>
  </item>
  <item xmlns="http://www.tempuri.org/Item.xsd">
    <key>value</key>
  </item>
</items>

一些“item”节点定义了“xmlns”属性,而另一些则没有。当我尝试遍历我的 XSL 中的结果时,它没有找到定义了 xmlns 属性的节点。

<xsl:for-each select="item">
  <xsl:value-of select="key" />
</xsl:for-each>

我对整个 XSL 有点陌生,所以我不确定我做错了什么。

【问题讨论】:

    标签: xml loops xslt foreach xml-namespaces


    【解决方案1】:

    您需要在 &lt;xsl:stylesheet&gt; 定义中定义相同的命名空间。

    然后:

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:ns="http://www.tempuri.org/Item.xsd"
        extension-element-prefixes="exsl"
        encoding="utf-8">
    
    . . .
    
    <xsl:for-each select="item|ns:item">
        <xsl:value-of select="key|ns:key"/>
    </xsl:for-each>
    

    确实,您应该尝试为相同的事物使用相同的命名空间。

    【讨论】:

    • 谢谢。这很好用。然而,它带来了另一个问题。一旦我进入“ns:item”元素,有没有办法通过输入“key”而不是“ns:key”来访问每个“key”?
    • 不,命名空间的定义方式,key 和 ns:key 是不同的。通过更改项目的默认命名空间,您可以更改项目内部键的命名空间。
    【解决方案2】:

    首先,如果您不了解 XML 名称空间的工作原理以及它们的含义,那么您将遇到无穷无尽的问题。您正在努力解决的这个问题只是冰山一角。

    也就是说,您可以按照 Kyle Butt 建议的方式处理命名空间,在 stylesheet 元素中分配前缀到命名空间的转换范围映射,然后在 XPath 表达式中使用前缀。

    但是如果您不知道命名空间怎么办?然后你必须使用更钝的工具:

    <xsl:for-each select="*[local-name()='item']">
      <xsl:value-of select="*[local-name()='key']"/>
    </xsl:for-each>
    

    使用local-name() 会完全忽略命名空间。但是你不能在节点测试中使用它(它必须是像foo 这样的名称或像x:foo 这样的限定名称),你只能在谓词中使用它。这就是为什么不可爱的*[local-name()='foo'] 是唯一的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多