Android 如何解析通过POST发送到RubyonRails的XML?

Android 如何解析通过POST发送到RubyonRails的XML?,android,ruby-on-rails,xml,xml-parsing,Android,Ruby On Rails,Xml,Xml Parsing,我正在从Android设备向Rails应用程序发送一个XML结构。此XML的结构如下所示: <Updates> <Update type="1"><Data>...</Data><Something>...</Something></Update> <Update type="2"><Data>...</Data><Something>...</Somethi

我正在从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>
这是我的控制器:

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
class UpdateController“”+output+“”}
结束
结束
私有#私有方法如下:
def更新费用(费用数量)
当前用户。更新属性(“错误费用”,错误费用的数量)
结束
def更新等级数据(等级id、等级1、等级2、等级3)
更新的_-level=level.where(“level_-id=?和user_-id=?”,level_-id,current_-user.id)
如果更新了\u level.empty?
当前用户.levels.create(属性={:level\u id=>level\u id,:star\u 1=>star\u 1,:star\u 2=>star\u 2,:star\u 3=>star\u 3})
其他的
更新了_级别[0]。更新了_属性(:star_1=>star_1,:star_2=>star_2,:star_3=>star_2)
结束
最新水平
结束
def更新风塔数据(风塔id、风塔状态)
更新的塔=塔。其中(“塔id=?和用户id=?”,塔id,当前用户id)
如果更新为空?
当前用户.towers.create(属性={:tower\u id=>tower\u id,:tower\u state=>tower\u state})
其他的
已更新\u塔[0]。更新\u属性(:塔\u状态=>塔\u状态)
结束
更新的天安门大厦
结束
def更新已登录(身份验证令牌)
注销用户=用户。其中(“身份验证令牌=?”,身份验证令牌)。首先
已注销\u用户。重置\u身份验证\u令牌!
注销用户。更新属性(“是否已登录”,false)
结束
############################################################################################################################
############################################################################################################################
结束

您是否已经尝试过类似的方法

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

如果rails给您一个散列,只需在您想要的散列中迭代集合。您处理POST的控制器是什么样子的?

您是否已经尝试过类似的方法

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

如果rails给您一个散列,只需在您想要的散列中迭代集合。处理帖子的控制器是什么样子的?

这可能有点晚了,但对于稍后引用本文的人来说,这就是我解决类似情况的方法

string = request.body.read # rather than using params you can get get/post message with this 
然后按如下方式使用

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

有关如何使用Nokogiri的更多信息,请参考

这可能有点晚了,但对于稍后引用本文的任何人来说,这就是我如何解决类似情况的方法

string = request.body.read # rather than using params you can get get/post message with this 
然后按如下方式使用

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

有关如何使用Nokogiri的更多信息,请参阅

我已经按照您的建议做了。我还编辑了我的原始帖子,以显示我得到的错误和我的控制器。为什么“TypeError(无法将字符串转换为整数)”一直在发生?似乎循环中的“update”有时是HashWithUnderfertaccess,有时是数组。解决方案是什么?如果是数组,索引必须是整数(因此
update.fetch(“type”)
失败,因为更新是数组)。基于该XML,我认为Rails应该有一个params[:Updates],它是一个
hashWithInferenceTaccess
,包含一个
hashWithInferenceTaccess
更新,它们本身就是
数组。因此,您得到的不是一个可以调用
.fetch
的更新对象,而是一个
数组,该数组在索引0处有“type”,在索引1处有“n”。你的代码非常接近工作状态,但它只是没有正确处理更新对象。我已经找到了答案!我会的