Вариант 1: захват всех элементов данных
Если все, что вам нужно, это перечислить все элементы данных страницы, вот одна строка:
Hash[doc.xpath("//span/@*[starts-with(name(), 'data-')]").map{|e| [e.name,e.value]}]
Выход:
{"data-age"=>"50", "data-location"=>"London"}
Вариант 2: группировать результаты по тегу
Если вы хотите сгруппировать результаты по тегу (возможно, вам необходимо выполнить дополнительную обработку для каждого тега), вы можете сделать следующее:
tags = []
datasets = "@*[starts-with(name(), 'data-')]"
#If you want any element, replace "span" with "*"
doc.xpath("//span[#{datasets}]").each do |tag|
tags << Hash[tag.xpath(datasets).map{|a| [a.name,a.value]}]
end
Тогда tags
- это массив, содержащий хэш-пары ключ-значение, сгруппированные по тегу.
Вариант 3: поведение, подобное плагину jQuery datasets
Если вы предпочитаете плагиноподобный подход, следующий метод даст вам dataset
метод для каждого узла Nokogiri.
module Nokogiri
module XML
class Node
def dataset
Hash[self.xpath("@*[starts-with(name(), 'data-')]").map{|a| [a.name,a.value]}]
end
end
end
end
Затем вы можете найти набор данных для одного элемента:
doc.at_css("span").dataset
Или получить набор данных для группы элементов:
doc.css("span").map(&:dataset)
Пример:
Ниже приведено поведение метода dataset
, описанного выше. Учитывая следующие строки в HTML:
<span data-age="50" data-location="London" class="highlight">Joe Bloggs</span>
<span data-age="40" data-location="Oxford" class="highlight">Jim Foggs</span>
Вывод будет:
[
{"data-location"=>"London", "data-age"=>"50"},
{"data-location"=>"Oxford", "data-age"=>"40"}
]