开发者

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>"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