1

バックグラウンド

HTTPartyを使用してXMLハッシュ応答を解析しています。残念ながら、ハッシュ応答にエントリ(?)が1つしかない場合、結果のハッシュはインデックスに登録できません。結果の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パーサーであるCrackに対応するように送信される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 に答える