Android 如何解析通过POST发送到RubyonRails的XML?
我正在从Android设备向Rails应用程序发送一个XML结构。此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
<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”。你的代码非常接近工作状态,但它只是没有正确处理更新对象。我已经找到了答案!我会的