XQuery计数器里面的for

时间:2011-04-13 16:20:42

标签: xml xquery counter

假设我有以下XQuery代码:

   for $y in doc("file.xml")/A/B

        for $x in $y/C where $x/constraint1 != "-" and $x/constraint2 > 2.00
            do stuff 

我可以使用计数器来计算我的代码在第二个for循环中输入的数量吗? 我试过这个:

   for $y in doc("file.xml")/A/B
       let $i := 0
        for $x in $y/C where $x/constraint1 != "-" and $x/constraint2 > 2.00
            $i := $i + 1

但是我遇到了编译错误。我还需要总结一些这样的约束:

   for $y in doc("file.xml")/A/B
       let $i := 0
       let $sum := 0
        for $x in $y/C where $x/constraint1 != "-" and $x/constraint2 > 2.13
            $i := $i + 1
            $sum := $sum + $x/constraint2

但当然这也不起作用:(。

任何建议都将受到高度赞赏。 另外,你能建议一本好的书/教程/网站来做这些事吗?

4 个答案:

答案 0 :(得分:17)

你不经常需要它,但是如果你真的需要在XQuery for expression中使用一个计数器变量(类似于xsl:for-each中的position())你可以使用“at”变量

for $x at $pos in //item return
  <item position="{$pos}" value="{string($x)}"/>

答案 1 :(得分:0)

我认为你并不了解陈述范式的基础知识。

总计数和总和将是:

let $items := doc('file.xml')/A/B/C[constraint1 != '-' and constraint2 > 2.13]
return ('Count:', count($items), 'Sum:', sum($items/constraint2))

部分计数和总和将是:

let $items := doc('file.xml')/A/B/C[constraint1 != '-' and constraint2 > 2.13]
for $pos in (1 to count($items))
return ('Count:', $pos, 'Sum:', sum($items[position() le $pos]/constraint2))

答案 2 :(得分:0)

要循环显示计数器,最好也更简单的方法是在for循环中添加 at $ pos 。 $ pos将作为一个柜台。

代码段:

{for $artist **at $pos** in (/ns:Entertainment/ns:Artists/ns:Name)

  return
      <tr><td>{$pos}&nbsp;&nbsp;
    {$artist}</td></tr>

}

输出

1   Artist

2   Artist 

3   Artist 

4   Artist

5   Artist

6   Artist

答案 3 :(得分:0)

这是另一种解决方案,如果您不想对集合中的每个项目进行计数或操作,但您只想计算/行动,如果某个条件适用。 在这种情况下,您可能会记住XQuery的函数式编程范例,并使用递归函数调用实现此计数/操作:

declare function ActIf($collection as element(*)*, $index as xs:integer, $indexMax as xs:integer, $condition as xs:string, $count as xs:integer) as xs:integer
{
if($index <= $indexMax) then
    let $element := $collection[$index]
    if($element/xyz/text() eq $condition) then
        (: here you can call a user-defined function before continuing to the next element :)
        ActIf($collection, $index + 1, $indexMax, $condition, $count + 1)
    else
        ActIf($collection, $index + 1, $indexMax, $condition, $count)
else (: no more items left:)
    $count
};

更简单的方法是使用适当的XPath表达式:

for $element at $count in $collection[xyz = $condition]
return
    (: call your user-defined function :)

甚至

myFunction($collection[xyz = $condition])

如果你想用XQuery实现更复杂的东西,那么递归解决方案可能会非常有用......