使用xslt数组问题将Soap转换为jsonx

时间:2017-02-15 23:03:12

标签: arrays xml xslt soap

我正在学习xslt,我需要你的帮助。我必须将Soap消息转换为Jsonx,问题是在字段“body”中我需要所有子类型都是数组,除了最后一个必须是object类型的子节点,我有以下条目代码

<NS1:Envelope xmlns:NS1="http://schemas.xmlsoap.org/soap/envelope/">
   <NS1:Body>
      <NS2:Consulta xmlns:NS2="http://ejemplo.com/servicios">
         <header>
            <fechaHora>201612021719232416</fechaHora>
            <idioma>es_EC</idioma>
            <ip>192.168.1.23</ip>
         </header>
         <body>
            <productos>
               <tarjetas>
                  <tarjeta>
                     <numerotarjeta>123456789</numerotarjeta>
                     <tipo>MASTERCARD GOLD STN</tipo>
                     <moneda>USD</moneda>
                     <valorPagar>300</valorPagar>
                  </tarjeta>
                  <tarjeta>
                     <numerotarjeta>123456987</numerotarjeta>
                     <tipo>MASTERCARD GOLD STN</tipo>
                     <moneda>USD</moneda>
                     <valorPagar>15</valorPagar>
                  </tarjeta>
               </tarjetas>
               <libros>
                  <libro>
                     <id>123456789</id>
                     <nombre>Libro 1</nombre>
                  </libro>
               </libros>
               <revistas>
                  <revista>
                     <id>12</id>
                     <nombre>revista 1</nombre>
                  </revista>
                  <revista>
                     <id>122</id>
                     <nombre>revista 2</nombre>
                  </revista>
               </revistas>
            </productos>
         </body>
         <error>
            <error1>0</error1>
            <mensaje>OK</mensaje>
         </error>
      </NS2:Consulta>
   </NS1:Body>
</NS1:Envelope>

我正在使用以下xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>
    <!-- Array -->
    <xsl:template match="*[*[2]][name(*[1])=name(*[2])]">
        <json:object name="{name()}">
            <json:array name="{name(*[1])}">
                <xsl:apply-templates/>
            </json:array>
        </json:object>
    </xsl:template>
    <!-- Array member -->
    <xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | /">
        <json:object>
            <xsl:apply-templates/>
        </json:object>
    </xsl:template>
    <!-- Object -->
    <xsl:template match="*">
        <json:object name="{name()}">
            <xsl:apply-templates/>
        </json:object>
    </xsl:template>

    <!-- Object Body -->
    <xsl:template match="body[not(body)]">
        <json:array name="{name()}">
            <xsl:apply-templates/>
        </json:array>
    </xsl:template>
    <!-- String -->
    <xsl:template match="*[not(*)]">
        <json:string name="{name()}">
            <xsl:value-of select="."/>
        </json:string>
    </xsl:template>
</xsl:stylesheet>

通过应用xslt,我得到以下结果,其中我对book标签有问题,因为它是一个包含一个元素的数组,但它将它转换为一个对象,但它需要作为一个对象接收阵列

<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
   <json:object name="NS1:Envelope">
      <json:object name="NS1:Body">
         <json:object name="NS2:Consulta">
            <json:object name="header">
               <json:string name="fechaHora">201612021719232416</json:string>
               <json:string name="idioma">es_EC</json:string>
               <json:string name="ip">192.168.1.23</json:string>
            </json:object>
            <json:array name="body">
               <json:object name="productos">
                  <json:object name="tarjetas">
                     <json:array name="tarjeta">
                        <json:object>
                           <json:string name="numerotarjeta">123456789</json:string>
                           <json:string name="tipo">MASTERCARD GOLD STN</json:string>
                           <json:string name="moneda">USD</json:string>
                           <json:string name="valorPagar">300</json:string>
                        </json:object>
                        <json:object>
                           <json:string name="numerotarjeta">123456987</json:string>
                           <json:string name="tipo">MASTERCARD GOLD STN</json:string>
                           <json:string name="moneda">USD</json:string>
                           <json:string name="valorPagar">15</json:string>
                        </json:object>
                     </json:array>
                  </json:object>
                  <json:object name="libros">
                     <json:object name="libro">
                        <json:string name="id">123456789</json:string>
                        <json:string name="nombre">Libro 1</json:string>
                     </json:object>
                  </json:object>
                  <json:object name="revistas">
                     <json:array name="revista">
                        <json:object>
                           <json:string name="id">12</json:string>
                           <json:string name="nombre">revista 1</json:string>
                        </json:object>
                        <json:object>
                           <json:string name="id">122</json:string>
                           <json:string name="nombre">revista 2</json:string>
                        </json:object>
                     </json:array>
                  </json:object>
               </json:object>
            </json:array>
            <json:object name="error">
               <json:string name="error1">0</json:string>
               <json:string name="mensaje">OK</json:string>
            </json:object>
         </json:object>
      </json:object>
   </json:object>
