They are not competitors: XQuery 3.1 *contains* XPath 3.1. Every valid XPath expression is a valid XQuery, which is why a bare path like //album runs fine in an XQuery processor. The question is never which language is better — it is whether your task needs the things XQuery adds on top.
XPath on the Music Playlist sample:
//album[count(tracks/track) > 3]/title
Pure XPath: it selects existing nodes from the document. That is all XPath can do — the nodes come back as they are.
XQuery 3.1 on the Music Playlist sample:
<long-albums>{
for $a in //album
let $n := count($a/tracks/track)
where $n > 3
order by $n descending
return <album tracks="{$n}">{string($a/title)}</album>
}</long-albums>
The same selection in XQuery — but now the result is a new document: a <long-albums> wrapper, an ordering, and a computed tracks attribute that exists nowhere in the source.
Use XPath when you want to *find* nodes in a document that already exists. Use XQuery when you want to *build* something — a different shape, a summary, a join across two documents, a report.
| Capability | XPath 3.1 | XQuery 3.1 |
|---|---|---|
| Select nodes by path, axis, predicate | Yes | Yes |
| Full function library, maps, arrays, sequences | Yes | Yes |
| Return nodes that already exist | Yes | Yes |
| Construct new elements and attributes | No | Yes — direct and computed constructors |
for / let / where / order by / return | for and let only | Full FLWOR |
| Declare namespaces, functions, variables up front | No | Yes — the prolog |
| Branch on a node's type | No | typeswitch |
| Where it typically runs | Browsers, Selenium, XSLT, config files | XML databases and processors |
Most of the confusion in this comparison is not XPath versus XQuery at all — it is XPath 1.0 versus 3.1. XPath 1.0 is what browsers, Selenium locators, and most older tooling implement, and it has no sequences, no let, no for, and a much smaller function library.
If your expression has to run in a browser or a Selenium locator, you are writing 1.0 and neither 3.1 nor XQuery features are available to you. The Sandbox has a version toggle so you can tell a syntax error apart from a version problem in one click.
XQuery is not XSLT. Both transform XML, but XSLT is template- and rule-driven while XQuery reads as a programming language — and a document that arrives in an unpredictable shape is often easier in XSLT than in XQuery.
XQuery is also not a full data-manipulation language on its own. Updating expressions (insert, delete, replace) are a separate specification, and the engine here does not implement them — nor XQuery modules or fn:transform. The engine-support page lists every gap with a portable rewrite.