2016-05-30 5 views
1

Я пытаюсь скопировать сообщение с мылом в пользовательский xml (удаление пространства имен мыла из Envelope, Header, Body и удаление префикса пространства имен из элемента ResponseHeader, все прекрасно ожидать, что одно пространство имен xapns: примесное пространство, входящее в ResponseHeader . и ResponseData элементыУдалить xmlns soap-атрибут из xml с помощью xslt

Вход:

<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns="http:test/201/2" 
xmlns:m0="http:test/201/3" 
xmlns:ns0="http:test/201/4" 
xmlns:ns2="http:test/201/5" 
xmlns:ns1="http:test/201/6" 
xmlns:ns3="http:test/201/7" 
xmlns:ns6="http:test/201/8" 
xmlns:ns4="http:test/201/9" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
> 
<soap:Header> 
<ns0:ResponseHeader> 
<ns:Env>Dev</ns:Env> 
<ns:Version>1</ns:Version> 
<ns:Server> 
<ns:Name>NAME</ns:Name> 
</ns0:ResponseHeader> 
</soap:Header> 
<soap:Body> 
<ns2:ResponseData> 
<ns2:Employee /> 
<ns2:MessageList> 
<ns2:Message> 
<ns4:Type>new</ns4:Type> 
<ns4:Code>1</ns4:Code> 
<ns4:Source>contract</ns4:Source> 
<ns4:Description>new hire</ns4:Description> 
</ns2:Message> 
</ns2:Employee> 
</ns2:ResponseData> 
</soap:Body> 
</soap:Envelope> 

Ожидаемый результат:

<Envelope 
xmlns:ns="http:test/201/2" 
xmlns:m0="http:test/201/3" 
xmlns:ns0="http:test/201/4" 
xmlns:ns2="http:test/201/5" 
xmlns:ns1="http:test/201/6" 
xmlns:ns3="http:test/201/7" 
xmlns:ns6="http:test/201/8" 
xmlns:ns4="http:test/201/9" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
> 
<Header> 
<ResponseHeader> 
<ns:Env>Dev</ns:Env> 
<ns:Version>1</ns:Version> 
<ns:Server> 
<ns:Name>NAME</ns:Name> 
</ResponseHeader> 
</Header> 
<Body> 
<ns2:ResponseData> 
<ns2:Employee /> 
<ns2:MessageList> 
<ns2:Message> 
<ns4:Type>new</ns4:Type> 
<ns4:Code>1</ns4:Code> 
<ns4:Source>contract</ns4:Source> 
<ns4:Description>new hire</ns4:Description> 
</ns2:Message> 
</ns2:Employee> 
</ns2:ResponseData> 
</Body> 
</Envelope> 

Мой XSLT:

<xsl:stylesheet version="2.0" extension-element-prefixes="dp" exclude-result-prefixes="soap ns3 snss ns0 ns1 ns4 #default" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns="http:test/201/2" 
xmlns:m0="http:test/201/3" 
xmlns:ns0="http:test/201/4" 
xmlns:ns2="http:test/201/5" 
xmlns:ns1="http:test/201/6" 
xmlns:ns3="http:test/201/7" 
xmlns:ns6="http:test/201/8" 
xmlns:ns4="http:test/201/9" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
> 
    <xsl:output method="xml" version="1.0" indent="no"/> 
    <xsl:template match="node()|@*" exclude-result-prefixes="#all"> 

    <xsl:copy> 
<xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="soap:*" exclude-result-prefixes="#all"> 
    <xsl:element name="{local-name()}"> 
    <xsl:copy-of select="namespace::*[not(. = namespace-uri(..))]"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 
    <xsl:template match="tns:ResponseData" exclude-result-prefixes="#all"> 
<ResponseHeader> 
    <xsl:copy-of select="namespace::*[not(. = namespace-uri(..))]"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </ResponseHeader> 
</xsl:template> 

</xsl:stylesheet> 

Получение выход:

<Envelope 

xmlns:ns="http:test/201/2" 
xmlns:m0="http:test/201/3" 
xmlns:ns0="http:test/201/4" 
xmlns:ns2="http:test/201/5" 
xmlns:ns1="http:test/201/6" 
xmlns:ns3="http:test/201/7" 
xmlns:ns6="http:test/201/8" 
xmlns:ns4="http:test/201/9" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
> 
<Header> 
<ResponseHeader xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
<ns:Env>Dev</ns:Env> 
<ns:Version>1</ns:Version> 
<ns:Server> 
<ns:Name>NAME</ns:Name> 
</ResponseHeader> 
</Header> 
<Body> 
<ns2:ResponseData xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
<ns2:Employee /> 
<ns2:MessageList> 
<ns2:Message> 
<ns4:Type>new</ns4:Type> 
<ns4:Code>1</ns4:Code> 
<ns4:Source>contract</ns4:Source> 
<ns4:Description>new hire</ns4:Description> 
</ns2:Message> 
</ns2:Employee> 
</ns2:ResponseData> 
</Body> 
</Envelope> 

Пожалуйста, помогите, как избавиться, если XMLNS: атрибут мыло?

+0

Пожалуйста, разместите ** хорошо сформированный ** вход и выход. –

ответ

0

Это решение работает во всех версиях XSLT: 1,0, 2,0 и 3,0 (и также намного короче):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:x="http:test/201/4"> 
<xsl:output omit-xml-declaration="yes"/> 

    <xsl:template match="*" priority="1"> 
    <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
     <xsl:copy-of select="namespace::*[not(name()='soap')]"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="soap:* | x:ResponseHeader" priority="2"> 
    <xsl:element name="{local-name()}"> 
     <xsl:copy-of select="namespace::*[not(name()='soap')]"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

Когда это преобразование применяется на документе XML (хорошо сформированные):

<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns="http:test/201/2" 
xmlns:m0="http:test/201/3" 
xmlns:ns0="http:test/201/4" 
xmlns:ns2="http:test/201/5" 
xmlns:ns1="http:test/201/6" 
xmlns:ns3="http:test/201/7" 
xmlns:ns6="http:test/201/8" 
xmlns:ns4="http:test/201/9" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <soap:Header> 
     <ns0:ResponseHeader> 
     <ns:Env>Dev</ns:Env> 
     <ns:Version>1</ns:Version> 
     <ns:Server/> 
     <ns:Name>NAME</ns:Name> 
     </ns0:ResponseHeader> 
    </soap:Header> 
    <soap:Body> 
     <ns2:ResponseData> 
     <ns2:Employee> 
      <ns2:MessageList> 
       <ns2:Message> 
        <ns4:Type>new</ns4:Type> 
        <ns4:Code>1</ns4:Code> 
        <ns4:Source>contract</ns4:Source> 
        <ns4:Description>new hire</ns4:Description> 
       </ns2:Message> 
      </ns2:MessageList> 
     </ns2:Employee> 
     </ns2:ResponseData> 
    </soap:Body> 
</soap:Envelope> 

разыскиваемый, правильный результат получается:

<Envelope xmlns:ns="http:test/201/2" xmlns:m0="http:test/201/3" 
      xmlns:ns0="http:test/201/4" xmlns:ns2="http:test/201/5" 
      xmlns:ns1="http:test/201/6" xmlns:ns3="http:test/201/7" 
      xmlns:ns6="http:test/201/8" xmlns:ns4="http:test/201/9" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Header> 
     <ResponseHeader> 
      <ns:Env>Dev</ns:Env> 
      <ns:Version>1</ns:Version> 
      <ns:Server/> 
      <ns:Name>NAME</ns:Name> 
     </ResponseHeader> 
    </Header> 
    <Body> 
     <ns2:ResponseData> 
      <ns2:Employee> 
       <ns2:MessageList> 
        <ns2:Message> 
         <ns4:Type>new</ns4:Type> 
         <ns4:Code>1</ns4:Code> 
         <ns4:Source>contract</ns4:Source> 
         <ns4:Description>new hire</ns4:Description> 
        </ns2:Message> 
       </ns2:MessageList> 
      </ns2:Employee> 
     </ns2:ResponseData> 
    </Body> 
</Envelope> 
+1

'* [local-name() = 'ResponseHeader']' = плохая практика. Пространства имен следует использовать, а не игнорировать. –

+0

@ michael.hor257k, Это, как правило, разумная обратная связь. Я не уверен, что 'ResponseHeader' всегда будет в этом пространстве имен, хотя - вот почему я буквально выполнил требование о том, чтобы результирующий элемент не содержал пространства имен. Другими словами, это выражение имеет свои собственные прецеденты, и я считаю, что текущая проблема представляет такой случай использования. Независимо от того, что я считаю, что отражение ваших отзывов уменьшит общность решения, я сделал именно это. Любые другие комментарии? –

0

Ни ваш ввод, ни ваш вывод не являются хорошо сформированным XML. И ваш «XSLT» - это даже не XSLT-документ!

AFAICT, что вы хотите сделать:

XSLT 2,0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns0="http:test/201/4" 
exclude-result-prefixes="soap"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="*"> 
    <xsl:copy copy-namespaces="no"> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="soap:* | ns0:ResponseHeader"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="/soap:Envelope"> 
    <Envelope> 
     <xsl:copy-of select="namespace::*"/> 
     <xsl:apply-templates/> 
    </Envelope> 
</xsl:template> 

</xsl:stylesheet> 

Применяя это к следующему хорошо сформированным ввод XML:

<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns="http:test/201/2" 
xmlns:m0="http:test/201/3" 
xmlns:ns0="http:test/201/4" 
xmlns:ns2="http:test/201/5" 
xmlns:ns1="http:test/201/6" 
xmlns:ns3="http:test/201/7" 
xmlns:ns6="http:test/201/8" 
xmlns:ns4="http:test/201/9" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <soap:Header> 
     <ns0:ResponseHeader> 
     <ns:Env>Dev</ns:Env> 
     <ns:Version>1</ns:Version> 
     <ns:Server/> 
     <ns:Name>NAME</ns:Name> 
     </ns0:ResponseHeader> 
    </soap:Header> 
    <soap:Body> 
     <ns2:ResponseData> 
     <ns2:Employee> 
      <ns2:MessageList> 
       <ns2:Message> 
        <ns4:Type>new</ns4:Type> 
        <ns4:Code>1</ns4:Code> 
        <ns4:Source>contract</ns4:Source> 
        <ns4:Description>new hire</ns4:Description> 
       </ns2:Message> 
      </ns2:MessageList> 
     </ns2:Employee> 
     </ns2:ResponseData> 
    </soap:Body> 
</soap:Envelope> 

вернется:

<?xml version="1.0" encoding="UTF-8"?> 
<Envelope xmlns:ns0="http:test/201/4" xmlns:ns="http:test/201/2" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:m0="http:test/201/3" 
      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
      xmlns:ns2="http:test/201/5" 
      xmlns:ns1="http:test/201/6" 
      xmlns:ns3="http:test/201/7" 
      xmlns:ns6="http:test/201/8" 
      xmlns:ns4="http:test/201/9"> 
    <Header> 
     <ResponseHeader> 
     <ns:Env>Dev</ns:Env> 
     <ns:Version>1</ns:Version> 
     <ns:Server/> 
     <ns:Name>NAME</ns:Name> 
     </ResponseHeader> 
    </Header> 
    <Body> 
     <ns2:ResponseData> 
     <ns2:Employee> 
      <ns2:MessageList> 
       <ns2:Message> 
        <ns4:Type>new</ns4:Type> 
        <ns4:Code>1</ns4:Code> 
        <ns4:Source>contract</ns4:Source> 
        <ns4:Description>new hire</ns4:Description> 
       </ns2:Message> 
      </ns2:MessageList> 
     </ns2:Employee> 
     </ns2:ResponseData> 
    </Body> 
</Envelope> 

Обратите внимание, что последний шаблон, соответствующий /soap:Envelope, включен в стоимость по чисто косметическим причинам. Если вы его удалите, результатом будет:

<?xml version="1.0" encoding="UTF-8"?> 
<Envelope> 
    <Header> 
     <ResponseHeader> 
     <ns:Env xmlns:ns="http:test/201/2">Dev</ns:Env> 
     <ns:Version xmlns:ns="http:test/201/2">1</ns:Version> 
     <ns:Server xmlns:ns="http:test/201/2"/> 
     <ns:Name xmlns:ns="http:test/201/2">NAME</ns:Name> 
     </ResponseHeader> 
    </Header> 
    <Body> 
     <ns2:ResponseData xmlns:ns2="http:test/201/5"> 
     <ns2:Employee> 
      <ns2:MessageList> 
       <ns2:Message> 
        <ns4:Type xmlns:ns4="http:test/201/9">new</ns4:Type> 
        <ns4:Code xmlns:ns4="http:test/201/9">1</ns4:Code> 
        <ns4:Source xmlns:ns4="http:test/201/9">contract</ns4:Source> 
        <ns4:Description xmlns:ns4="http:test/201/9">new hire</ns4:Description> 
       </ns2:Message> 
      </ns2:MessageList> 
     </ns2:Employee> 
     </ns2:ResponseData> 
    </Body> 
</Envelope> 

, который семантически идентичен предыдущему результату.

+0

Спасибо, оба. Это действительно поможет. Я внес небольшой вклад в ввод. Ожидая того же выхода: – Mike

+0

Мой начальный вопрос ответил. Я сделал небольшие изменения для ввода и ожидания ответа. – Mike

+0

@Mike Я не вижу никаких изменений. В любом случае, если это небольшое изменение, вы должны быть в состоянии сделать настройку самостоятельно. В противном случае задайте новый вопрос. –

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