【问题标题】:Transform a xml into another with xsl使用 xsl 将 xml 转换为另一个
【发布时间】:2011-03-24 13:44:04
【问题描述】:

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

谁能帮帮我?

【问题讨论】:

    标签: xml xslt transform


    【解决方案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 命名空间位于那些实际上没有使用它的元素的范围内。

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

    【讨论】:

    • 请注意,ActualizaPlanesResponseActualizaPlanesRespuesta 在同一个命名空间中,但我认为它们不应该如此。
    • @lwburk:谢谢。现在它已经修复了。
    【解决方案2】:
    1. XSLT 变量都是不可变的,并且作用域仅限于它们的父元素,因此如下:

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

      ...每次通过循环创建一个新的局部变量。它在循环之外是不可见的。

    2. &lt;xsl:param&gt; 用于捕获传递给样式表及其模板的参数,因此&lt;xsl:param name="{$etiqueta}"&gt; 基本上没有任何作用。

    3. &lt;xsl:with-param&gt; 用于将参数传递给模板。要输出一个值,请使用&lt;xsl:value-of&gt;

    为了比较,下面的样式表:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-14
      • 2012-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 2022-01-07
      • 1970-01-01
      相关资源
      最近更新 更多