开发者

Transform a xml into another with xsl

开发者 https://www.devze.com 2023-02-19 17:28 出处:网络
I need to convert this xml: <SOAP-ENV:Envelope SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"

I need to convert this xml:

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns1="http://85.152.52.210/moodle/webservice/soap/simpleserver.php//"
    xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <SOAP-ENV:Body>
        <ns1:moodle_course_update_plansResponse>
            <return SOAP-ENC:arrayType="ns2:Map[1]" xsi:type="SOAP-ENC:Array">
                <item xsi:type="ns2:Map">
                    <item>
                        <key xsi:type="xsd:string">PlanId</key>
                        <value xsi:type="xsd:string" />
                    </item>
                    <item>
                        <key xsi:type="xsd:string">Operacion</key>
                        <value xsi:type="xsd:string">D</value>
                    </item>
                    <item>
                        <key xsi:type="xsd:string">OpDesc</key>
                        <value xsi:type="xsd:string">Desconocida</value>
                    </item>
                    <item>
                        <key xsi:type="xsd:string">ErrorId</key>
                        <value xsi:type="xsd:string">01</value>
                    </item>
                    <item>
                        <key xsi:type="xsd:string">ErrorDesc</key>
                        <value xsi:type="xsd:string">Faltas datos de entrada. Es necesario
                            especificar el identificador del plan en GesforIaap</value>
                    </item>
                </item>
            </return>
        </ns1:moodle_course_update_plansResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

into this one:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <ActualizaPlanesResponse xmlns="http://www.princast.es/iaap/teleformacion/1.0/kedrosWS/kedrosWS.wsdl">
         <ns1:ActualizaPlanesRespuesta xmlns:ns1="http://princast.es/teleformacion/1.0/kedrosWS/kedrosWS.xsd">
            <ns1:listaErroresPlanes>
               <ns1:Error>
                  <ns1:PlanId>Identificador de plan desconocido</ns1:PlanId>
                  <ns1:Operacion>
                     <ns1:Codigo>D</ns1:Codigo>
                     <ns1:Descripcion>Desconocida</ns1:Descripcion>
                  </ns1:Operacion>
                  <ns1:Error>
                     <ns1:Codigo>01</ns1:Codigo>
                     <ns1:Descripcion>Faltan datos de entrada. Es necesario especificar el identificador del plan en GesforIaap.</ns1:Descripcion>
                  </ns1:Error>
               </ns1:Error>
            </ns1:listaErroresPlanes>
         </ns1:ActualizaPlanesRespuesta>
      </ActualizaPlanesResponse>
   </soapenv:Body>
</soapenv:Envelope>

I'm trying to do that with this piece of xsl:

<xsl:template match="ns1:moodle_course_update_plansResponse">
         <ActualizaPlanesResponse xmlns="http://www.princast.es/iaap/teleformacion/1.0/kedrosWS/kedrosWS.wsdl">
         <ns1:ActualizaPlanesRespuesta xmlns:ns1="http://princast.es/teleformacion/1.0/kedrosWS/kedrosWS.xsd">
            <xsl:choose>
                <xsl:when test="SOAP-ENC:arrayType=xsd:ur-type[0]">
                    <ns1:listaErroresPlanes/>
                </xsl:when>
                <xsl:otherwise>
                <xsl:for-each match="item/item">
                    <xsl:variable name="etiqueta">
                        <xsl:value-of select="key" />
                    </xsl:variable>

                    <xsl:param name="{$etiqueta}">
                        <xsl:value-of select="value" />
                    </xsl:param>

                </xsl:for-each>
                <ns1:Error>
                  <ns1:PlanId> <xsl:with-param name="PlanId" /></ns1:PlanId>
                  <ns1:Operacion>
                     <ns1:Codigo><xsl:with-param name="OperacionId" /></ns1:Codigo>
                     <ns1:Descripcion><xsl:with-param name="OperacionDesc" /></ns1:Descripcion>
                  </ns1:Operacion>
                  <ns1:Error>
                     <ns1:Codigo><xsl:with-param name="ErrorId" /></ns1:Codigo>
                     <ns1:Descripcion><xsl:with-param name="ErrorDesc" /></ns1:Descripcion>
                  </ns1:Error>
                 </ns1:Error>
                </xsl:otherwise>
            </xsl:choose>
         </ns1:ActualizaPlanesRespuesta>
      </ActualizaPlanesResponse>
    </xsl:template>

