Нокогири: как найти выбранный вариант <select>? - PullRequest
0 голосов
/ 17 декабря 2010

Мне нужно получить значение выбранной опции HTML:

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

Я пробовал это с помощью Nokogiri, но это не работает:

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

Ответы [ 2 ]

4 голосов
/ 17 декабря 2010

Это работает для меня, даже с неверной разметкой:

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 голосов
/ 18 декабря 2010

Вот некоторые вещи о том, что Nokogiri возвращает при поиске, и более упрощенные способы сделать это:

search возвращает набор узлов, который похож на массив.Будьте осторожны при запросе атрибута узла, когда у вас есть набор узлов.

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

Доступ к члену набора узлов с помощью индексации:

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

Это работает, но я считаю его непреднамереннымпобочный эффект:

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

Это то же самое, но оно завершается ошибкой, за исключением:

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

Поскольку вы хотите выбрать выбранную опцию внутри тега с идентификатором, я бы пошелпосле этого с помощью CSS-селекторов.at_css, at и % возвращают один узел, упрощая задачу.

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