在jQuery中,你有:eq选择器将匹配元素集合减少为具有给定索引的元素。
Nokogiri怎么办?我搜索得很久,但找不到办法。
见这个例子:
require 'nokogiri'
html ='
<div>
<p>foo</p></div>
<span>
<p>bar</p>
<p>foobar</p></span>
'
doc = Nokogiri::HTML(html)
p doc.search('p:eq(0)')
# -> []
答案 0 :(得分:2)
以下是我的捕鱼方式:
require 'nokogiri'
html ='
<p>foo</p>
<p>bar</p>
<p>foobar</p>
'
doc = Nokogiri::HTML(html)
doc.search('//p[3]')
=> [#<Nokogiri::XML::Element:0x811058ac name="p" children=[#<Nokogiri::XML::Text:0x81104f74 "foobar">]>]
Nokogiri返回了一个NodeSet,一个节点集合,就像一个数组。我可以使用at
代替search
进行搜索,只检索节点:
doc.at('//p[3]').text
=> "foobar"
或者它可以返回NodeSet,你可以让Ruby从中提取特定的元素:
doc.search('//p')[2].text
=> "foobar"
p doc.search('p:eq(0)')
'p:eq(0)'
不是CSS,也不是XPath。它是一个添加到JavaScript的jQuery选择器。您不能将Nokogiri的jQuery或JavaScript用作访问器,它必须是CSS或XPath。
你的例子甚至没有做我想要的。 [i]运算符与nth-child相当!
每jQuery's documentation for :eq
:
描述:将匹配元素集减少到指定索引处的元素。
//p[3]
,或使用search('p')[2]
让Ruby切片NodeSet,将返回一个特定的节点。在我的示例中,我正在检索第三个<p>
标记的内容,该标记相当于jQuery的:eq(2)
。
使用与之前相同的示例:
require 'nokogiri'
html ='
<p>foo</p>
<p>bar</p>
<p>foobar</p>
'
doc = Nokogiri::HTML(html)
doc.search('//p[0]').text
doc.search('//p[1]').text
doc.search('//p[2]').text
doc.search('//p[3]').text
doc.search('//p')[0].text
doc.search('//p')[1].text
doc.search('//p')[2].text
doc.search('//p')[3].text
将其转入IRB我看到:
irb(main):011:0* doc.search('//p[0]').text # => ""
irb(main):012:0> doc.search('//p[1]').text # => "foo"
irb(main):013:0> doc.search('//p[2]').text # => "bar"
irb(main):014:0> doc.search('//p[3]').text # => "foobar"
irb(main):015:0> doc.search('//p')[0].text # => "foo"
irb(main):016:0> doc.search('//p')[1].text # => "bar"
irb(main):017:0> doc.search('//p')[2].text # => "foobar"
irb(main):018:0> doc.search('//p')[3].text
NoMethodError: undefined method `text' for nil:NilClass
from (irb):18
使用//p[1]
相当于将以下HTML与JavaScript和jQuery一起使用,将其加载到浏览器中,并查看显示“foo”的警报:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>
<body>
<p>foo</p>
<p>bar</p>
<p>foobar</p>
<script>
$().ready(function(){
alert($('p:eq(0)').text());
});
</script>
</body>
</html>
因此,//p
在XPath中带有[1]
切片,在Ruby中带有[0]
切片,相当于JavaScript中的:eq(0)
。但是,由于Nokogiri不使用JavaScript或jQuery,因此必须使用CSS或XPath。
现在可以使用jQuery的选择器,这样就可以了:
require 'nokogiri'
html = '
<html>
<body>
<p>foo</p>
this text
<p>bar</p>
</body>
</html>
'
doc = Nokogiri::HTML(html)
doc.at('p:contains("foo")').next_sibling.text.strip
=> "this text"
答案 1 :(得分:0)
似乎只减少匹配节点的集合,就是使用Ruby和这样的数组方法:
doc = Nokogiri ...
doc.search("table")[2].search("...")
Nokogiri的XPath及其CSS选择器都不支持与jQuery的:eq
运算符相同的功能。
答案 2 :(得分:-1)
尝试使用:nth-child(N)
(第一个元素是找到N = 1)