XSLT 不忽略命名空间前缀

Posted

技术标签:

【中文标题】XSLT 不忽略命名空间前缀【英文标题】:XLST not ignoring namespace prefix 【发布时间】:2018-04-30 02:35:21 【问题描述】:

我有以下 xmldata 输入,应该通过 xslt 进行转换。 我只是想提取 ns:something 内容。 dynamicNS 命名空间在运行时可能不同。

<?xml version="1.0"?>
<dynamicNS:header>
  <ns:something>
    <ns:myid>1</ns:myid>
    <ns:myvalue>2</ns:myvalue>
  </ns:something>
</dynamicNS:header>

输出应该是:

<?xml version="1.0"?>
  <ns:something>
    <ns:myid>1</ns:myid>
    <ns:myvalue>2</ns:myvalue>
  </ns:something>

我试过了:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="*">
      <ns:something>
          <xsl:copy-of select="node()"/>
      </ns:something>
    </xsl:template>

</xsl:stylesheet>

但这给了我错误:元素“dynamicNS:header”的前缀“dynamicNS”未绑定。;

我不想为 dynamicNS 添加命名空间,因为每次运行都可能不同。

获得所需输出的正确方法是什么?

谢谢大家。

【问题讨论】:

错误消息来自 XML 解析器,告诉您在输入中没有前缀 dynamicNS 的命名空间声明。这样,输入不是名称空间格式良好的 XML,因此不能用作 XSLT/XPath 的输入,因为这需要名称空间格式正确的 XML。 谢谢马丁。你的解释很有道理。所以现在我将命名空间声明手册添加到从数据对象生成的 xmldata 中。它现在可以工作,但我仍然不确定我的 xslt 实现是否是正确的选择。至少现在结果很好。使用第一篇文章中提到的 xslt 是我改造的最佳方式吗? 我看不出所发布的样式表代码是如何工作的XSLT 处理器将如何处理它。 【参考方案1】:

如果您想省略根元素及其命名空间声明并仅复制其子元素,那么在 XSLT 2 及更高版本中您可以使用

复制根的所有子元素,例如输入

<dynamicNS:header xmlns:dynamicNS="http://example.com/foo">
  <ns:something xmlns:ns="http://example.com/ns">
    <ns:myid>1</ns:myid>
    <ns:myvalue>2</ns:myvalue>
  </ns:something>
</dynamicNS:header>

转化为结果

<ns:something xmlns:ns="http://example.com/ns">
    <ns:myid>1</ns:myid>
    <ns:myvalue>2</ns:myvalue>
  </ns:something>

http://xsltransform.hikmatu.com/gWcDMee

正如我在 cmets 中已经说过的,XSLT 的输入和样式表代码都需要是名称空间格式良好的 XML 文档,因此您在问题中发布的输入和输出带有不存在名称空间声明的前缀不允许 XSLT 处理。

【讨论】:

以上是关于XSLT 不忽略命名空间前缀的主要内容,如果未能解决你的问题,请参考以下文章

xsd:any 元素的命名空间前缀并使用 XSLT 添加命名空间前缀

XSLT 将命名空间前缀添加到元素最佳实践

XSLT - 删除前缀命名空间特定节点 XML

xslt 中的 XML 命名空间处理

如何使用 XSLT 替换命名空间中的元素?

Xpath或Xquery忽略任何类型的命名空间前缀