0

我正在从 Android 设备向 Rails 应用程序发送 XML 结构。此 XML 的结构如下所示:

<Updates>
<Update type="1"><Data>...</Data><Something>...</Something></Update>
<Update type="2"><Data>...</Data><Something>...</Something></Update>
<Update type="3"><Data>...</Data><Something>...</Something></Update>
</Updates>

我看起来好像 Rails 把它变成了一个哈希。

我怎样才能浏览每个标签(这个数字会有所不同),查看它的类型属性,然后使用其他元素中的数据?

我一直在为此苦苦挣扎。

这是我不断收到的错误(TypeError(无法将字符串转换为整数)):

Started POST "/update/index?auth_token=rAyrJgr4w6LNBSXRoYie" for 127.0.0.1 at 2012-04-11 23:44:29 -0500
Processing by UpdateController#index as XML
  Parameters: {"Updates"=>{"Update"=>{"type"=>"2", "levelID"=>"7", "S1"=>"1", "S2"=>"0", "S3"=>"0"}}, "auth_token"=>"rAyrJgr4w6LNBSXRoYie"}
WARNING: Can't verify CSRF token authenticity
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."authentication_token" = 'rAyrJgr4w6LNBSXRoYie' LIMIT 1
   (0.1ms)  begin transaction
   (0.5ms)  UPDATE "users" SET "current_sign_in_at" = '2012-04-12 04:44:29.385406', "sign_in_count" = 2, "updated_at" = '2012-04-12 04:44:29.386311' WHERE "users"."id" = 1
   (2.2ms)  commit transaction
Completed 500 Internal Server Error in 9ms

TypeError (can't convert String into Integer):
  app/controllers/update_controller.rb:21:in `fetch'
  app/controllers/update_controller.rb:21:in `block in index'
  app/controllers/update_controller.rb:19:in `each'
  app/controllers/update_controller.rb:19:in `index'


  Rendered /Users/colegroff/.rvm/gems/ruby-1.9.2-p290@exterminator/gems/actionpack-3.2.1/lib/action_dispatch/middleware/templates/rescues/_trace.erb (50.2ms)
  Rendered /Users/colegroff/.rvm/gems/ruby-1.9.2-p290@exterminator/gems/actionpack-3.2.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.8ms)
  Rendered /Users/colegroff/.rvm/gems/ruby-1.9.2-p290@exterminator/gems/actionpack-3.2.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (55.6ms)
----------------------------------------------------
params[:Updates].class: ActiveSupport::HashWithIndifferentAccess
----------------------------------------------------
update.inspect: ["type", "2"]

这是我的控制器:

class UpdateController < ApplicationController

  before_filter :authenticate_user!

  def index

    output = ""

    puts "----------------------------------------------------"
    puts "params[:Updates].class: #{params[:Updates].class.to_s}"
    puts "----------------------------------------------------"

    if !params[:Updates].nil?
      params[:Updates][:Update].each do |update|
        puts "update.inspect: #{update.inspect}"
        puts "update.fetch(\"type\"): #{update.fetch("type")}"
        puts "update.fetch(\"type\").class.to_s: #{update.fetch("type").class.to_s}"
        update_type = update.fetch("type")
        puts "update_type: #{update_type}"

        case update_type

        when "0"
          puts "inside case 0"
          number_of_bug_bucks = update.fetch("numberOfBugBucks")
          update_bug_bucks(number_of_bug_bucks)
          output += "<Update type='0'>"
          output += "<numberOfBugBucks>#{current_user.bug_bucks.to_s}</numberOfBugBucks>"
          output += "</Update>"
        when "2"
          puts "inside case 2"
          level_id = update.fetch("levelID")
          star_1 = update.fetch("S1")
          star_2 = update.fetch("S2")
          star_3 = update.fetch("S3")
          updated_level = update_level_data(level_id, star_1, star_2, star_3)
          output += "<Update type='2'>"
          output += "<levelID>#{updated_level[0].level_id}</levelID>"
          output += "<S1>#{updated_level[0].star_1}</S1>"
          output += "<S2>#{updated_level[0].star_2}</S2>"
          output += "<S3>#{updated_level[0].star_3}</S3>"
          output += "</Update>"
        when "3"
          puts "inside case 3"
          tower_id = update.fetch("towerID")
          tower_state = update.fetch("towerState")
          updated_tower = update_tower_data(tower_id, tower_state)
          output += "<Update type='3'>"
          output += "<towerID>#{updated_tower[0].tower_id}</towerID>"
          output += "<towerState>#{updated_tower[0].tower_state}</towerState>"
          output += "</Update>"
        when "4"
          puts "inside case 4"
          authentication_token = update.fetch("AuthToken")
          update_is_logged_in = update_is_logged_in(authentication_token)
          output += "<Update type='4'>"
          output += "<AuthToken>#{update_is_logged_in[0].authentication_token}</AuthToken>"
          output += "</Update>"
        end

        puts "----------------------------------------------------"

      end
    end

    puts "output: #{output}"
    puts "----------------------------------------------------"

    respond_to do |format|
      format.xml { render :xml => "<Updates>" + output + "</Updates>" }
    end

  end

  private # private methods below:

    def update_bug_bucks(number_of_bug_bucks)
      current_user.update_attribute("bug_bucks", number_of_bug_bucks)
    end

    def update_level_data(level_id, star_1, star_2, star_3)      
      updated_level = Level.where("level_id = ? AND user_id = ?", level_id, current_user.id)      
      if updated_level.empty?
        current_user.levels.create(attributes = {:level_id => level_id, :star_1 => star_1, :star_2 => star_2, :star_3 => star_3})
      else
        updated_level[0].update_attributes(:star_1 => star_1, :star_2 => star_2, :star_3 => star_2)
      end      
      updated_level      
    end

    def update_tower_data(tower_id, tower_state)      
      updated_tower = Tower.where("tower_id = ? AND user_id = ?", tower_id, current_user.id)      
      if updated_tower.empty?
        current_user.towers.create(attributes = {:tower_id => tower_id, :tower_state => tower_state})
      else
        updated_tower[0].update_attributes(:tower_state => tower_state)
      end      
      updated_tower      
    end

    def update_is_logged_in(authentication_token)      
      logged_out_user = User.where("authentication_token = ?", authentication_token).first
      logged_out_user.reset_authentication_token!
      logged_out_user.update_attribute("is_logged_in", false)      
    end
    ############################################################################################################################
    ############################################################################################################################

end
4

2 回答 2

4

这可能有点晚了,但对于稍后参考这篇文章的任何人来说,这就是我解决类似情况的方法

string = request.body.read # rather than using params you can get get/post message with this 

然后按如下方式使用Nokogiri

doc = Nokogiri::XML(string)
doc.xpath("//Upadate")

有关如何使用 Nokogiri 的更多信息,请参阅http://nokogiri.org/tutorials

于 2014-01-30T07:25:28.837 回答
1

您是否已经尝试过类似的东西

params[:updates][:update].each do |update|
  puts "do something with this update: #{update.inspect}"
end

如果 rails 给你一个散列,只需遍历你想要的散列中的集合。处理 POST 的控制器是什么样的?

于 2012-04-12T02:52:31.647 回答