How to convert XML body to hash in Ruby?
I have an XML body that I would like to parse in a hash
<soap:Body> <TimesInMyDAY> <TIME_DATA> <StartTime>2010-11-10T09:00:00</StartTime> <EndTime>2010-11-10T09:20:00</EndTime> </TIME_DATA> <TIME_DATA> <StartTime>2010-11-10T09:20:00</StartTime> <EndTime>2010-11-10T09:40:00</EndTime> </TIME_DATA> <TIME_DATA> <StartTime>2010-11-10T09:40:00</StartTime> <EndTime>2010-11-10T10:00:00</EndTime> </TIME_DATA> <TIME_DATA> <StartTime>2010-11-10T10:00:00</StartTime> <EndTime>2010-11-10T10:20:00</EndTime> </TIME_DATA> <TIME_DATA> <StartTime>2010-11-10T10:40:00</StartTime> <EndTime>2010-11-10T11:00:00</EndTime> </TIME_DATA> </TimesInMyDAY> </soap:Body>
I would like to convert it to a hash like this:
{ :times_in_my_day => { :time_data = > [ {:start_time=>"2010-11-10T09:00:00", :end_time => "2010-11-10T09:20:00" }, {:start_time=>"2010-11-10T09:20:00", :end_time => "2010-11-10T09:40:00" }, {:start_time=>"2010-11-10T09:40:00", :end_time => "2010-11-10T10:00:00" }, {:start_time=>"2010-11-10T10:00:00", :end_time => "2010-11-10T10:20:00" }, {:start_time=>"2010-11-10T10:40:00", :end_time => "2010-11-10T11:00:00" } ] } }
Ideally, tags will be converted to snake_case characters and become keys in the hash.
In addition, there are no time zone offsets in datetime. They are in the local time zone (not UTC). So I would like to parse it to show the local offset, and then convert the xml datetime strings to Rails DateTime objects. The resulting array will look something like this:
{ :times_in_my_day => { :time_data = > [ {:start_time=>Wed Nov 10 09:00:00 -0800 2010, :end_time => Wed Nov 10 9:20:00 -0800 2010 }, {:start_time=>Wed Nov 10 09:20:00 -0800 2010, :end_time => Wed Nov 10 9:40:00 -0800 2010 }, {:start_time=>Wed Nov 10 09:40:00 -0800 2010, :end_time => Wed Nov 10 10:00:00 -0800 2010 }, {:start_time=>Wed Nov 10 10:00:00 -0800 2010, :end_time => Wed Nov 10 10:20:00 -0800 2010 }, {:start_time=>Wed Nov 10 10:40:00 -0800 2010, :end_time => Wed Nov 10 11:00:00 -0800 2010 } ] } }
I managed to convert a single datetime with the parse and in_time_zone as follows:
Time.parse(xml_datetime).in_time_zone(current_user.time_zone)
But I'm not quite sure what is the best way to parse the time when converting XML to hash.
I would be grateful for any advice. Thanks!
Edit
The code for converting a datetime string to a Rails DateTime object is incorrect. This will parse the xml datetime string at the system offset of the time zone and then convert that time to the user's time zone. The correct code is:
Time.zone.parse(xml_datetime)
If the user has a different time zone than the system, this will add the user's time zone offset to the original date string. There's a Railscast on how to enable custom timezone settings here: http://railscasts.com/episodes/106-time-zones-in-rails-2-1 .