But I don't get any answer:

<ActualizaPlanesResponse
            xmlns="http://www.princast.es/iaap/teleformacion/1.0/kedrosWS/kedrosWS.wsdl"
            xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://xml.apache.org/xml-soap"
            xmlns:ns1="http://85.152.52.210/moodle/webservice/soap/simpleserver.php//"
            xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ns1:ActualizaPlanes开发者_如何学运维Respuesta
                xmlns:ns1="http://princast.es/teleformacion/1.0/kedrosWS/kedrosWS.xsd">
                <ns1:Error>
                    <ns1:PlanId />
                    <ns1:Operacion>
                        <ns1:Codigo />
                        <ns1:Descripcion />
                    </ns1:Operacion>
                    <ns1:Error>
                        <ns1:Codigo />
                        <ns1:Descripcion />
                    </ns1:Error>
                </ns1:Error>
            </ns1:ActualizaPlanesRespuesta>
        </ActualizaPlanesResponse>

Can anyone help me?


This stylesheet:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ns1="http://princast.es/teleformacion/1.0/kedrosWS/kedrosWS.xsd"
 xmlns="http://www.princast.es/iaap/teleformacion/1.0/kedrosWS/kedrosWS.wsdl"
 exclude-result-prefixes="ns1">
    <xsl:output encoding="utf-8"/>
    <xsl:template match="/">
        <soapenv:Envelope xmlns="">
            <soapenv:Body>
                <ActualizaPlanesResponse xmlns=
        "http://www.princast.es/iaap/teleformacion/1.0/kedrosWS/kedrosWS.wsdl">
                    <ns1:ActualizaPlanesRespuesta>
                        <xsl:apply-templates/>
                    </ns1:ActualizaPlanesRespuesta>
                </ActualizaPlanesResponse>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>
    <xsl:template match="item[item/key='ErrorId']"/>
    <xsl:template match="item[item/key='ErrorId'][1]" priority="1">
        <ns1:listaErroresPlanes>
            <xsl:apply-templates select="../item[item/key='ErrorId']" 
                                 mode="error"/>
        </ns1:listaErroresPlanes>
    </xsl:template>
    <xsl:template match="item" mode="error">
        <ns1:Error>
            <ns1:PlanId>Identificador de plan desconocido</ns1:PlanId>
            <ns1:Operacion>
                <ns1:Codigo>
                    <xsl:value-of select="item[key='Operacion']/value"/>
                </ns1:Codigo>
                <ns1:Descripcion>
                    <xsl:value-of select="item[key='OpDesc']/value"/>
                </ns1:Descripcion>
            </ns1:Operacion>
            <ns1:Error>
                <ns1:Codigo>
                    <xsl:value-of select="item[key='ErrorId']/value"/>
                </ns1:Codigo>
                <ns1:Descripcion>
                    <xsl:value-of select="item[key='ErrorDesc']/value"/>
                </ns1:Descripcion>
            </ns1:Error>
        </ns1:Error>
    </xsl:template>
</xsl:stylesheet>

Output:

<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ActualizaPlanesResponse
         xmlns="http://www.princast.es/iaap/teleformacion/1.0/kedrosWS/kedrosWS.wsdl">
            <ns1:ActualizaPlanesRespuesta
             xmlns:ns1="http://princast.es/teleformacion/1.0/kedrosWS/kedrosWS.xsd">
                <ns1:listaErroresPlanes>
                    <ns1:Error>
                        <ns1:PlanId>Identificador de plan desconocido</ns1:PlanId>
                        <ns1:Operacion>
                            <ns1:Codigo>D</ns1:Codigo>
                            <ns1:Descripcion>Desconocida</ns1:Descripcion>
                        </ns1:Operacion>
                        <ns1:Error>
                            <ns1:Codigo>01</ns1:Codigo>
                            <ns1:Descripcion>Faltas datos de entrada. Es necesario
                              especificar el identificador del plan en GesforIaap.
                            </ns1:Descripcion>
                        </ns1:Error>
                    </ns1:Error>
                </ns1:listaErroresPlanes>
            </ns1:ActualizaPlanesRespuesta>
        </ActualizaPlanesResponse>
    </soapenv:Body>
