0

我有以下 XML:

<root xmlns:myns="derf">
    <child>
        <grandchild>mikey</grandchild>
    </child>
</root>

我正在尝试将其转换为以下 XML:

<root xmlns="theNamespace" xmlns:myns="derf">
    <child>
        <grandchild>mikey</grandchild>
    </child>
</root>

我认为以下 XSLT 会做到这一点:

<xsl:template match="/">
    <xsl:apply-templates select="/root"/>
</xsl:template>

<!-- identity template -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="root">
    <root xmlns="theNamespace">
        <xsl:apply-templates select="@*|node()"/>
    </root>
</xsl:template>

虽然发出:

<root xmlns="theNamespace">
    <child xmlns="" xmlns:myns="derf">
        <grandchild>mikey</grandchild>
    </child>
</root>

有人可以帮助我理解 - 并且理想地修复 - 为什么xmlns:myns="derf"最终出现在child节点上而不是root输出中的节点上?

我基本上只是想用xmlns命名空间值来扩充原始 XML。

在此先感谢,马特

4

1 回答 1

0

这里有两个问题 - 首先,您只是将root元素放在theNamespace命名空间中,因此子元素仍在其原始(空)命名空间中。其次,<xsl:copy>复制元素的命名空间的工作,但文字元素不会。此 XSLT 应该按照您描述的方式运行:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[name() = local-name()]">
    <xsl:element name="{name()}" namespace="theNamespace">
      <xsl:copy-of select="namespace::*[name() != '']" />
      <xsl:apply-templates select="@* | node()" />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

在您的示例输入上运行时,结果是:

<root xmlns="theNamespace" xmlns:myns="derf">
  <child>
    <grandchild>mikey</grandchild>
  </child>
</root>
于 2013-05-08T06:39:40.720 回答