Reputation: 550
I would like to use Iverson bracket (ie. mapping true => 1, false => 0) in the XPath expression.
Example: instead of writing
someNumber+(if(elem1/elem2[@attr='123'])then(1)else(0)))*someOtherNumber
I would like to write (but somehow without the "Iverson")
someNumber+Iverson(elem1/elem2[@attr='123'])*someOtherNumber
The following doesn't work:
someNumber+[elem1/elem2[@attr='123']]*someOtherNumber
Casting to boolean works:
someNumber+boolean(elem1/elem2[@attr='123'])*someOtherNumber
Is there a more simple syntax than "if(...)then(1)else(0)" or "boolean(...)"?
Upvotes: 2
Views: 151
Reputation: 57189
Interestingly, in XPath you already use a version of the Iverson bracket syntax with predicates in [@attr='123']
or [@attr]
, which returns true if its EBV is true. But if it evaluates to a number, it will return the nth item from the sequence.
For the discussion, let's replace your expression elem1/elem2[@attr='123']
with EXPR
for brevity, and the rest like:
X + EXPR * Y
Where the idea is to get as close as possible to the Iverson syntax for EXPR.
Your expression requires less parentheses:
X + if(EXPR) then 1 else 0 * Y
This can also be written as the following, assuming false-value of EXPR
is an empty sequence:
X + (EXPR, 1, 0)[2] * Y
Is there a more simple syntax than "boolean(...)"?
You suggested the boolean(EXPR)
function, but as you mentioned in the comments, this will not work, you need to convert it to a number, for instance with:
X + number(boolean(EXPR)) * Y
I think the shortest version in XPath 2.0 is the empty-sequence dismissal approach, but it may not always work, it requires the first item to return the empty sequence.
If you have a validating processor that sets the element as boolean, you can use:
X + number(EXPR) * Y
Or if typed as a number with valid values 0 and 1, just:
EXPR
Let's see if with the new XPath 3.0 syntax we can get even simpler:
let $Iv := function($i) { number(boolean($i)) }
return X + $Iv(EXPR) * Y
With XQuery and XSLT, but also XPath, you can declare this variable globally, which changes the expression into:
X + $Yv(EXPR) * Y
But you'll still have to deal with the parentheses, but keep reading...
In 3.1, the arrow operator has been introduced, which allows your original example to be written as:
X + EXPR=>boolean()=>number() * Y
Given that we now have a global variable with a function item, we can do:
X + EXPR=>$Iv() * Y
Since setting a global variable to an anonymous function is nothing more than creating a function, we can also declare a function in XQuery or XSLT. Something like:
X + EXPR=>i:v() * Y
Upvotes: 5