Read a random row from a xml file
I have a xml file like:
<root>
<car>honda</car>
<car>toyota</car>
</root>
Now I want to load the xml, and choose a random row from it and return the contents of the car tag i.e. the word honda or toyota.
I'm using this for a website to display a random row per page request us开发者_JAVA百科ing rails 3.
require 'nokogiri'
def random_car
doc = Nokogiri::XML.parse(File.open('cars.xml'))
cars = doc.xpath('//car').to_a
cars.sample.try(:text)
end
Note that Array#sample
is an ActiveSupport 3 function which is automatically available in Rails 3, while Nokogiri is a gem that you will need to install (add it to your Gemfile).
Using Object#try
ensures the function still works (returns nil) if nothing matches the XPath search, as Array#sample
returns nil if the array is empty.
To make this faster (if the XML file is large), cache the list of cars somewhere, like a constant. This won't every reload the file though, so if you expect the XML file to change, you may not want to do this.
CARS = Nokogiri::XML.parse(File.open('cars.xml')).xpath('//car').to_a
def random_car
CARS.sample.try(:text)
end
Here's how I'd go about it:
require 'nokogiri'
# added some cars to make it more interesting
xml = <<EOT
<root>
<car>honda</car>
<car>toyota</car>
<car>ford</car>
<car>edsel</car>
<car>de lorean</car>
<car>nissan</car>
<car>bmw</car>
<car>volvo</car>
</root>
EOT
doc = Nokogiri::XML(xml)
# doc.search('car') returns a nodeset.
# to_a converts the nodeset to an array.
# shuffle returns a randomly sorted array.
# first returns the element 0 from the randomly sorted array.
# to_xml merely converts it back to the text representation of the XML so it's easy to see what was selected.
doc.search('car').to_a.shuffle.first.to_xml # => "<car>toyota</car>"
doc.search('car').to_a.shuffle.first.to_xml # => "<car>edsel</car>"
doc.search('car').to_a.shuffle.first.to_xml # => "<car>volvo</car>"
精彩评论