XPath 中艾弗森括号最简单的语法是什么?

taf*_*it3 2 xpath

我想在 XPath 表达式中使用 Iverson 括号(即映射 true => 1, false => 0)。

示例:而不是写

someNumber+(if(elem1/elem2[@attr='123'])then(1)else(0)))*someOtherNumber
Run Code Online (Sandbox Code Playgroud)

我想写(但不知何故没有“艾弗森”)

someNumber+Iverson(elem1/elem2[@attr='123'])*someOtherNumber
Run Code Online (Sandbox Code Playgroud)

以下不起作用:

someNumber+[elem1/elem2[@attr='123']]*someOtherNumber
Run Code Online (Sandbox Code Playgroud)

转换为布尔值工作:

someNumber+boolean(elem1/elem2[@attr='123'])*someOtherNumber
Run Code Online (Sandbox Code Playgroud)

有没有比“if(...)then(1)else(0)”或“boolean(...)”更简单的语法?

Abe*_*bel 5

艾弗森

有趣的是,在 XPath 中,您已经使用了带有or谓词的Iverson 括号语法版本,如果 EBV 为 true,则返回 true。但如果它计算结果为数字,它将返回序列中的第 n 项[@attr='123'][@attr]

为了进行讨论,为了简洁起见,让我们将您的表达式替换elem1/elem2[@attr='123']为:EXPR

X + EXPR * Y
Run Code Online (Sandbox Code Playgroud)

其想法是尽可能接近 EXPR 的 Iverson 语法。

XPath 2.0

您的表达式需要更少的括号:

X + if(EXPR) then 1 else 0 * Y
Run Code Online (Sandbox Code Playgroud)

假设 的 false-value 是一个空序列,也可以写成如下形式EXPR

X + (EXPR, 1, 0)[2] * Y
Run Code Online (Sandbox Code Playgroud)

有没有比“boolean(...)”更简单的语法?

您建议了该boolean(EXPR)函数,但正如您在评论中提到的,这不起作用,您需要将其转换为数字,例如:

X + number(boolean(EXPR)) * Y
Run Code Online (Sandbox Code Playgroud)

我认为 XPath 2.0 中最短的版本是空序列消除方法,但它可能并不总是有效,它需要第一项返回空序列。

如果您有一个将元素设置为布尔值的验证处理器,则可以使用:

X + number(EXPR) * Y
Run Code Online (Sandbox Code Playgroud)

或者,如果输入有效值为 0 和 1 的数字,则:

EXPR
Run Code Online (Sandbox Code Playgroud)

XPath 3.0

让我们看看使用新的 XPath 3.0 语法是否可以变得更简单:

let $Iv := function($i) { number(boolean($i)) }
return X + $Iv(EXPR) * Y
Run Code Online (Sandbox Code Playgroud)

使用 XQuery 和 XSLT,以及 XPath,您可以全局声明此变量,这会将表达式更改为:

X + $Yv(EXPR) * Y
Run Code Online (Sandbox Code Playgroud)

但您仍然需要处理括号,但请继续阅读......

XPath 3.1

在 3.1 中,引入了箭头运算符,它允许您的原始示例写为:

X + EXPR=>boolean()=>number() * Y
Run Code Online (Sandbox Code Playgroud)

鉴于我们现在有一个带有函数项的全局变量,我们可以这样做:

X + EXPR=>$Iv() * Y
Run Code Online (Sandbox Code Playgroud)

其他方法

由于将全局变量设置为匿名函数无非就是创建函数,因此我们也可以在 XQuery 或 XSLT 中声明函数。就像是:

X + EXPR=>i:v() * Y
Run Code Online (Sandbox Code Playgroud)