我可以让XQuery在与XQJ绑定的变量中评估{$ expression}吗?

时间:2012-10-02 20:40:56

标签: java xquery basex xquery-update

为了模仿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>

......很好地屈服:

org.w3c.dom.Node

但是,我想在我的Java代码中定义节点,然后bind定义DocumentString,甚至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。将节点绑定为{{1}}值具有相同的效果。

当然,这是对“XQuery注入”的一个很好的保护。那么:有没有办法让XQuery Update进程成为变量本身的封闭表达式?

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

2 个答案:

答案 0 :(得分:2)

XQuery Update的transform expression可能会对您有所帮助。它可用于修改主存储器中的现有节点。您的示例可以重写如下:

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

转换表达式的当前语法是首先需要习惯的。更好的可读语法可能受官方规范的未来版本的限制。

答案 1 :(得分:1)

说到注入...为什么不直接将节点作为字符串传递并使用basex:eval()?

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

上方,xquery: refers to a BaseX module