我在 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
。
- Nokogiri 中是否有任何关于 CSS 选择器的文档?
- 也许有人可以编写自定义
:has
伪类?这是一个 example如何编写:regexp
选择器。 - 我可以选择使用 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/