1

背景

我正在使用 HTTParty 解析 XML 哈希响应。不幸的是,当哈希响应只有一个条目(?)时,生成的哈希是不可索引的。我已经确认生成的 XML 语法对于单个和多个条目(?)是相同的。当哈希中总是有多个条目(?)时,我还确认我的代码有效。

问题

我如何适应单个哈希条目的情况和/或是否有更简单的方法来完成我想要做的事情?

代码

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/ruby-1.9.3-p374@SiriProxy/gems/siriproxy-0.3.2/plugins/siriproxy-redeye/lib/siriproxy-redeye.rb:145:in `[]': can't convert String into Integer (TypeError)
4

1 回答 1

2

我看到有几个选项。如果您控制端点,您可以修改正在发送的 XML 以适应 HTTParty 的底层 XML 解析器,通过在XML 元素上放置一个type="array"属性来破解。devices

否则,您可以在索引设备之前检查设备的类别:

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

每当您必须在动态语言中进行类型检查时,它就不太理想了,因此如果您发现自己不止一次地这样做,那么可能值得引入多态性或至少提取一种方法来执行此操作。

于 2013-02-11T00:54:34.683 回答