Xml XSLT 1.0的命名空间输出导致问题
我正在使用XSLT1.0转换一些XML 我不太确定解释这一点的最佳方式,因此将使用一些示例 我的输入XML包含一个专门化,使用xsi:type声明。请参阅有效负载节点: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">
<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的功能不同:我没有看过你的代码就无法回答你的问题。我猜您正在复制元素节点,但不知何故,您没有复制名称空间节点。如果您使用的是
指令,则可能会发生这种情况。无论如何,你的代码显然不是“复制”转换。