Xml XSLT 1.0的命名空间输出导致问题

Xml XSLT 1.0的命名空间输出导致问题,xml,xslt,namespaces,xslt-1.0,Xml,Xslt,Namespaces,Xslt 1.0,我正在使用XSLT1.0转换一些XML 我不太确定解释这一点的最佳方式,因此将使用一些示例 我的输入XML包含一个专门化,使用xsi:type声明。请参阅有效负载节点: <ns0:RootNode xmlns:ns0="namespace1" xmlns:ns1="namespace2" xmlns:xsi="http://www.w3.org/2001/XMLSchema"> <ns0:Payload xsi:type="ns1:SpecialPayload">

我正在使用XSLT1.0转换一些XML

我不太确定解释这一点的最佳方式,因此将使用一些示例

我的输入XML包含一个专门化,使用xsi:type声明。请参阅有效负载节点:

<ns0:RootNode xmlns:ns0="namespace1" xmlns:ns1="namespace2" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
  <ns0:Payload xsi:type="ns1:SpecialPayload">
    <ns1:InnerNode>Hello</ns1:InnerNode>
  </ns0:Payload>
</ns0:RootNode>

你好
当我通过XSLT发送它时(假设是1对1的副本),我得到以下输出

<ns0:RootNode xmlns:ns0="namespace1" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
  <ns0:Payload xsi:type="ns1:SpecialPayload">
    <ns1:InnerNode xmlns:ns1="namespace2">Hello</ns1:InnerNode>
  </ns0:Payload>
</ns0:RootNode>

你好
请注意,ns1命名空间已附加到有效负载节点内的各个节点。在大多数情况下,这很好,但是我需要更早地进行声明,即在根节点上,因为这会使有效负载节点上的xsi:type定义无效,因为此时序列化程序不知道ns1名称空间,这会阻止正确的下游解析

我可以做些什么来强制更早地输出这个名称空间

已编辑的XSLT代码:

  <!-- Replace The ESBMessage node with the SOAP method -->
  <xsl:template match="s1:ESBMessage" mode="copy">
    <s0:SendESBMessage>
      <s0:msg>
        <xsl:apply-templates select="*" mode="copy"/>
      </s0:msg>
    </s0:SendESBMessage>
  </xsl:template>

  <!-- Generic Copy -->
  <xsl:template match="*" mode="copy">
    <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates mode="copy"/>
    </xsl:element>
  </xsl:template>

请注意,ns1名称空间已被删除 附加到各个节点 在有效负载节点内。在大多数情况下 这很好,不过我需要 该声明将在更早的时候发布, i、 e.在根节点上,因为它使 xsi:有效负载上的类型定义 节点无效,因为此时 序列化程序不知道 ns1命名空间,它阻止正确的 解析下游

如何强制使用此命名空间 要早一点输出吗

您可以做一些非常简单的事情:向我们展示您的代码

您关于“简单副本”丢失顶部节点的一个名称空间的声明,对于以下两个“简单副本”不正确:


当此转换应用于提供的XML文档时

<ns0:RootNode xmlns:ns0="namespace1" xmlns:ns1="namespace2" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
  <ns0:Payload xsi:type="ns1:SpecialPayload">
    <ns1:InnerNode>Hello</ns1:InnerNode>
  </ns0:Payload>
</ns0:RootNode>
<ns0:RootNode xmlns:ns0="namespace1" xmlns:ns1="namespace2" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
  <ns0:Payload xsi:type="ns1:SpecialPayload">
    <ns1:InnerNode>Hello</ns1:InnerNode>
  </ns0:Payload>
</ns0:RootNode>

你好
结果相同

<ns0:RootNode xmlns:ns0="namespace1" xmlns:ns1="namespace2" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
  <ns0:Payload xsi:type="ns1:SpecialPayload">
    <ns1:InnerNode>Hello</ns1:InnerNode>
  </ns0:Payload>
</ns0:RootNode>
<ns0:RootNode xmlns:ns0="namespace1" xmlns:ns1="namespace2" xmlns:xsi="http://www.w3.org/2001/XMLSchema">
  <ns0:Payload xsi:type="ns1:SpecialPayload">
    <ns1:InnerNode>Hello</ns1:InnerNode>
  </ns0:Payload>
</ns0:RootNode>

你好
这是第二个“简单副本”:

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

 <xsl:template match="/">
  <xsl:copy-of select="."/>
 </xsl:template>
</xsl:stylesheet>


结果再次与源XML文档相同

从我的回答中可以看出,您的问题缺少重要和必要的信息。请提供演示问题的最小代码示例。嗨,Dimitre,我已根据要求添加了一个代码示例。我只是在查看你的代码,看看我是否遗漏了什么。非常感谢。你的规则根本不是身份规则。您的意思是:在
copy
模式下匹配元素时,创建一个具有相同QName和相同命名空间URI的元素。添加属性child的副本作为内容,并在
copy
模式下将模板应用于节点child。因此,基本上,你正在剥离作用域名称空间,这是使用
xsl:copy
指令时不会发生的事情。Dimitre,我用你的复制代码替换了我的复制代码,它成功了。为什么*semantics与node()?@*?@themistry的功能不同:我没有看过你的代码就无法回答你的问题。我猜您正在复制元素节点,但不知何故,您没有复制名称空间节点。如果您使用的是
指令,则可能会发生这种情况。无论如何,你的代码显然不是“复制”转换。