Pushing an OR into the node check

51 Views Asked by At

To do an OR on two different nodes, I can do the following:

//C:Year[not(@value="2019")] | //R:Year[not(@value="2019")]

However, if there is a long expression, this becomes a bit unwieldy, especially if there are more than 2 ORs. Is there a way to do something like the following:

//(C:Year or R:Year)[not(@value="2019")]

Basically, is it possible rather than evaluate the full axis-node-predicate expression and OR-ing the full thing, to be able to put an OR within the node test itself.

1

There are 1 best solutions below

2
On BEST ANSWER

This (only) works in XPath 2.0+

//(C:Year | R:Year)[not(@value="2019")]

But, unfortunately, not in XPath 1.0.

The W3C XPath 1.0 language reference states under 3.1:

Parentheses may be used for grouping.

[14] Expr        ::= OrExpr   
[15] PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall

However /steps/ (*StepExpr) are not mentioned.

But the XPath 2.0 ref states:

Parentheses must be used when "/" is used on the left hand side of an operator, as in "(/) * 5".

With this hint I came up with this query that also works in XPath 1.0:

((//C:Year)|(//C:Year))[not(@value="2019")]

So, v2+ is more flexible but the same principle applies. Gustafson, M. Kay, and others discussed an XPath 2.0 bug long this lines leading to Errata XP.E3. D. Chamberlin:

On July 31, 2007, the Query and XSLT working groups agreed to add parentheses to the expansions of leading-/ and leading-// in path expressions, as suggested by this bug report. The revised expansions will appear in a future errata document. Regards, Don Chamberlin (for the joint working groups)