从标记中提取HTML5数据属性

我想从标签中提取所有HTML5数据属性,就像这个jQuery插件一样 。

例如,给定:

Joe Bloggs 

我想得到一个哈希:

 { 'data-age' => '50', 'data-location' => 'London' } 

我最初希望使用通配符作为我的CSS选择器的一部分,例如

 Nokogiri(html).css('span[@data-*]').size 

但似乎不支持。

选项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数据集插件一样的行为

如果您更喜欢类似插件的方法,下面将为您提供每个Nokogiri节点上的dataset方法。

 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中的以下行:

 Joe Bloggs Jim Foggs 

输出将是:

 [ {"data-location"=>"London", "data-age"=>"50"}, {"data-location"=>"Oxford", "data-age"=>"40"} ] 

你可以用一点xpath做到这一点:

 doc = Nokogiri.HTML(html) data_attrs = doc.xpath "//span/@*[starts-with(name(), 'data-')]" 

这将获得以’data-‘开头的span元素的所有属性。 (您可能希望分两步完成此操作,首先获取您感兴趣的所有元素,然后依次从每个元素中提取数据属性。

继续这个例子(使用你问题中的span ):

 hash = data_attrs.each_with_object({}) do |n, hsh| hsh[n.name] = n.value end puts hash 

生产:

 {"data-age"=>"50", "data-location"=>"London"} 

Node#css文档提到了一种附加自定义伪指标选择器的方法。 对于选择属性以“data-”开头的节点,这可能如下所示:

 Nokogiri(html).css('span:regex_attrs("^data-.*")', Class.new { def regex_attrs node_set, regex node_set.find_all { |node| node.attributes.keys.any? {|k| k =~ /#{regex}/ } } end }.new) 

尝试循环遍历element.attributes同时忽略任何不以data-开头的attribue。