我正在使用XSLT 1.0来转换某些XML。
我不太确定解释这个的最好方法,所以会使用一些例子。
我的输入XML包含一个使用xsi:type声明的特化。请参阅Payload节点:
<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发送它时(让我们假设一对一的副本),我得到以下输出
<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>
答案 0 :(得分:1)
注意ns1名称空间已经存在 附加到各个节点 在有效负载节点内。在多数情况下 这很好,但我需要 那个宣言要早点发生, 即在根节点上,因为它是 xsi:有效负载上的类型定义 节点无效,因为此时 序列化器不知道 ns1名称空间,阻止正确 解析下游。
如何强制使用此命名空间 要早一点输出?
您可以做一些非常简单的事情:向我们展示您的代码!
您的声明“简单副本”丢失了顶级节点的名称空间之一,对于以下两个“简单副本”不适用:
<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="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的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>
这是第二个“简单副本”:
<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文档相同。