2012-03-17 85 views
5

可能重复:
Best way to use html5 data attributes with rails content_tag helper?提取HTML5数据属性

我想提取来自标签的所有HTML5数据属性,就像this jQuery plugin

例如,给定:

<span data-age="50" data-location="London" class="highlight">Joe Bloggs</span> 

我想如哈希:

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

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

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

但似乎不支持。

+0

链接的“重复”的问题是关于_creating_数据属性(和Rails相关),这个问题是关于_extracting_他们来自现有的HTML,所以它不是重复的。 – matt 2013-11-18 16:45:25

回答

6

选项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是一个ar包含键值哈希对,按标签分组。

方案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下面几行:

<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"} 
] 
+0

如果有多个跨度,虽然这会将它们混合在一起 – pguardiario 2012-03-18 01:48:31

+0

@pguardiario是的。这会在整个页面中创建一个包含所有数据属性的哈希表。 – 2012-03-19 12:51:27

1

尝试循环浏览element.attributes,同时忽略不以data-开头的任何属性。

2

Node#css文档提到了附加自定义伪选择器的方法。这可能看起来像下面的选择节点与属性以“数据 - ”:

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

你可以用一点的XPath做到这一点:

doc = Nokogiri.HTML(html) 
data_attrs = doc.xpath "//span/@*[starts-with(name(), '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"}