jquery - :has CSS pseudo class in Nokogiri

标签 jquery css ruby-on-rails ruby nokogiri

我在 Nokogiri 中寻找伪类 :has . 它应该像 jQuery 的 has selector 一样工作.

例如:

<li><h1><a href="dfd">ex1</a></h1><span class="string">sdfsdf</span></li>
<li><h1><a href="dsfsdf">ex2</a></h1><span class="string"></span></li>
<li><h1><a href="sdfd">ex3</a></h1></li>

CSS 选择器应该只返回第一个链接,即具有非空 span.string 兄弟的链接。

在 jQuery 中,这个选择器运行良好:

$('li:has(span.string:not(:empty))>h1>a')

但不在 Nokogiri:

Nokogiri::HTML(html_source).css('li:has(span.string:not(:empty))>h1>a')

:not:empty 效果很好,但不是 :has


  1. Nokogiri 中是否有任何关于 CSS 选择器的文档?
  2. 也许有人可以编写自定义:has 伪类?这是一个 example如何编写 :regexp 选择器。
  3. 我可以选择使用 XPath。如何为 li:has(span.string:not(:empty))>h1>a 编写 XPath?

最佳答案

problem with Nokogiri's current implementation of :has()是它创建的 XPath 要求内容是直接子项,而不是任何后代:

puts Nokogiri::CSS.xpath_for( "a:has(b)" )
#=> "//a[b]"
#=> Should output "//a[.//b]" to be correct

要使此 XPath 与 jQuery 的功能相匹配,您需要允许 span 成为后代元素。例如:

require 'nokogiri'
d = Nokogiri.XML('<r><a/><a><b><c/></b></a></r>')
d.at_css('a:has(b)')    #=> #<Nokogiri::XML::Element:0x14dd608 name="a" children=[#<Nokogiri::XML::Element:0x14dd3e0 name="b" children=[#<Nokogiri::XML::Element:0x14dd20c name="c">]>]>
d.at_css('a:has(c)')    #=> nil
d.at_xpath('//a[.//c]') #=> #<Nokogiri::XML::Element:0x14dd608 name="a" children=[#<Nokogiri::XML::Element:0x14dd3e0 name="b" children=[#<Nokogiri::XML::Element:0x14dd20c name="c">]>]>

对于您的具体情况,这是完整的“损坏的”XPath:

puts Nokogiri::CSS.xpath_for( "li:has(span.string:not(:empty)) > h1 > a" )
#=> //li[span[contains(concat(' ', @class, ' '), ' string ') and not(not(node()))]]/h1/a

这里是固定的:

# Adding just the .//
//li[.//span[contains(concat(' ', @class, ' '), ' string ') and not(not(node()))]]/h1/a

# Simplified to assume only one CSS class is present on the span
//li[.//span[@class='string' and not(not(node()))]]/h1/a

# Assuming that `not(:empty)` really meant "Has some text in it"
//li[.//span[@class='string' and text()]]/h1/a

# ..or maybe you really wanted "Has some text anywhere underneath"
//li[.//span[@class='string' and .//text()]]/h1/a

# ..or maybe you really wanted "Has at least one element child"
//li[.//span[@class='string' and *]]/h1/a

关于jquery - :has CSS pseudo class in Nokogiri,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11760171/

相关文章:

css - 在我的 Mac 上全局安装 SASS 时出错

javascript - 通过上一个输入框的onClick函数使输入框可见只作用一次

ruby-on-rails - 搜索#search中的Rails:Elasticsearch::Transport::Transport::Errors::BadRequest

ruby-on-rails - Ruby on Rails 允许对 RSpec 测试进行批量分配

ruby-on-rails - Rails 根据两个字段查找或创建

javascript - jquery 无法检测大写锁定的打开和关闭以及按键是大写还是小写

javascript - 缩放图像组以适合父宽度/高度

jquery - 具有接触边界的 div 网格 - 停止加倍

javascript - 从 Bootstrap 中删除页面顶部空间

jquery - 如何使用 Netbeans Connector 阻止 Inspect Element Tab 不断重新加载页面