How to map CSS selectors to XPath queries
Over in the use Perl journals, Tatsuhiko Miyagawa wondered whether CSS selectors can be translated to XPath – which, of course, they can. Like him, however, I discovered that there isn’t any easily found table of equivalents that shows how selectors map to queries (though quite a lot of working Javascript to do such a conversion). Maybe that’s because to people versed in XPath, it’s really quite straightforward and obvious, but I decided to take 5 minutes to knock out some Google fodder.
So here you go:
CSS Pattern | XPath equivalent | Meaning |
---|---|---|
* |
* |
Matches any element. |
E |
E |
Matches any E element (i.e., an element of type E). |
E F |
E//F |
Matches any F element that is a descendant of an E element. |
E > F |
E/F |
Matches any F element that is a child of an element E. |
E:first-child |
*[1]/self::E |
Matches element E when E is the first child of its parent. |
E:lang(c) |
E[ @xml:lang = "c" |
Matches element of type E if it is in (human) language c (the document language specifies how language is determined). |
E + F |
E/following-sibling::*[1]/self::F |
Matches any F element immediately preceded by an element E. |
E[foo] |
E[ @foo ] |
Matches any E element with the "foo" attribute set (whatever the value). |
E[foo="warning"] |
E[ @foo = "warning" ] |
Matches any E element whose "foo" attribute value is exactly equal to "warning". |
E[foo~="warning"] |
E[ contains( |
Matches any E element whose "foo" attribute value is a list of space-separated values, one of which is exactly equal to "warning". |
E[lang|="en"] |
E[ @lang = "en" |
Matches any E element whose "lang" attribute has a hyphen-separated list of values beginning (from the left) with "en". |
DIV.warning |
DIV[ contains( |
HTML only. The same as DIV[class~="warning"]. |
E#myid |
E[ @id = "myid" ] |
Matches any E element ID equal to "myid". |
Obviously, the E:link
, E:visited
, E:active
, E:hover
and E:focus
selectors have no equivalent XPath query so I left them out.
The table in the spec doesn’t include examples of the shorthand notation for class or ID selectors that apply to any element (.warning
and #myid
, respectively), but they’re simply the same as *.warning
and *#myid
, from which follows how to translate them.
Lastly, any XPath query translated from a CSS selector needs to begin with //
.
That’s all there is to it.