2

RubygemSavonを使用してSOAPサービスにアクセスしようとしています。サービスに接続してリクエストを行い、応答を受信することはできますが、応答を解析できません。

応答には、multiRef要素への複数のhref参照が含まれています。を使用してデコードしようとすると

response.to_hash[:get_user_risk_profile_response][:get_user_risk_profile_return][:href]

#id0を取得します。id0リファレンスをフォローするにはどうすればよいですか?

SOAPの応答は以下のとおりです。ありがとう!

<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>
    <getUserStatusResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <getUserStatusReturn href="#id0"/>
    </getUserStatusResponse>
    <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns1:UserRiskProfileBean" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://xrisk.api.example.com">
      <parameters xsi:type="ns2:ArrayOf_tns3_ParamBean" xsi:nil="true" xmlns:ns2="http://api.example.com"/>
      <siteID xsi:type="soapenc:string">UNKNOWN</siteID>
      <userID xsi:type="soapenc:string">sam.wiggins</userID>
      <userRiskScore href="#id1"/>
      <userRiskScoreDT xsi:type="xsd:dateTime">2011-02-16T18:15:50.012Z</userRiskScoreDT>
    </multiRef>
    <multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">640</multiRef>
  </soapenv:Body>
</soapenv:Envelope>
4

2 に答える 2

1

It seems that the best approach, for the moment, was to just roll my own parsing using XPath. It's crude and probably not very bullet proof, but will do the job until something better comes along.

class SavonResponseXMLParser

  def initialize(response_xml)
    @doc = REXML::Document.new(response_xml)
  end

  def get_property(property)
    property_value = nil
    elements = REXML::XPath.match(@doc, "//#{property}")
    if (elements.length == 1)
      element = elements[0]
      href = element.attributes['href']
      if (href)
        href =~ /^#id(\d+)/
        multiref_elements = REXML::XPath.match(@doc,"//multiRef[@id='id#{$1}']")
        if (multiref_elements.length == 1)
          multiref_element = multiref_elements[0]
          property_value = multiref_element.text 
        end
      else
        property_value = element.text
      end
    end
    return property_value
  end
end
于 2011-04-11T18:01:33.553 に答える
0

参照を手動で解決する必要があります。

id = response.to_hash[:get_user_risk_profile_response][:get_user_risk_profile_return][:href]
references = response.to_hash[:multi_ref]
result = references.select {|ref| ref[:id] == id.sub('#', '') }

上記をヘルパーメソッド/モジュールに入れることをお勧めします:

module MultiRef
  def resolve_ref(id)
    references = to_hash[:multi_ref]
    references.select {|ref| ref[:id] == id.sub('#', '') }
  end
end
Savon::Response.send(:include, MultiRef)

次に、単純に次のようにします。

response.resolve_ref("#id1")

hrefハッシュ値を適切な参照値に再帰的に置き換えることは、読者の練習問題として残されています;)

于 2011-02-23T21:19:54.360 に答える