0

XmlSlurperがどうやら結果に取り組んでいない理由がわかりません。

import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*


def String WSDL_URL = ...
def http = new HTTPBuilder( WSDL_URL , ContentType.XML )
String soapEnvelope = 
          """<?xml version="1.0" encoding="utf-8"?>
        <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                         xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
          <soap12:Body>
            <GetTerritories xmlns="...">
              <State>AZ</State>
              <ZipCode>85203</ZipCode>
            </GetTerritories>
          </soap12:Body>
        </soap12:Envelope>"""
        http.request( POST, XML ) {
             headers."Content-Type" = "application/soap+xml; charset=utf-8"
             headers."Accept" = "application/soap+xml; charset=utf-8"
             body = soapEnvelope

            response.success = { resp, xml ->     
                println "XML was ${xml}"
                println "Territories were ${xml.Territories}"
                println "State were ${xml.Territories.State}"
                println "City was ${xml.Territories.Territory.City}"
                println "County was ${xml.Territories.Territory.County}"
            }

            response.failure = { resp, xml ->
                xml
            }
        } 

につながる

XML was <Territories><State>AZ</State><ZipCode>85203</ZipCode><Territory><City>Mesa</City><County>Maricopa</County>...</Territory></Territories>
Territories were 
State were 
City was 
County was 

更新:John Wagenleitnerの洞察のおかげで、私はもう少し掘り下げました。

そのアサートを追加すると、次の問題が発生します。

assert "Territories" == xml.name()
                     |  |   |
                     |  |   Envelope
                     |  <Territories><State>AZ</State><ZipCode>85203</ZipCode</Territories>
                     false

リクエストパラメータをからPOST, XMLに変更すると、次のことPOST, TEXTがわかります。

XML was <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope 
      xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <soap:Body>
        <GetTerritoriesResponse xmlns="...">
            <GetTerritoriesResult>&lt;Territories&gt;&lt;State&gt;AZ&lt;/State&gt;&lt;ZipCode&gt;85203&lt;/ZipCode&gt;&lt;Territory&gt;&lt;City&gt;Mesa&lt;/City&gt;&lt;County&gt;Maricopa&lt;/County&gt;...&lt;/Territory&gt;&lt;/Territories&gt;
            </GetTerritoriesResult>
        </GetTerritoriesResponse>
    </soap:Body>
</soap:Envelope>

..。

したがって、XmlSlurperは、変数が出力されているときに、SOAPのものを破棄し、最も内側のノード()を評価しているように見えますが、実際にはそのノードに移動していません。これは予想される動作ですか?

より完全で最新のSOAP呼び出しを見つけて、httpBuilderを使用して解析することができなかったため、XMLが適切なコンテンツタイプであると想定しました。しかし、私はTEXTを受け入れて、自分で本体を解析する必要があるように見えます。httpBuilderでSOAP応答を処理するより良い方法はありますか?

4

1 に答える 1

1

応答の生のテキストを印刷することをお勧めします。

println "XML was ${resp.data.text}"

印刷されたXML行が期待どおりであると仮定すると(エンベロープノードまたはボディノードがないため奇妙ですが)、 xmlへの参照からテリトリーを削除できるはずです。XmlSlurperで解析すると、ルートノードはGPathResultになります。

assert "Territories" == xml.name()
println "State were ${xml.State.text()}"
println "City were ${xml.Territory.City.text()}"
println "County were ${xml.Territory.County.text()}"

また、SOAP1.2のメディアタイプは「application/ soap+xml」であることを指摘したいと思います。

アップデート:

したがって、XmlSlurperは、変数が出力されているときに、SOAPのものを破棄し、最も内側のノード()を評価しているように見えますが、実際にはそのノードに移動していません。これは予想される動作ですか?

はい、GPathResultのtoString()メソッドは、実際の要素や属性ではなく、すべてのテキストノードを出力するだけです。HTTPBuilderを使用すると、次のコマンドを使用して生の応答テキストを印刷できます。

println resp.data.text

より完全で最新のSOAP呼び出しを見つけて、httpBuilderを使用して解析することができなかったため、XMLが適切なコンテンツタイプであると想定しました。しかし、私はTEXTを受け入れて、自分で本体を解析する必要があるように見えます。httpBuilderでSOAP応答を処理するより良い方法はありますか?

ContentType.XMLは問題ありません。問題は、Webサービスが返すSOAP応答がどのように形成されるかにあります。Webサービスは、Territoriesの結果をGetTerritoriesResult要素のエンコードされた文字列として送り返します。HTTPBuilderが自動的に解析する実際のXML応答の一部としてではありません(これは、HTTPBuilderの処理方法に問題はありません)。本当に必要なデータはそのエンコードされた文字列に含まれているため、GetTerritoriesResultのテキストノードを自分で解析する必要があります。

response.success = { resp, xml ->     
    println "XML was ${resp.data.text}"
    def territories = new XmlSlurper().parseText(
        xml.Body.GetTerritoriesResponse.GetTerritoriesResult.text()
    )
    println "State were ${territories.State}"
    println "City was ${territories.Territory.City}"
    println "County was ${territories.Territory.County}"
}
于 2011-10-20T00:26:27.460 に答える