2013-02-11 74 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