从标记中提取HTML5数据属性

And*_*ite 5 ruby xml html5 nokogiri

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

例如,给定:

<span data-age="50" data-location="London" class="highlight">Joe Bloggs</span>
Run Code Online (Sandbox Code Playgroud)

我想得到一个哈希:

{ 'data-age' => '50', 'data-location' => 'London' }
Run Code Online (Sandbox Code Playgroud)

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

Nokogiri(html).css('span[@data-*]').size
Run Code Online (Sandbox Code Playgroud)

但似乎不支持.

Mar*_*mas 6

选项1:抓取所有数据元素

如果您只需要列出所有页面的数据元素,那么这是一个单行:

Hash[doc.xpath("//span/@*[starts-with(name(), 'data-')]").map{|e| [e.name,e.value]}]
Run Code Online (Sandbox Code Playgroud)

输出:

{"data-age"=>"50", "data-location"=>"London"}
Run Code Online (Sandbox Code Playgroud)

选项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
Run Code Online (Sandbox Code Playgroud)

然后tags是一个包含按标记分组的键值哈希对的数组.

选项3:jQuery数据集插件之类的行为

如果您更喜欢类似插件的方法,以下内容将为您提供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
Run Code Online (Sandbox Code Playgroud)

然后,您可以找到单个元素的数据集:

doc.at_css("span").dataset
Run Code Online (Sandbox Code Playgroud)

或者获取一组元素的数据集:

doc.css("span").map(&:dataset)
Run Code Online (Sandbox Code Playgroud)

例:

以下是上述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>
Run Code Online (Sandbox Code Playgroud)

输出将是:

[
 {"data-location"=>"London", "data-age"=>"50"},
 {"data-location"=>"Oxford", "data-age"=>"40"}
]
Run Code Online (Sandbox Code Playgroud)