The expressions are equivalent provided that neither of the predicates is positional. A predicate is positional if (a) its value is numeric, or (b) its value depends on the current position in the dynamic context (for practical purposes, that means if it's an expression that calls the position()
function).
Assuming this condition is met, there is no good reason for preferring one expression over the other. It's possible of course that some XPath processor might evaluate one of them faster than the other, but it's very unlikely to be a signficant difference, and it could equally well favour either of the two.
There are minor differences in the degree of freedom offered to processors in how far they can go in optimising the constructs in ways that affect error handling, and these rules vary slightly between XPath versions, but again this is very unlikely to be significant in practice.
The equivalence doesn't apply to positional predicates because (a) when you write A[X][Y]
, the value of position()
within Y
is different from its value within X
, and (b) if X
or Y
is numeric then it is interpreted as position()=X
(or position()=Y
), and this doesn't apply to the operands of and
: you can't rewrite A[@code][1]
as A[@code and 1]
.