How to choose for multiple classes using Nokogiri and Ruby

From a table element, I would like to select all rows that have an even class or an odd class.

I tried jQuery syntax:

 report.css("table.data tr[class~=odd even]").each{|line| parse_line_item(line)} 

but he threw a mistake, any help is appreciated, thanks.

+4
source share
2 answers

Use two selectors: report.css("table.data tr.odd, table.data tr.even")

The ~= operator in the CSS attribute selector checks to see if the value matches a list of classes separated by spaces. For example, tr[class~=odd] will match <tr class="odd"> and <tr class="odd ball"> . However, in the particular case of the class attribute, the best selector is simply tr.odd .

If you use the ~= operator with a space in the value (as in tr[class~="odd even"] , the selector will never match anything.

+10
source

The CSS selector you have doesn't even have a syntactically valid selector:

 [class~=odd even] 

Values ​​containing spaces should always be specified, so the correct way to write this selector would be:

 [class~="odd even"] 

However, this selector cannot really match anything: the selector of the attribute values [attr~=val] matches ...

an element with the attribute att , whose value is a list of words separated by spaces, one of which is exactly equal to "val" . If "val" contains spaces, it will never represent anything (since words are separated by spaces)

Since words are separated by spaces, this means that they can never contain spaces. But the word you are looking for ( "odd even" ) contains spaces, so it cannot match anything.

Presumably, what you are looking for is an OR combinator, but it does not exist. So what you are looking for cannot be expressed using CSS selectors.

Well, actually, this is not so: it can be expressed using CSS selectors. You can simply use selector groups that give you a set of match joins, which is equivalent to using the OR combinator:

 table.data tr.odd, table.data tr.even 

Remember: CSS is set-based, so order doesn't matter. In your case, order matters, which means CSS is really the wrong tool to work with:

 report.xpath('//table[@class="data"]//tr[@class="odd" or @class="even"') 

Although I have to admit that I'm not sure why you are not just using something like this:

 report.css('table.data tr') 

After all, does not select all the odd and all the even lines the same as selecting all the lines? I mean, what else did you get there, irrational lines?

+2
source

Source: https://habr.com/ru/post/1305306/


All Articles