我想在xquery中创建一个计数器。我最初的尝试如下所示:
let $count := 0
for $prod in $collection
let $count := $count + 1
return
<counter>{$count }</counter>
预期结果:
<counter>1</counter>
<counter>2</counter>
<counter>3</counter>
实际结果:
<counter>1</counter>
<counter>1</counter>
<counter>1</counter>
$count
变量无法更新或重置。为什么我不能重新分配现有变量?什么是获得理想结果的更好方法?
答案 0 :(得分:22)
尝试在:
使用'for $d at $p in $collection
return
element counter { $p }
这将为您提供每个'$ d'的位置。如果要将此与order by
子句一起使用,则这将不起作用,因为该位置基于初始顺序,而不是基于排序结果。要解决这个问题,只需将FLWOR表达式的排序结果保存在变量中,并在第二个FLWOR中使用at
子句,该FLWOR只迭代第一个排序结果。
let $sortResult := for $item in $collection
order by $item/id
return $item
for $sortItem at $position in $sortResult
return <item position="{$position}"> ... </item>
答案 1 :(得分:8)
正如@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)
这与您的示例完全一样。
在 XQuery 3.0 中,甚至在标准库中定义了此函数的更通用版本:fn:fold-right($f, $zero, $seq)
那就是说,在你的例子中,你绝对应该使用@ {huhuwohu所示的at $count
。
答案 2 :(得分:6)
XQuery是functional programming language,其中包含不可变变量,因此无法更改变量的值。另一方面,您可以使用功能强大的函数集,这可以解决许多日常编程问题。
let $count := 0
for $prod in $collection]
let $count := $count + 1
return
<counter>{$count }</counter>
第1行中的 let $count
在所有范围内定义了此变量,在这种情况下,这些变量都是以下行。第3行中的let $count
定义了一个新的$count
0+1
,在此代码块中的所有后续行中有效 - 未定义。所以你确实将$count
增加了三倍,但立即丢弃了结果。
BaseX'查询信息显示此查询的优化版本
for $prod in $collection
return element { "counter" } { 1 }
要获取$collection
中的元素总数,您只需使用
return count($collection)
有关XQuery函数的列表,您可以查看XQuery part of functx,其中包含XQuery函数列表以及一些其他有用的函数,这些函数可以作为模块包含在内。
答案 3 :(得分:6)
上面的所有解决方案都有效,但我想提一下,您可以使用XQuery Scripting扩展来设置变量值:
variable $count := 0;
for $prod in (1 to 10)
return {
$count := $count + 1;
<counter>{$count}</counter>
}
您可以在http://www.zorba-xquery.com/html/demo#twh+3sJfRpHhZR8pHhOdsmqOTvQ=
上试用此示例答案 4 :(得分:6)
特定于MarkLogic,您也可以使用xdmp:set
。但这打破了功能语言的假设,所以保守地使用它。
有关实际代码中xdmp:set
的示例,搜索解析器https://github.com/mblakele/xqysp/blob/master/src/xqysp.xqy可能会有所帮助。
答案 5 :(得分:4)
使用xdmp:set
代替以下查询
let $count := 0
for $prod in (1 to 4)
return ( xdmp:set($count,number($count+1)) ,<counter>{$count }</counter>
答案 6 :(得分:2)
我认为你正在寻找类似的东西:
<强> XQUERY:强>
for $x in (1 to 10)
return
<counter>{$x}</counter>
<强>输出:强>
<counter>1</counter>
<counter>2</counter>
<counter>3</counter>
<counter>4</counter>
<counter>5</counter>
<counter>6</counter>
<counter>7</counter>
<counter>8</counter>
<counter>9</counter>
<counter>10</counter>