2010-10-12 2 views
0

Я использую XSLT 1.0 для преобразования некоторого XML.Выход пространства имен с XSLT 1.0, вызывающий проблемы

Я не совсем уверен, что лучший способ объяснить это, поэтому будет использовать некоторые примеры.

Мой ввод 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 (предположим, 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> 
+0

Как вы можете видеть из моего ответа, на ваш вопрос отсутствует важная и необходимая информация. Пожалуйста, предоставьте минимальный пример кода, демонстрирующий проблему. –

+0

Привет, Dimitre, я добавил пример кода в соответствии с запросом. Я просто просматриваю ваш код, чтобы узнать, нет ли там чего-то. Спасибо! – themistry

+0

Ваше правило не является правилом идентификации вообще. Вы говорите: * При сопоставлении элемента в режиме 'copy', создайте элемент с тем же QName и тем же URI пространства имен. Добавьте в качестве содержимого копию дочерних элементов атрибута и примените шаблоны к дочерним элементам узла в режиме «copy». * Таким образом, в основном ваши дескрипторы в пространствах имен в области, что не происходит при использовании команды 'xsl: copy'. – 2010-10-12 12:25:45

ответ

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-документа источника.

+0

Dimitre, я заменил свой код для копирования вашим, и это сработало. Почему семантика * не делает то же самое, что и node()? @ *? – themistry

+0

@themistry: Я не могу ответить на ваш вопрос, не увидев ваш код. Я * предполагаю, что вы копируете узлы элементов, но каким-то образом вы не копируете узлы пространства имен. Это может произойти, если вы используете инструкцию ''. В любом случае, ваш не отображаемый код, очевидно, не является «копией». –

Смежные вопросы