Я использую XSLT 1.0 для преобразования XML.
Я не совсем уверен, как лучше объяснить это, поэтому приведу несколько примеров.
Мой входной XML содержит специализацию, использующую объявление типа xsi :. Смотрите узел полезной нагрузки:
<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>