使用xsl将xml转换为另一个xml

时间:2011-03-24 13:44:05

标签: xml xslt transform

我需要转换这个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 个答案:

答案 0 :(得分:1)

此样式表:

<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命名的命名空间在那些实际上没有使用它的元素的范围内。

编辑:修复了错误的命名空间。

答案 1 :(得分:0)

  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>

  4. 为了比较,以下样式表:

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