0

XQuery Updateで自動インクリメント値を模倣するために<root count="0"/>、これを初めて実行する場合を想定して、以下は正常に機能します。

let $count := /root/@count
return (
  insert node <node id='{ $count }'/> into /root,
  replace value of node $count with $count + 1  
)

...うまく譲ります:

<root count="1">
  <node id="0">
</root>

ただし、Javaコードでノードを定義し、それをor、または、またはとしてバインドしたいと思います。好き:org.w3c.dom.NodeDocumentString

String expr =
     " declare variable $n external; "
   + " let $count := /root/@count; "
   + " return ( "
   + "   insert node $n into /root, "
   + "   replace value of node $count with $count + 1 "
   + " ) ";
XQConnection xqc = ...;
XQPreparedExpression xqp = xqc.prepareExpression(expr);
// org.w3c.dom.Node node is <node id='{ $count }'/>
xqp.bindNode(new QName("n"), node, null);
xqp.executeQuery();

ただし、これにより、属性にテキストが残ります。 { $count }ノードを値としてバインドしxs:stringても同じ効果があります。

もちろん、これは「XQueryインジェクション」に対する優れた保護です。それでも:XQuery Updateに、変数自体にある囲まれた式を処理させる方法はありますか?

(XQueryで自動インクリメント値を使用する他の賢いアイデアも大歓迎ですが、XQuery Updateで自動インクリメントを参照してください?

4

2 に答える 2

3

XQueryUpdateの変換式がここで役立つ場合があります。メインメモリ内の既存のノードを変更するために使用できます。あなたの例は次のように書き直すことができます:

declare variable $n external;

let $count := /root/@count
let $n :=
  copy $c := $n
  modify replace value of node $c/node/@id with $count
  return $c
return (
  insert node $n into /root,
  replace value of node $count with $count + 1
)

外部ノードが変数に$nコピーされ、ルートノードの属性が現在の値のに置き換えられます。$c@id$count

もちろん、このアプローチには多くのバリエーションがあります。@idたとえば、ダミーを置き換える代わりに、新しい属性を挿入できます。

  copy $c := $n
  modify insert node attribute id { $count } into $c/node
  return $c

変換式の現在の構文は、最初に慣れる必要があるものです。より読みやすい構文は、公式仕様の将来のバージョンの対象となる可能性があります。

于 2012-11-03T18:18:16.687 に答える
2

インジェクションと言えば...ノードを文字列として渡してbasex:eval()を使用しないのはなぜですか?

String node = "<node id='{ $count }'/>";
String expr =
   ...
   + "   insert node xquery:eval($n) into /root, "
   ...

上記はxquery: 、BaseXモジュールを指します

于 2012-10-02T22:42:14.923 に答える