13

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変数が更新に失敗しているか、リセットされています。既存の変数を再割り当てできないのはなぜですか? 望ましい結果を得るためのより良い方法は何でしょうか?

4

7 に答える 7

22

'at'を使用してみてください:

for $d at $p in $collection
return 
element counter { $p }

これにより、各「$d」の位置がわかります。これを句と一緒に使用したい場合order by、位置はソート結果ではなく最初の順序に基づいているため、これは機能しません。これを克服するには、FLWOR 式の並べ替えられた結果を変数に保存atし、最初の並べ替えられた結果を反復するだけの 2 番目の FLWOR で句を使用します。

let $sortResult := for $item in $collection
                   order by $item/id
                   return $item

for $sortItem at $position in $sortResult
return <item position="{$position}"> ... </item>
于 2012-04-24T09:29:27.567 に答える
9

@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)

とはいえ、あなたの例では、at $count@tohuwawohu で示されているように必ず使用する必要があります。

于 2012-04-24T10:01:27.283 に答える
6

も使用できる MarkLogic 固有のxdmp:set. しかし、これは関数型言語の仮定を破るので、慎重に使用してください。

http://docs.marklogic.com/5.0doc/docapp.xqy#display.xqy?fname=http://pubs/5.0doc/apidoc/ExsltBuiltins.xml&category=Extension&function=xdmp:set

xdmp:set実際のコードの例として、検索パーサーhttps://github.com/mblakele/xqysp/blob/master/src/xqysp.xqyが役立つ場合があります。

于 2012-04-24T18:50:56.330 に答える
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=で実際に試すことができます。

于 2012-04-24T11:55:15.920 に答える
6

不変変数

XQuery は関数型プログラミング言語であり、とりわけ不変変数を使用するため、変数の値を変更することはできません。一方、強力な関数のコレクションが利用可能で、日常のプログラミングの問題の多くを解決します。

let $count := 0
for $prod in $collection]
  let $count := $count + 1
return 
<counter>{$count }</counter>

let $count1行目では、この変数をすべてのスコープで定義しています。この場合、すべての次の行です。3 行目では、このコード ブロック内の後続のすべての行で有効なlet $countnew$countを定義していますが、これは定義されていません。したがって、実際には 1 ずつ3 回インクリメントしますが、結果はすぐに破棄します。0+1$count

BaseX ' query info は、このクエリの最適化されたバージョンを示しています。

for $prod in $collection
  return element { "counter" } { 1 }

ソリューション

の要素の総数を取得するには$collection、次を使用できます

return count($collection)

XQuery 関数のリストについては、XQuery 関数のリストとモジュールとして含めることができるその他の便利な関数の両方を含むfunctx の XQuery 部分を見ることができます。

于 2012-04-24T09:16:49.083 に答える
4

xdmp:set以下のクエリの代わりに使用

let $count := 0
for $prod in (1 to 4)
return ( xdmp:set($count,number($count+1)) ,<counter>{$count }</counter> 
于 2015-03-04T12:23:18.523 に答える