无法使用Savon 2访问SOAP xml嵌套id = attribute

时间:2015-07-02 12:43:33

标签: ruby xml soap savon

在下面的肥皂响应中(来自SoapUI),在父SearchForReservationResponse标记下,我试图提取Reservation idRestaurant idLocation id的值萨文2。

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <SearchForReservationResponse xmlns="http://schemas.livebookings.net/OneFormat/Aggregator/Internal/1/0/">
         <Reservation id="34639536" status="Confirmed">
            <DiningDateAndTime>2015-07-01T17:00:00</DiningDateAndTime>
            <Restaurant id="25200">
               <Name>Eat Food - UK Demo Website - Bookatable.com</Name>
               <Location id="35839">
                  <Name>Bar</Name>
               </Location>
            </Restaurant>
            <Size>2</Size>
            <Created>2015-07-01T13:22:17.41</Created>
            <SessionId>DINNER</SessionId>
            <FirstName>John</FirstName>
            <LastName>Smith</LastName>
            <ConfirmationNumber>JWRW5HR5</ConfirmationNumber>
            <AllowedToCancelOnline>true</AllowedToCancelOnline>
            <RestaurantPhoneNumber type="Main">+44 7951300529</RestaurantPhoneNumber>
         </Reservation>
      </SearchForReservationResponse>
   </soap:Body>
</soap:Envelope>

以下是我尝试访问Reservation id的尝试。经过大量的谷歌搜索后,我发现新的Savon 2语法使用了@attrib,但我不断收到错误,因为我认为我没有正确使用这种Ruby嵌套的哈希语法 - 我发现它非常令人困惑,而且对于Ruby来说还是一个新手。如果你能在这里帮助我,我将不胜感激!

require 'savon'

class SearchReservation
  attr_reader :reservation_id

  def client
    client = Savon.client(wsdl: "http://example-wsdl-url", follow_redirects: :follow_redirects)
  end

  def main_method(confirm_number, email)
    message = {'ConfirmationNumber' => "JWRW5HR5", 'EMail' => "jon@" }
    response = client.call(:search_for_reservation, message: message)
    data = response.body(:search_for_reservation_response => { @attrib => {:reservation => :id} })   
    if data
      @reservation_id = data[:id]
  end
end

end

search = SearchReservation.new
puts search.main_method("JWRW5HR5", "jon@")

N.B。电子邮件值jon @不必是有效的电子邮件地址(仅用于测试目的) - 它在SoapUI中返回有效的响应。

我在终端/控制台中的最后一个语法错误跟踪:

/~/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/savon-2.11.1/lib/savon/response.rb:36:in `body': wrong number of arguments (1 for 0) (ArgumentError)
    from search.rb:13:in `main_method'
    from search.rb:22:in `<main>'

1 个答案:

答案 0 :(得分:0)

我的最终解决方案取出了我需要的所有价值观。值得注意的是:尽管在放置response.body时,dining_date_and_time被显示为xml,但当使用@dining_date_and_time = data[:dining_date_and_time]提取时,日期和时间值会被干净地打印出来。一旦移植到成熟的Rails应用程序,这是关键。

尽管在网上讨论了所有关于属性的问题,但是只需要确保你在&#34;树中足够远,就可以拉出xml标签中的ID。 (即,位置ID属于位置标记)然后指定密钥:在这种情况下,api将其显示为:@id用于每个嵌套的大小写。

N.B,这只返回控制台中每次调用的最后一个值。但是,一旦集成到Rails中,所有值都应在视图中拉出。 (希望!)

require 'savon'

class SearchClass

  def client
  client = Savon.client(wsdl: "http://wsdl-example-url", follow_redirects: :follow_redirects)
  end

  def return_data(confirm_number, email)
    message = {'ConfirmationNumber' => confirm_number, 'EMail' => email  }
    response = client.call(:search_for_reservation, message: message)
    data = response.to_hash[:search_for_reservation_response][:reservation]
    @reservation_id = data[:@id]
    @dining_date_and_time = data[:dining_date_and_time]
    @size = data[:size]
    @session_id = data[:session_id]
    @first_name = data[:first_name]
    @last_name = data[:last_name]
    @confirm_number = data[:confirmation_number]
    @allowed_to_cancel_online = data[:allowed_to_cancel_online]
    @restaurant_phone_number = data[:restaurant_phone_number]

    data2 = response.to_hash[:search_for_reservation_response][:reservation][:restaurant]
    @restaurant_id = data2[:@id]
    @restaurant_name = data2[:name]

    data3 = response.to_hash[:search_for_reservation_response][:reservation][:restaurant][:location]
    @location_id = data3[:@id]
    @location_name = data3[:name]

  end  

end

search = SearchClass.new
puts search.return_data("JWRW5HR5", "jon@")