XPath中的@attr!=“ value”`和`not(@ attr =“ value”)`有什么区别?

时间:2019-05-15 16:58:54

标签: ruby xpath nokogiri

有这样的HTML。

Action

要获得我写的最大页面数。

goal

起初,我写了on-deny而不是<div class="paginate_box"> <span class="disabled prev_page">Back</span> <span class="current">1</span> <a rel="next" href="page2">2</a> <a rel="next" href="page3">3</a> <a class="next_page" rel="next" href="page2">Next</a> </div> ,但是它与标记不匹配。为什么不匹配?我在做什么错了?

1 个答案:

答案 0 :(得分:2)

因此,这里的问题是您试图在仅出现在最后一个节点上的属性(!=)上使用@class。这意味着@class无法在其他节点上进行比较,因为它实际上什么也没说!='next_page'。

由于没有什么比不上什么,运算符(包括!==)将始终返回false。

在您的not函数中,您要询问是否没有任何内容='next_page'始终为false(如上所述),因此not使其成为true和元素被选中。

您可以通过将一个类添加到其他锚标记之一然后使用!=版本来证明这一点。

请注意,您可以简化代码以仅使用xpath

doc.xpath('//div[@class="paginate_box"]/a[not(@class="next_page")][last()]').text 
#=> "3"
# Or  
doc.xpath('//div[@class="paginate_box"]/a[not(@class="next_page")][last()]/text()').to_s
#=> "3"

如果next_page定位符始终存在并且始终位于最后,并且最高页码始终位于其前面,则可以完全避免这种情况:

doc.xpath('//div[@class="paginate_box"]/a[position()=last()-1]').text
#=> "3"

在这里,我们要说的是在该div中最后一个之前的位置找到锚点。

替代:

doc.xpath('//div[@class="paginate_box"]/a[last()]/preceding-sibling::a[1]').text
#=> "3"

这将按自底向上的顺序找到最后一个锚,然后是所有锚同级,然后我们在该列表中选择第一个。