</soapenv:Envelope>

Note: @exclude-result-prefixes prevents ns1 named namespace to be in scope for those elements that did not actually use it.

EDIT: Wrong namespace fixed.


  1. XSLT variables are both immutable and scoped to their parent element, so the following:

    <xsl:for-each match="item/item">
        <xsl:variable name="etiqueta">
            <xsl:value-of select="key" />
         </xsl:variable>
    </xsl:for-each>
    

    ...creates a new, local variable each time through the loop. It's not visible outside the loop.

  2. <xsl:param> is used to capture arguments passed to stylesheets and their templates, so <xsl:param name="{$etiqueta}"> is having basically no effect.

  3. <xsl:with-param> is used to pass arguments to templates. To output a value, use <xsl:value-of>.

For comparison, the following stylesheet:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:ns1="http://princast.es/teleformacion/1.0/kedrosWS/kedrosWS.xsd"
    xmlns:ns2="http://www.princast.es/iaap/teleformacion/1.0/kedrosWS/kedrosWS.wsdl"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:template match="/">
        <soapenv:Envelope>
            <soapenv:Body>
                <ns2:ActualizaPlanesResponse>
                    <ns1:ActualizaPlanesRespuesta>
                        <ns1:listaErroresPlanes>
                            <xsl:apply-templates />
                        </ns1:listaErroresPlanes>
                    </ns1:ActualizaPlanesRespuesta>
                </ns2:ActualizaPlanesResponse>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>
    <!-- suppress unwanted return types -->
    <xsl:template match="return[@soapenc:arrayType='xsd:ur-type[0]']" />
    <xsl:template match="item[@xsi:type='ns2:Map']">
        <ns1:Error>
            <ns1:PlanId>Identificador de plan desconocido</ns1:PlanId>
            <ns1:Operacion>
                <ns1:Codigo>
                    <xsl:value-of select="item[key='Operacion']/value" />
                </ns1:Codigo>
                <ns1:Descripcion>
                    <xsl:value-of select="item[key='OpDesc']/value" />
                </ns1:Descripcion>
            </ns1:Operacion>
            <ns1:Error>
                <ns1:Codigo>
                    <xsl:value-of select="item[key='ErrorId']/value" />
                </ns1:Codigo>
                <ns1:Descripcion>
                    <xsl:value-of select="item[key='ErrorDesc']/value" />
                </ns1:Descripcion>
            </ns1:Error>
        </ns1:Error>
    </xsl:template>
</xsl:stylesheet>

Produces the following output:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <ns2:ActualizaPlanesResponse
            xmlns:ns2="http://www.princast.es/iaap/teleformacion/1.0/kedrosWS/kedrosWS.wsdl">
            <ns1:ActualizaPlanesRespuesta
                xmlns:ns1="http://princast.es/teleformacion/1.0/kedrosWS/kedrosWS.xsd">
                <ns1:listaErroresPlanes>
                    <ns1:Error>
                        <ns1:PlanId>Identificador de plan desconocido</ns1:PlanId>
                        <ns1:Operacion>
                            <ns1:Codigo>D</ns1:Codigo>
                            <ns1:Descripcion>Desconocida</ns1:Descripcion>
                        </ns1:Operacion>
                        <ns1:Error>
                            <ns1:Codigo>01</ns1:Codigo>
                            <ns1:Descripcion>Faltas datos de entrada. Es necesario
                                especificar el identificador del plan en GesforIaap
                            </ns1:Descripcion>
                        </ns1:Error>
                    </ns1:Error>
                </ns1:listaErroresPlanes>
            </ns1:ActualizaPlanesRespuesta>
        </ns2:ActualizaPlanesResponse>
    </soapenv:Body>
</soapenv:Envelope>
0

精彩评论

暂无评论...
验证码 换一张
取 消