Openhood

CSS3 Expression to XPath with Nokogiri

Image by by Blake Sherman on unsplash

Nokogiri is such a wonderful library. Today we were trying to get the equivalent xpath query from a css expression and we found a fun way to do it automatically using Nokogiri.

Install nokogiri

First step is to have nokogiri installed

gem install nokogiri

Try it in irb

Open a terminal and start irb

irb

Then try some fun translations, require Rubygems and Nokogiri:

require "rubygems"
# => true
require "nokogiri"
# => true

Let’s try to get all the first TRs from the TBODYs (skipping the first one) in a TABLE

Nokogiri::CSS.parse("table tbody:nth-child(n+2) tr:nth-child(1)").first.to_xpath
# => "//table//tbody[(position() >= 2) and (((position()-2) mod 1) = 0)]//*[position() = 1 and self::tr]"

Now let’s get all the as direct children of a p whose class attribute finish by facebox

Nokogiri::CSS.parse("p > a:not([@class$=facebox])").first.to_xpath
# => "//p/a[not(substring(@class, string-length(@class) - string-length('facebox') + 1, string-length('facebox')) = 'facebox')]"

We can even get multiple at once

Nokogiri::CSS.parse("div[@class*=comments] p[@class=comment]:last-child, a[@class*=facebox]").map{|css| css.to_xpath }
# => ["//div[contains(@class, 'comments')]//p[@class = 'comment' and last-child(.)]", "//a[contains(@class, 'facebox')]"]

As you could see the XPath queries generated are a little bit verbose, but at least you can quickly get a working query if you’re more familiar with CSS3 expressions.

Copyright © 2024 Openhood SARL