2011-10-19 3 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의 통찰력에, 나는 좀 더 파고했다. 그래서 보이는

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> 

...

을 : 계시 POST, XML에서 POST, TEXT에 요청 매개 변수를 변경

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

: 나는 주장을 추가하면

, 내가 문제를 참조 변수가 인쇄 될 때 XmlSlurper와 같이 SOAP 물건을 버리고 내부 탐색 노드()를 평가하는 동안 실제로 탐색하지 않습니다. 그 노드. 이 예상되는 동작입니까?

더 완벽하고 현대적인 SOAP 호출을 찾을 수 없었고 httpBuilder를 사용하여 구문 분석을 수행 했으므로 XML을 올바른 콘텐츠 형식으로 간주했습니다. 그러나 나는 텍스트를 받아 들여 절름발이로 해석해야하는 것처럼 보입니다. 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 호출 및 구문 분석을 찾을 수 없었습니다

println resp.data.text 

, 그래서 XML이 올바른 콘텐츠가 될 것입니다 가정 : HTTPBuilder 사용하면 사용하여 원시 응답 텍스트를 인쇄 할 수 있습니다 유형. 그러나 나는 TEXT를 받아 들여 절름발이 인 본문을 구문 분석해야하는 것처럼 보입니다. httpBuilder를 사용하여 SOAP 응답을 처리하는 더 좋은 방법이 있습니까?

ContentType.XML이 문제는 웹 서비스 리턴이 형성되고, 어떻게 SOAP 응답 함께, 괜찮습니다. 웹 서비스는이 방식에 문제가되지 않습니다합니다 (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()를 호출하면 해당 요소의 텍스트 내용이있는 문자열이 반환됩니다. println과 같은 일을 할 때는 GPathResult의 toString() 메서드가 요소의 텍스트 내용을 인쇄하기 때문에 대개 꼭 필요한 것은 아닙니다. –

관련 문제