Nokogiri 使用通配符查找所有数据属性
Nokogiri to Find All Data Attrabutes Using a Wildcard
我想在循环浏览文档时从 img
标签中删除所有数据属性。我尝试了一些使用 has_attribute?
和 xpath
的选项,none 返回了 true
。
article.css('img').each do |img|
# There is a `data` element
img.has_attribute?("data-lazy-srcset") # true
# But I only get `false` or empty arrays when trying wildcards
img.has_attribute?('data-*') # false
img.has_attribute?("//*[@*[contains(., 'data-')]]") # false
img.has_attribute?("//*[contains(., 'data-')]") # false
img.has_attribute?("//@*[starts-with(name(), 'data-')]") # false
img.xpath("//*[@*[contains(., 'data-')]]") # []
img.xpath("//*[contains(., 'data-')]") # []
end
如何 select 这些 img
标签上的所有 data-
属性?
您可以使用以下方法搜索属性以“data-”开头的 img 标签:
//img[@*[starts-with(name(),'data-')]]
分解:
- // - 文档中的任意位置
- img - img 标签
- @* - 所有属性
- starts-with(name(),'data-') - 属性名称以“data-”开头
示例:
require 'nokogiri'
doc = Nokogiri::HTML(<<-END_OF_HTML)
<img src='' />
<img data-method='a' src= ''>
<img data-info='b' src= ''>
<img data-type='c' src= ''>
<img src= ''>
END_OF_HTML
imgs = doc.xpath("//img[@*[starts-with(name(),'data-')]]")
puts imgs
# <img data-method="a" src="">
# <img data-info="b" src="">
# <img data-type="c" src="">
或使用您想要的循环
doc.css('img').select do |img|
img.xpath(".//@*[starts-with(name(),'data-')]").any?
end
#[#<Nokogiri::XML::Element:0x384 name="img" attributes=[#<Nokogiri::XML::Attr:0x35c name="data-method" value="a">, #<Nokogiri::XML::Attr:0x370 name="src">]>,
# #<Nokogiri::XML::Element:0x3c0 name="img" attributes=[#<Nokogiri::XML::Attr:0x398 name="data-info" value="b">, #<Nokogiri::XML::Attr:0x3ac name="src">]>,
# #<Nokogiri::XML::Element:0x3fc name="img" attributes=[#<Nokogiri::XML::Attr:0x3d4 name="data-type" value="c">, #<Nokogiri::XML::Attr:0x3e8 name="src">]>]
更新 删除属性:
doc.css('img').each do |img|
img.xpath(".//@*[starts-with(name(),'data-')]").each(&:remove)
end
puts doc.to_s
#<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" #\"http://www.w3.org/TR/REC-html40/loose.dtd\">
#<html>
#<body>
# <img src=\"\">
# <img src=\"\">
# <img src=\"\">
# <img src=\"\">
# <img src=\"\">
#</body>
#</html>
这可以简化为doc.xpath("//img/@*[starts-with(name(),'data-')]").each(&:remove)
我想在循环浏览文档时从 img
标签中删除所有数据属性。我尝试了一些使用 has_attribute?
和 xpath
的选项,none 返回了 true
。
article.css('img').each do |img|
# There is a `data` element
img.has_attribute?("data-lazy-srcset") # true
# But I only get `false` or empty arrays when trying wildcards
img.has_attribute?('data-*') # false
img.has_attribute?("//*[@*[contains(., 'data-')]]") # false
img.has_attribute?("//*[contains(., 'data-')]") # false
img.has_attribute?("//@*[starts-with(name(), 'data-')]") # false
img.xpath("//*[@*[contains(., 'data-')]]") # []
img.xpath("//*[contains(., 'data-')]") # []
end
如何 select 这些 img
标签上的所有 data-
属性?
您可以使用以下方法搜索属性以“data-”开头的 img 标签:
//img[@*[starts-with(name(),'data-')]]
分解:
- // - 文档中的任意位置
- img - img 标签
- @* - 所有属性
- starts-with(name(),'data-') - 属性名称以“data-”开头
示例:
require 'nokogiri'
doc = Nokogiri::HTML(<<-END_OF_HTML)
<img src='' />
<img data-method='a' src= ''>
<img data-info='b' src= ''>
<img data-type='c' src= ''>
<img src= ''>
END_OF_HTML
imgs = doc.xpath("//img[@*[starts-with(name(),'data-')]]")
puts imgs
# <img data-method="a" src="">
# <img data-info="b" src="">
# <img data-type="c" src="">
或使用您想要的循环
doc.css('img').select do |img|
img.xpath(".//@*[starts-with(name(),'data-')]").any?
end
#[#<Nokogiri::XML::Element:0x384 name="img" attributes=[#<Nokogiri::XML::Attr:0x35c name="data-method" value="a">, #<Nokogiri::XML::Attr:0x370 name="src">]>,
# #<Nokogiri::XML::Element:0x3c0 name="img" attributes=[#<Nokogiri::XML::Attr:0x398 name="data-info" value="b">, #<Nokogiri::XML::Attr:0x3ac name="src">]>,
# #<Nokogiri::XML::Element:0x3fc name="img" attributes=[#<Nokogiri::XML::Attr:0x3d4 name="data-type" value="c">, #<Nokogiri::XML::Attr:0x3e8 name="src">]>]
更新 删除属性:
doc.css('img').each do |img|
img.xpath(".//@*[starts-with(name(),'data-')]").each(&:remove)
end
puts doc.to_s
#<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" #\"http://www.w3.org/TR/REC-html40/loose.dtd\">
#<html>
#<body>
# <img src=\"\">
# <img src=\"\">
# <img src=\"\">
# <img src=\"\">
# <img src=\"\">
#</body>
#</html>
这可以简化为doc.xpath("//img/@*[starts-with(name(),'data-')]").each(&:remove)