2013-02-11 26 views
1

背景Ruby Hash parsed_response錯誤

我正在使用HTTParty來解析XML哈希響應。不幸的是,當散列響應只有一個條目(?)時,結果散列不可索引。我已經確認了所產生的XML語法對於單個和多個條目(?)是相同的。當散列中總是有多個條目(?)時,我也確認了我的代碼有效。

問題

如何適應單一的哈希條目的情況下和/或在那裏實現什麼,我試圖做一個更簡單的方法?

CODE

require 'httparty' 

    class Rest 
    include HTTParty 
    format :xml 
    end 


    def test_redeye 
    # rooms and devices 
    roomID = Hash.new 
    deviceID = Hash.new { |h,k| h[k] = Hash.new } 
    rooms = Rest.get(@reIp["theater"] + "/redeye/rooms/").parsed_response["rooms"] 
    puts "rooms #{rooms}" 
    rooms["room"].each do |room| 
     puts "room #{room}" 
     roomID[room["name"].downcase.strip] = "/redeye/rooms/" + room["roomId"] 
     puts "roomid #{roomID}" 
     devices = Rest.get(@reIp["theater"] + roomID[room["name"].downcase.strip] + "/devices/").parsed_response["devices"] 
     puts "devices #{devices}" 
     devices["device"].each do |device| 
      puts "device #{device}" 
      deviceID[room["name"].downcase.strip][device["displayName"].downcase.strip] = "/devices/" + device["deviceId"] 
      puts "deviceid #{deviceID}" 
     end 
    end 
    say "Done" 
    end 

XML - 單次入境

<?xml version="1.0" encoding="UTF-8" ?> 
<devices> 
    <device manufacturerName="Philips" description="" portType="infrared" deviceType="0" modelName="" displayName="TV" deviceId="82" /> 
</devices> 

XML - 多次入境

<?xml version="1.0" encoding="UTF-8" ?> 
<devices> 
    <device manufacturerName="Denon" description="" portType="infrared" deviceType="6" modelName="Avr-3311ci" displayName="AVR" deviceId="77" /> 
    <device manufacturerName="Philips" description="" portType="infrared" deviceType="0" modelName="" displayName="TV" deviceId="82" /> 
</devices> 

產生的誤差

[Info - Plugin Manager] Matches, executing block 
rooms {"room"=>[{"name"=>"Home Theater", "currentActivityId"=>"78", "roomId"=>"-1", "description"=>""}, {"name"=>"Living", "currentActivityId"=>"-1", "roomId"=>"81", "description"=>"2nd Floor"}, {"name"=>"Theater", "currentActivityId"=>"-1", "roomId"=>"80", "description"=>"1st Floor"}]} 
room {"name"=>"Home Theater", "currentActivityId"=>"78", "roomId"=>"-1", "description"=>""} 
roomid {"home theater"=>"/redeye/rooms/-1"} 
devices {"device"=>[{"manufacturerName"=>"Denon", "description"=>"", "portType"=>"infrared", "deviceType"=>"6", "modelName"=>"Avr-3311ci", "displayName"=>"AVR", "deviceId"=>"77"}, {"manufacturerName"=>"Philips", "description"=>"", "portType"=>"infrared", "deviceType"=>"0", "modelName"=>"", "displayName"=>"TV", "deviceId"=>"82"}]} 
device {"manufacturerName"=>"Denon", "description"=>"", "portType"=>"infrared", "deviceType"=>"6", "modelName"=>"Avr-3311ci", "displayName"=>"AVR", "deviceId"=>"77"} 
deviceid {"home theater"=>{"avr"=>"/devices/77"}} 
device {"manufacturerName"=>"Philips", "description"=>"", "portType"=>"infrared", "deviceType"=>"0", "modelName"=>"", "displayName"=>"TV", "deviceId"=>"82"} 
deviceid {"home theater"=>{"avr"=>"/devices/77", "tv"=>"/devices/82"}} 
room {"name"=>"Living", "currentActivityId"=>"-1", "roomId"=>"81", "description"=>"2nd Floor"} 
roomid {"home theater"=>"/redeye/rooms/-1", "living"=>"/redeye/rooms/81"} 
devices {"device"=>{"manufacturerName"=>"Philips", "description"=>"", "portType"=>"infrared", "deviceType"=>"0", "modelName"=>"", "displayName"=>"TV", "deviceId"=>"82"}} 
device ["manufacturerName", "Philips"] 
/usr/local/rvm/gems/[email protected]/gems/siriproxy-0.3.2/plugins/siriproxy-redeye/lib/siriproxy-redeye.rb:145:in `[]': can't convert String into Integer (TypeError) 

回答

2

我看到有幾個選項。如果您控制端點,則可以通過在devices XML元素上添加type="array"屬性來修改發送到accomodate HTTParty's underlying XML parser, Crack的XML。

否則,你可以檢查一下該設備是什麼類索引到它之前:

case devices["device"] 
when Array 
    # act on the collection 
else 
    # act on the single element 
end 

它比理想要少得多,只要你有做類型檢查的動態語言,所以如果你發現你自己不止一次地這樣做,可能值得引入多態,或者至少提取一個方法來做到這一點。

+0

我用案例方法,直到製造商回到我身邊。 – Elvis 2013-02-11 03:38:14