sparklemotion/nokogiri

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

Open

#707 aberto em 18 de jun. de 2012

Ver no GitHub
 (3 comments) (0 reactions) (0 assignees)Ruby (806 forks)batch import
help wantedneeds/fix-for-failing-testtopic/css

Métricas do repositório

Stars
 (5.615 stars)
Métricas de merge de PR
 (Nenhuma PRs mesclada em 30d)

Description

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.

Guia do colaborador