2011-10-19 11 views
0

XmlSlurperが明らかに結果に作用していない理由を理解できません。Groovy HTTPBuilder SOAP応答が適切に解析されない

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 

UPDATEにつながる:ジョン・Wagenleitnerの洞察力のおかげで、私はもう少し掘りをしました。

私はそのアサートを追加すると、私は問題を参照してください。POST, XMLからPOST, TEXTにリクエストパラメータを変更

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

が明らかにされています

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応答を処理するより良い方法はありますか?

答えて

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()}" 

また、SOAP 1.2メディアタイプが「application/soap + xml」であることを指摘しておきたいと思います。

UPDATE:

だから、変数は アウトを印刷しているときに、XmlSlurperのように見え、実際にそれにナビゲートしていない間)(SOAPのものを捨てると、最も内側のノード を評価していますノード。これは の動作ですか?

はい、GPathResultのtoString()メソッドは、実際の要素や属性ではなく、すべてのテキストノードを出力します。私はhttpBuilderを使用してAAより完全な、近代的なSOAP呼び出しと 解析を見つけることができなかったので、私は、XMLが適切なコンテンツになると想定

println resp.data.text 

を:HTTPBuilderを使用すると、使用して、生の応答テキストをプリントアウトすることができます タイプです。しかし、私はTEXTを受け入れて自分自身の身体を解析する必要があるように思えますが、それは自分の体である です。 httpBuilderでSOAP の応答を処理するより良い方法はありますか?

ContentType.XMLは問題がWebサービスの戻りが形成されていることをどのようにSOAPレスポンスである、結構です。 Webサービスは、これは仕方の問題ではありません(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}" 
} 
+0

ありがとう、このコメントは非常に役に立ちました。私がScott DavisのGroovy Recipesについて読んだところから、text()はXmlSlurperではなく、XmlParser用であると思った。私は$ {xml}と$ {xml.name()}のプリントアウトの不一致に悩まされています。なぜそれがそれをやっているのか分かりますか? –

+0

xml GPathResultを印刷すると、タグは表示されず、テキストコンテンツだけが表示されるため、見た結果が表示されます。 –

+0

GPathResultでtext()を呼び出すと、その要素のテキスト内容のStringが返されます。 printlnのようなことをするときは、GPathResultのtoString()メソッドが要素のテキスト内容を出力するので、通常は厳密には必要ありません。 –

関連する問題