Nokogiri: how to find the selected option of <select>?

对着背影说爱祢 提交于 2019-12-13 04:12:41

问题


I need to get a value of the selected HTML option:

<select  name="DisplayCurrency" id="DisplayCurrency" >
<option  value="GBP" >Pounds Sterling</option>
<option  value="EUR"  selected="selected" >Euros</option>
<option  value="CHF" >Swiss Francs</option>
<option  value="DKK" >Danish Krona</option>
<option  value="CSK" >Czech Krowns</option>
<option  value="HUF" >Hungarian Forints</option>
<option  value="PLN" >Polish Zloty</option>
</option>
</select>

I tried this using Nokogiri, but it does not work:

page.search('//select[@id="DisplayCurrency"]/option[@selected=selected]').attr('value')

回答1:


This works for me, even with the invalid markup:

require 'nokogiri'
doc = Nokogiri::XML <<ENDXML
  <select name="DisplayCurrency" id="DisplayCurrency" >
  <option value="GBP" >Pounds Sterling</option>
  <option value="EUR" selected="selected" >Euros</option>
  <option value="CHF" >Swiss Francs</option>
  <option value="DKK" >Danish Krona</option>
  <option value="CSK" >Czech Krowns</option>
  <option value="HUF" >Hungarian Forints</option>
  <option value="PLN" >Polish Zloty</option>
  </option>
  </select>
ENDXML

puts doc.css('#DisplayCurrency option[@selected="selected"]').attr('value')
#=> EUR

puts doc.at_xpath('//select[@id="DisplayCurrency"]/option[@selected="selected"]').attr('value')
#=> EUR

puts doc.at_xpath('//*[@id="DisplayCurrency"]/option[@selected="selected"]/@value').value
#=> EUR

p RUBY_VERSION, Nokogiri::VERSION
#=> "1.9.2"
#=> "1.4.4"



回答2:


Here's some things about what Nokogiri returns when searching and more streamlined ways to git 'er done:

search returns a nodeset, which is like an array. Be careful asking for an attribute of an node when you have a nodeset.

doc = Nokogiri::HTML(html)
doc.search('option[@selected="selected"]').class # => Nokogiri::XML::NodeSet

Access a member of a nodeset by indexing:

doc.search('option[@selected="selected"]').first.attr('value') # => "EUR"
doc.search('option[@selected="selected"]')[0].attr('value') # => "EUR"

This works but I consider it an unintended side effect:

doc.search('option[@selected="selected"]').attr('value') # => #<Nokogiri::XML::Attr:0x80427464 name="value" value="EUR">

This is the same thing but it fails with an exception:

doc.search('option[@selected="selected"]')['value']  
# ~> -:26:in `[]': can't convert String into Integer (TypeError)
# ~>    from -:26:in `<main>'

Because you want the selected option inside a tag with an ID, I'd go after it using CSS selectors. at_css, at and % return a single node, simplifying the task.

doc.at_css('#DisplayCurrency option[@selected="selected"]')['value'] # => "EUR"
doc.at('#DisplayCurrency option[@selected="selected"]')['value'] # => "EUR"
(doc % '#DisplayCurrency option[@selected="selected"]')['value'] # => "EUR"


来源:https://stackoverflow.com/questions/4466198/nokogiri-how-to-find-the-selected-option-of-select

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!