我想在xquery中创建一个计数器.我最初的尝试看起来如下:
let $count := 0
for $prod in $collection
let $count := $count + 1
return
<counter>{$count }</counter>
Run Code Online (Sandbox Code Playgroud)
预期结果:
<counter>1</counter>
<counter>2</counter>
<counter>3</counter>
Run Code Online (Sandbox Code Playgroud)
实际结果:
<counter>1</counter>
<counter>1</counter>
<counter>1</counter>
Run Code Online (Sandbox Code Playgroud)
该$count
变量或者未能更新或处于复位状态.为什么我不能重新分配现有变量?什么是获得理想结果的更好方法?
toh*_*ohu 22
尝试使用'at':
for $d at $p in $collection
return
element counter { $p }
Run Code Online (Sandbox Code Playgroud)
这将为您提供每个'$ d'的位置.如果要与order by
子句一起使用它,这将不起作用,因为位置基于初始顺序,而不是排序结果.为了克服这个问题,只需将FLWOR表达式的排序结果保存在变量中,并at
在第二个FLWOR中使用该子句,该FLWOR只迭代第一个排序结果.
let $sortResult := for $item in $collection
order by $item/id
return $item
for $sortItem at $position in $sortResult
return <item position="{$position}"> ... </item>
Run Code Online (Sandbox Code Playgroud)
正如@Ranon所说,所有XQuery值都是不可变的,因此您无法更新变量.但是如果你真的需要一个可更新的数字(不应该太频繁),你可以使用递归:
declare function local:loop($seq, $count) {
if(empty($seq)) then ()
else
let $prod := $seq[1],
$count := $count + 1
return (
<count>{ $count }</count>,
local:loop($seq[position() > 1], $count)
)
};
local:loop($collection, 0)
Run Code Online (Sandbox Code Playgroud)
这与您的示例完全一样.
在XQuery 3.0中,甚至在标准库中定义了此函数的更通用版本:fn:fold-right($ f,$ zero,$ seq)
也就是说,在你的例子中,你绝对应该使用at $count
@tohuwawohu所示.
XQuery是一种函数式编程语言,其中包含不可变变量,因此您无法更改变量的值.另一方面,您可以使用功能强大的函数集,从而解决了许多日常编程问题.
let $count := 0
for $prod in $collection]
let $count := $count + 1
return
<counter>{$count }</counter>
Run Code Online (Sandbox Code Playgroud)
let $count
第1行定义了所有范围内的变量,在这种情况下都是以下行.let $count
第3行定义了一个新的$count
,它在此代码块0+1
中的所有后续行中有效- 未定义.所以你确实增加了三倍,但立即丢弃了结果.$count
BaseX的查询信息显示了此查询的优化版本
for $prod in $collection
return element { "counter" } { 1 }
Run Code Online (Sandbox Code Playgroud)
要获得元素的总数$collection
,您可以使用
return count($collection)
Run Code Online (Sandbox Code Playgroud)
有关XQuery函数的列表,您可以查看functx的XQuery部分,其中包含XQuery函数列表以及一些其他有用的函数,这些函数可以作为模块包含在内.
上面的所有解决方案都是有效的,但我想提一下,您可以使用XQuery Scripting扩展来设置变量值:
variable $count := 0;
for $prod in (1 to 10)
return {
$count := $count + 1;
<counter>{$count}</counter>
}
Run Code Online (Sandbox Code Playgroud)
你可以在http://www.zorba-xquery.com/html/demo#twh+3sJfRpHhZR8pHhOdsmqOTvQ=上试试这个例子.
具体到MarkLogic,您也可以使用xdmp:set
.但这打破了功能语言的假设,因此保守地使用它.
有关xdmp:set
实际代码的示例,搜索解析器https://github.com/mblakele/xqysp/blob/master/src/xqysp.xqy可能会有所帮助.