3

標準の WSDL ファイル (XML で表現) があるとします。

<wsdl:definitions>

      <wsdl:types>
        ...
      </wsdl:types>

      <wsdl:message>
        ...
      </wsdl:message>

      <wsdl:portType name="countrySoap”&gt;
         <wsdl:operation name="GetCountryByCountryCode">
             <wsdl:documentation>Get country name by country code</wsdl:documentation>
             <wsdl:input message="tns:GetCountryByCountryCodeSoapIn" />
             <wsdl:output message="tns:GetCountryByCountryCodeSoapOut" />
         </wsdl:operation>
        <wsdl:operation name="GetISD">
            <wsdl:documentation>Get International Dialing Code </wsdl:documentation>
            <wsdl:input message="tns:GetISDSoapIn" />
            <wsdl:output message="tns:GetISDSoapOut" />
        </wsdl:operation>
        ...
      <wsdl:portType name="countrySoap”&gt;

  ....
</wsdl:definitions>

私がやりたいことは、すべてのメッセージの入力メッセージと出力メッセージを交換する簡単で効率的な方法を持つことです。

たとえば、私は欲しい:

         <wsdl:operation name="GetCountryByCountryCode">
             <wsdl:documentation>Get country name by country code</wsdl:documentation>
             <wsdl:input message="tns:GetCountryByCountryCodeSoapOut" />
             <wsdl:output message="tns:GetCountryByCountryCodeSoapIn" />
         </wsdl:operation>

私が使用している wsdl ファイルの例は、 http ://www.webservicex.net/country.asmx?WSDL にあります。

その他の注意事項:

  • これがより効率的であるように思われるため、私はおそらく XSLT ベースのソリューションを探しています。たとえば、私の現在のソリューションは Java ベースですが、思ったほど効率的ではないようです。
  • 解決策が任意の名前空間を無視できるとよいでしょう。たとえば、一部の wsdl ファイルwsdl:definitionsは 、wsdl:portType、 - として存在し、他のファイルは 、、などでwsdl:operationある可能性があります。definitionsportTypeoperation
4

2 に答える 2

1

名前空間のプレフィックスについて心配する必要はありません。名前空間の uri が一致する限り、特に問題にはなりません。

XSLT と XQuery はどちらもコンパクトなソリューションを提供します。ただし、出力のインデントは、XSLT で微調整するのが少し簡単かもしれません。

XSLT 2.0 ソリューションは次のとおりです。

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="wsdl:input">
        <xsl:copy>
            <xsl:apply-templates select="../wsdl:output/(@*|node())"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="wsdl:output">
        <xsl:copy>
            <xsl:apply-templates select="../wsdl:input/(@*|node())"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet> 

XQuery 1.0 ソリューションは次のとおりです。

xquery version "1.0";

declare namespace wsdl = "http://schemas.xmlsoap.org/wsdl/";

declare function local:recurse-nodes($nodes) {
    for $node in $nodes
    return typeswitch ($node)
        case $node as element (wsdl:input) return
            element { node-name($node) } { $node/../wsdl:output/local:recurse-nodes(@*|node()) }
        case $node as element (wsdl:output) return
            element { node-name($node) } { $node/../wsdl:input/local:recurse-nodes(@*|node()) }
        case $node as element () return
            element { node-name($node) } { $node/local:recurse-nodes(@*|node()) }
        case $node as document-node () return
            document { local:recurse-nodes($node/node()) }
        default return $node
};

local:recurse-nodes(doc("country.xml"))

チッ!

于 2012-07-17T16:44:36.120 に答える
1

この XSLT (1.0 と 2.0 の両方) 変換:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="some:wsdl">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="x:input/@message">
  <xsl:attribute name="message">
    <xsl:value-of select="../../x:output/@message"/>
  </xsl:attribute>
 </xsl:template>

 <xsl:template match="x:output/@message">
  <xsl:attribute name="message">
    <xsl:value-of select="../../x:input/@message"/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

次の XML ドキュメントに適用した場合(提供された、著しく不正な形式のものから取得):

<wsdl:definitions xmlns:wsdl="some:wsdl">

          <wsdl:types>
            ...
          </wsdl:types>

          <wsdl:message>
            ...
          </wsdl:message>

          <wsdl:portType name="countrySoap">
             <wsdl:operation name="GetCountryByCountryCode">
                 <wsdl:documentation>Get country name by country code</wsdl:documentation>
                 <wsdl:input message="tns:GetCountryByCountryCodeSoapIn" />
                 <wsdl:output message="tns:GetCountryByCountryCodeSoapOut" />
             </wsdl:operation>
            <wsdl:operation name="GetISD">
                <wsdl:documentation>Get International Dialing Code </wsdl:documentation>
                <wsdl:input message="tns:GetISDSoapIn" />
                <wsdl:output message="tns:GetISDSoapOut" />
            </wsdl:operation>
            ...
          </wsdl:portType>

      ....
</wsdl:definitions>

必要な正しい結果が生成されます

<wsdl:definitions xmlns:wsdl="some:wsdl">
   <wsdl:types>
            ...
          </wsdl:types>
   <wsdl:message>
            ...
          </wsdl:message>
   <wsdl:portType name="countrySoap">
      <wsdl:operation name="GetCountryByCountryCode">
         <wsdl:documentation>Get country name by country code</wsdl:documentation>
         <wsdl:input message="tns:GetCountryByCountryCodeSoapOut"/>
         <wsdl:output message="tns:GetCountryByCountryCodeSoapIn"/>
      </wsdl:operation>
      <wsdl:operation name="GetISD">
         <wsdl:documentation>Get International Dialing Code </wsdl:documentation>
         <wsdl:input message="tns:GetISDSoapOut"/>
         <wsdl:output message="tns:GetISDSoapIn"/>
      </wsdl:operation>
            ...
          </wsdl:portType>

      ....
</wsdl:definitions>
于 2012-07-18T02:36:39.177 に答える