</json:object>

但是应该收到以下内容,因为在任何地方,书籍,杂志都可以出现单个元素并将其转换为对象,但它是一个元素的数组。

<json:object name="libros">
    <json:array name="libro">
       <json:string name="id">123456789</json:string>
       <json:string name="nombre">Libro 1</json:string>
    </json:array>
</json:object>

1 个答案:

答案 0 :(得分:0)

在编写XSLT时,您是否知道元素的名称(例如libroslibro)?在这种情况下,您只需在模板中命名它们:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>
    <!-- Array -->
    <xsl:template match="*[*[2]][name(*[1])=name(*[2])] | libros[libro]">
        <json:object name="{name()}">
            <json:array name="{name(*[1])}">
                <xsl:apply-templates/>
            </json:array>
        </json:object>
    </xsl:template>
    <!-- Array member -->
    <xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | / | libro">
        <json:object>
            <xsl:apply-templates/>
        </json:object>
    </xsl:template>
    <!-- Object -->
    <xsl:template match="*">
        <json:object name="{name()}">
            <xsl:apply-templates/>
        </json:object>
    </xsl:template>

    <!-- Object Body -->
    <xsl:template match="body[not(body)]">
        <json:array name="{name()}">
            <xsl:apply-templates/>
        </json:array>
    </xsl:template>
    <!-- String -->
    <xsl:template match="*[not(*)]">
        <json:string name="{name()}">
            <xsl:value-of select="."/>
        </json:string>
    </xsl:template>
</xsl:stylesheet>

http://xsltransform.net/ncntCSX输出

              <json:object name="libros">
                 <json:array name="libro">
                    <json:object>
                       <json:string name="id">123456789</json:string>
                       <json:string name="nombre">Libro 1</json:string>
                    </json:object>
                 </json:array>
              </json:object>

这是一个建议尝试使用基于嵌套级别的通用方法(例如,具有grand子元素的body后代变为数组,它们的子数组成员):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>
    <!-- Array -->
    <xsl:template match="*[*[2]][name(*[1])=name(*[2])] | body//*[*/*]">
        <json:object name="{name()}">
            <json:array name="{name(*[1])}">
                <xsl:apply-templates/>
            </json:array>
        </json:object>
    </xsl:template>
    <!-- Array member -->
    <xsl:template match="*[parent::*[ name(*[1])=name(*[2]) ]] | / | body//*[*[not(*)]]">
        <json:object>
            <xsl:apply-templates/>
        </json:object>
    </xsl:template>
    <!-- Object -->
    <xsl:template match="*">
        <json:object name="{name()}">
            <xsl:apply-templates/>
        </json:object>
    </xsl:template>

    <!-- Object Body -->
    <xsl:template match="body[not(body)]">
        <json:array name="{name()}">
            <xsl:apply-templates/>
        </json:array>
    </xsl:template>
    <!-- String -->
    <xsl:template match="*[not(*)]">
        <json:string name="{name()}">
            <xsl:value-of select="."/>
        </json:string>
    </xsl:template>
</xsl:stylesheet>

http://xsltransform.net/ncntCSX/1联机,创建输出

                 <json:object name="libros">
                    <json:array name="libro">
                       <json:object>
                          <json:string name="id">123456789</json:string>
                          <json:string name="nombre">Libro 1</json:string>
                       </json:object>
                    </json:array>
                 </json:object>

表示libros,而没有在XSLT代码中提及该元素名称。