我浏览了Difference between nth-child() and eq()
链接。哪个说 -
非常直接。 nth-child为1索引,而eq为0索引。 nth-child基于当前元素parent,而.eq基于当前元素相对于所选元素的索引。它们是两种完全不同的方法,有两种截然不同的目的。
现在为了正确处理我写下面的代码:
doc = Nokogiri::HTML::Document.parse(<<-eohtml)
<html>
<head>
<style>
div { float:left; }
span { color:blue; }
</style>
</head>
<body>
<div>
<p>div1 p1</p>
<p>div1 p2</p>
<p>div1 p3</p>
<p>div1 p4</p>
</div>
<div>
<p>div2 p1</p>
<p>div2 p2</p>
<p>div2 p3</p>
<p>div2 p4</p>
</div>
</body>
</html>
eohtml
p doc.css("div p:eq(2)").map { |e| e.text }
p doc.css("div p:nth-child(2)").map { |e| e.text }
# >> ["div1 p2", "div2 p2"] Expected ["div1 p3", "div2 p3"]
# >> ["div1 p2", "div2 p2"]
有人可以帮我理解我做错的地方吗?实际上,对于这个输出,我不明白这两个css选择器之间的区别。
修改 的
我对XPATH
概念不满意。我尝试将CSS rules
转换为XPATH
,如下所示:
Nokogiri::CSS.xpath_for("div p:eq(2)")
Nokogiri::CSS.xpath_for("div p:nth-child(2)")
# >> ["//div//p[position() = 2]"]
# >> ["//div//*[position() = 2 and self::p]"]
任何人都可以通过解释xpath
表达来帮助我,希望那对我有意义吗?
答案 0 :(得分:8)
第一个:
Nokogiri::CSS.xpath_for("div p:eq(2)")
# >> ["//div//p[position() = 2]"]
这也称为//div//p[2]
,它意味着“返回第二个p
元素”,无论它们是否有其他兄弟元素。
第二个:
Nokogiri::CSS.xpath_for("div p:nth-child(2)")
# >> ["//div//*[position() = 2 and self::p]"]
这意味着“找到第二个位置的所有元素,只有当 恰好是p
时才返回它们。
示例强>
考虑以下HTML:
<html>
<body>
<div>
<p>Div1p1</p>
<i>Div1i1</i>
<p>Div1p2</p>
</div>
<div>
<p>Div2p1</p>
<p>Div2p2</p>
<p>Div2p3</p>
</div>
</body>
</html>
//p[2]
的输出将为:
<p>Div1p2</p>
<p>Div2p2</p>
因为“Div1p2”是第一个p
中的第二个div
,而“Div2p2”是第二个p
中的第二个div
。
//*[position()=2 and self::p]
的输出将为:
<p>Div2p2</p>
因为第一个div的第二个元素是i
,而不是p
。但是第二个div的第二个元素也恰好是p
,所以它匹配。