You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XSL的for-each标签中访问包含xmlns的所有属性?

How to Access Namespace Declaration Attributes (xmlns:*) in XSLT

你遇到的问题很典型——XML里的xmlns:*(包括无后缀的xmlns)不是常规属性,而是命名空间声明,XPath的@*轴只会选中普通属性,所以它们不会被遍历到。要获取这些"属性",需要用专门的XPath轴来访问命名空间节点。

解决方案:使用namespace::轴访问命名空间声明

在XSLT 2.0中,你可以通过namespace::轴获取当前节点上的所有命名空间节点,再将它们格式化成你需要的<name>和<value>结构。

修改后的XSLT代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
  <xsl:template match="/"> 
    <!-- 遍历所有常规属性 -->
    <xsl:for-each select="/schema/@*"> 
      <name><xsl:value-of select="name()"/></name> 
      <value><xsl:value-of select="."/></value> 
    </xsl:for-each> 

    <!-- 遍历所有命名空间声明(排除XML自带的默认xml命名空间) -->
    <xsl:for-each select="/schema/namespace::*[not(local-name()='xml')]">
      <name>
        <!-- 处理默认命名空间(无前缀的情况,即xmlns="xxx") -->
        <xsl:choose>
          <xsl:when test="local-name() = ''">xmlns</xsl:when>
          <xsl:otherwise>xmlns:<xsl:value-of select="local-name()"/></xsl:otherwise>
        </xsl:choose>
      </name>
      <value><xsl:value-of select="."/></value>
    </xsl:for-each>
  </xsl:template> 
</xsl:stylesheet>

代码说明

  1. 常规属性遍历:保留你原有的@*逻辑,处理a="a"和something:b="b"这类普通属性。
  2. 命名空间节点遍历:
    • namespace::*轴选中当前节点(这里是<schema>)上的所有命名空间节点。
    • not(local-name()='xml')过滤掉XML规范自带的xml命名空间(它的URI是http://www.w3.org/XML/1998/namespace,通常不需要输出)。
    • 针对默认命名空间(无前缀,即xmlns="xxx"),输出<name>xmlns</name>;带前缀的命名空间则输出<name>xmlns:前缀</name>,和XML中的写法完全一致。

最终转换结果

用这段XSLT处理你的XML,会得到完整的输出:

<name>a</name><value>a</value>
<name>something:b</name><value>b</value>
<name>xmlns:c</name><value>c</value>

为什么@*选不到命名空间声明?

XML解析器会把xmlns:*和xmlns识别为命名空间绑定信息,而非普通属性。在XPath数据模型中,它们属于单独的namespace::轴,和attribute::(简写@)轴是完全分开的,所以@*不会包含这些节点。

内容的提问来源于stack exchange,提问作者user3429660

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:27:38