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 代码中定义节点,然后将其绑定org.w3c.dom.Nodeor Document,甚至String。喜欢:

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 更新过程成为我在变量本身中包含的表达式?

(在 XQuery 中使用自动增量值的任何其他聪明的想法也非常受欢迎,但是请参阅Auto increment with XQuery Update?

4

2 回答 2

3

XQuery Update的转换表达式可能会对您有所帮助。它可用于修改主存中的现有节点。您的示例可以重写如下:

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 回答