sparklemotion/nokogiri

CSS `foo~:nth-child(2)` gives incorrect XPath

Open

#707 创建于 2012年6月18日

在 GitHub 查看
 (3 评论) (0 反应) (0 负责人)Ruby (5,615 star) (806 fork)batch import
help wantedneeds/fix-for-failing-testtopic/css

描述

Hi,

I’m the maintainer of cssselect, which does in Python pretty much the same as Nokogiri for CSS selectors: translate them to XPath. It looks like the SimonSapin/cssselect#12 bug also applies to Nokogiri. Namely, the XPath translation of :nth-child() and similar pseudo-classes is wrong when used after the + or ~ combinator. Here is a test case:

require 'nokogiri'
doc = Nokogiri::XML('<root><child1/><child2/><child3/></root>')
puts doc.css(':nth-child(2)').map { |e| e.name }
puts doc.css('child1 ~ :nth-child(2)').map { |e| e.name }

Expected output: child2 child2. Actual output child2 child3.

The problem is in the XPath translation of the later selector: //child1/following-sibling::*[position() = 2 and self::*] gives the element at position 2 when counting from child1, while we want the position among the parent’s children.

I am not sure it is even possible to correctly translate this selector to XPath: the = XPath operator on node-sets compares the text content of elements, not their identity.

The issue is similar for SimonSapin/cssselect#4 and Nokogiri’s #394.

贡献者指南