2017-02-15 34 views
0

我正尝试使用XSLT从给定输入XML生成XML输出。输出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> 

不正确的输出继电器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”',但是您使用仅在XSLT 2.0中可用的'xsl:namespace'。你实际上使用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

相关问题