patternrubyrailsMinor
Parsing data from XML using Ruby and Nokogiri
Viewed 0 times
xmlparsingusingrubyandfromdatanokogiri
Problem
I have a method that parses XML into an array of hashes.
Here is the original XML:
Here is the final array of hashes:
Here is the method, which uses Nokogiri for parsing:
Here is the original XML:
Here is the final array of hashes:
[{:queuePosition=>"0", :typeID=>"20495", :level=>"3", :startSP=>"2829", :endSP=>"16000", :startTime=>"2013-03-04 16:25:50", :endTime=>"2013-03-05 01:02:20"}, {:queuePosition=>"1", :typeID=>"19767", :level=>"4", :startSP=>"40000", :endSP=>"226275", :startTime=>"2013-03-05 01:02:20", :endTime=>"2013-03-07 06:40:31"}]
Here is the method, which uses Nokogiri for parsing:
def get_training_queue(xml_data)
queue = []
xml_data.xpath("//row").each do |skill_in_queue|
skill = {}
skill_in_queue.attributes.each do |details|
skill[details[0].to_s.to_sym] = details[1].to_s
end
queue
This works great, but it feels a bit inelegant.
- I'm curious if there is a better way to create the hashes within the internal loop?
- I am calling
to_s` because I couldn't figure out a way to pull out just the key/value without doing so, and it 'feels' like I'm missing some more elegant way of doing that.Solution
Notes:
I'd write:
All those each`s and in-place updates show that you think in imperative terms instead of functional, check this wiki page.
- Use functional
Enumerable#mapinstead of imperative patternobj = []+Enumerable#each+Array#
- Use Kernel#Hash to build a hash from its pairs. Note that this method is very ugly and some prefer a more OOP approach, in that case check Enumerable#mash from Facets.
- Use nokogiri_node.text
.
- Arguments in blocks can be unpacked.
I'd write:
require 'nokogiri'
require 'facets'
def get_training_queue(xml_data)
xml_data.xpath("//row").map do |skill_in_queue|
skill_in_queue.attributes.mash do |name, attribute|
[name.to_sym, attribute.text]
end
end
endAll those each`s and in-place updates show that you think in imperative terms instead of functional, check this wiki page.
Code Snippets
require 'nokogiri'
require 'facets'
def get_training_queue(xml_data)
xml_data.xpath("//row").map do |skill_in_queue|
skill_in_queue.attributes.mash do |name, attribute|
[name.to_sym, attribute.text]
end
end
endContext
StackExchange Code Review Q#23449, answer score: 4
Revisions (0)
No revisions yet.