Преобразуйте XML в другой с помощью XSL - PullRequest
0 голосов
/ 24 марта 2011

Мне нужно конвертировать этот 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>

в этот:

<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>

Я пытаюсь сделать это с помощью этого куска 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>

Но я не получаю никакого ответа:

<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:ActualizaPlanesRespuesta
                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>

Кто-нибудь может мне помочь?

Ответы [ 2 ]

1 голос
/ 24 марта 2011

Эта таблица стилей:

<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>

Выход:

<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>

Примечание : @exclude-result-prefixes не позволяет именованному пространству имен ns1 находиться в области действия для тех элементов, которые фактически его не использовали.

РЕДАКТИРОВАТЬ : Исправлено неправильное пространство имен.

0 голосов
/ 24 марта 2011
  1. Переменные XSLT являются как неизменяемыми, так и ограничены родительским элементом, поэтому следующее:

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

    ... каждый раз создает новую локальную переменную в цикле.Он не виден вне цикла.

  2. <xsl:param> используется для захвата аргументов, передаваемых в таблицы стилей и их шаблоны, поэтому <xsl:param name="{$etiqueta}"> в основном не имеет никакого эффекта.

  3. <xsl:with-param> используется для передачи аргументов в шаблоны.Чтобы вывести значение, используйте <xsl:value-of>.

Для сравнения: следующая таблица стилей:

<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>

Создает следующий вывод:

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...