2017-02-15 17 views
0

Я пытаюсь сгенерировать выход XML из данного входного XML с помощью XSLT. На выходе xml будут добавлены разные пространства имен на разных уровнях дерева xml. Я использую оси XPath (потомки), чтобы добавить пространство имен к дочерним узлам, но выводит узлы grandchildern рядом с дочерним узлом.Ошибка при добавлении нескольких пространств имен в вывод XML

Мой Входной XML

<?xml version="1.0" encoding="UTF-8"?> 
<request> 
    <header> 
     <sender> 
     <User>ServiceUser</User> 
     <userid type="UserId">ServiceUserid</userid> 
     </sender> 
     <receiver> 
     <Country>IND</Country> 
     </receiver>  
     <id>123456</id> 
    </header> 
    <Address type="physical"> 
     <subaddress> 
     <number>2</number> 
     </subaddress> 
     <doornumber>13</doornumber> 
     <streetName>mgr road</streetName> 
     <locality>cityname</locality> 
     <postalcode>612453</postalcode> 
    </Address> 
</request> 

Мой XSLT

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aa="xyz.com/aa" 
    xmlns:bb="xyz.com/bb" xmlns:addr="xyz.com/addr" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    version="1.0"> 

     <xsl:output encoding="utf-8" indent="yes" method="xml" omit-xml-declaration="yes" /> 
     <xsl:template match="/"> 
      <soapenv:Envelope> 
      <soapenv:Header /> 
      <soapenv:Body> 
       <xsl:copy> 
        <xsl:apply-templates select="node()|@*" /> 
       </xsl:copy> 
      </soapenv:Body> 
      </soapenv:Envelope> 
     </xsl:template> 
     <!-- template to copy attributes --> 
     <xsl:template match="@*"> 
      <xsl:attribute name="{local-name()}"> 
      <xsl:value-of select="." /> 
      </xsl:attribute> 
     </xsl:template> 
     <!-- apply the 'event' namespace to the top node and its descendants --> 
     <xsl:template match="//*"> 
      <xsl:choose> 
      <!--Add namespace for the root element--> 
      <xsl:when test="local-name() = 'request'"> 
       <xsl:element name="aa:{local-name()}"> 
        <xsl:namespace name="aa" select="'xyz.com/aa'" /> 
        <xsl:copy-of select="namespace::*" /> 
        <xsl:apply-templates select="node()|@*" /> 
       </xsl:element> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:element name="{local-name()}"> 
        <xsl:copy-of select="*" /> 
       </xsl:element> 
      </xsl:otherwise> 
      </xsl:choose> 
     </xsl:template> 
     <!-- template to copy the rest of the nodes --> 
     <xsl:template match="*[ancestor-or-self::header]"> 
      <xsl:element name="bb:{name()}"> 
      <xsl:apply-templates select="node()|@*" /> 
      </xsl:element> 
     </xsl:template> 
     <xsl:template match="//Address"> 
      <xsl:element name="aa:{local-name()}"> 
      <xsl:for-each select="//Address/descendant::*"> 
       <xsl:element name="addr:{name()}"> 
        <xsl:apply-templates select="node()|@*" /> 
       </xsl:element> 
      </xsl:for-each> 
      </xsl:element> 
     </xsl:template> 
     <xsl:template match="comment() | processing-instruction()"> 
      <xsl:copy /> 
     </xsl:template> 
    </xsl:stylesheet> 

Обязательный выход XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:aa="xyz.com/request" xmlns:bb="xyz.com/header" 
xmlns:addr="xyz.com/address"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <aa:request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
      <bb:header> 
       <bb:sender> 
        <bb:User>ServiceUser</bb:User> 
        <bb:userid type="UserId">ServiceUserid</bb:userid> 
       </bb:sender> 
       <bb:receiver> 
        <bb:Country>IND</bb:Country> 
       </bb:receiver>    
       <bb:id>123456</bb:id> 
      </bb:header> 
      <aa:Address type="physical"> 
       <addr:subaddress> 
        <number>2</number> 
       </addr:subaddress> 
       <addr:doornumber>13</addr:doornumber> 
       <addr:streetName>mgr road</addr:streetName> 
       <addr:locality>cityname</addr:locality> 
       <addr:postalcode>612453</addr:postalcode> 
      </aa:Address> 
     </aa:request> 
    </soapenv:Body> 
</soapenv:Envelope> 

Некорректное Ouput XML:

<soapenv:Envelope xmlns:aa="xyz.com/aa" 
    xmlns:bb="xyz.com/bb" xmlns:addr="xyz.com/addr" 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
     <soapenv:Header/> 
     <soapenv:Body> 
      <aa:request> 
      <bb:header> 
       <!-- Correct output here --> 
      </bb:header> 
      <aa:Address> 
       <addr:subaddress> 
        <number/> <!-- this element is empty -should have value "2" --> 
       </addr:subaddress> 
       <addr:number>2</addr:number> <!-- new element added which is incorrect--> 
       <addr:doornumber>13</addr:doornumber> 
       <addr:streetName>mgr road</addr:streetName> 
       <addr:locality>cityname</addr:locality> 
       <addr:postalcode>612453</addr:postalcode> 
      </aa:Address> 
      </aa:request> 
     </soapenv:Body> 
    </soapenv:Envelope> 

Можете ли вы кто-то пожалуйста, помогите мне с правильным XSLT для получения ожидаемого результата. Заранее спасибо.

+0

Ваша таблица стилей помечена как 'version =" 1.0 ", но вы используете' xsl: namespace', которая доступна только в XSLT 2.0. Вы действительно используете процессор XSLT 2.0? –

+0

Также не должно быть '' '' '' '? –

+0

@michael, это должно быть без пространства имен. Этот xslt будет обрабатываться сторонним инструментом, который поддерживает как XSLT 1.0, так и 2.0. – jack

ответ

1

Почему ты не можешь просто:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:bb="xyz.com/header" 
xmlns:aa="xyz.com/request" 
xmlns:addr="xyz.com/address"> 
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="/request"> 
    <soapenv:Envelope > 
     <soapenv:Header/> 
     <soapenv:Body> 
      <aa:request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
       <xsl:apply-templates/> 
      </aa:request> 
     </soapenv:Body> 
    </soapenv:Envelope> 
</xsl:template> 

<xsl:template match="*[ancestor-or-self::header]"> 
    <xsl:element name="bb:{local-name()}"> 
     <xsl:apply-templates select="node()|@*" /> 
    </xsl:element> 
</xsl:template> 

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

<xsl:template match="*[parent::Address]"> 
    <xsl:element name="addr:{local-name()}"> 
     <xsl:apply-templates select="node()|@*" /> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

Примечание: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" декларация не используется, и поэтому совершенно излишним.

+0

спасибо за ваш ответ. Я новичок в XSLT и все еще изучаю его. Попробуй свой XSLT. – jack

+0

он работает, спасибо много майкл .... – jack

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

  • Нет связанных вопросов^_^