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



为了模拟 XQuery 更新中的自动增量值,假设首次运行时<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.NodeDocument,甚至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 中使用自动增量值的任何其他聪明想法也非常受欢迎,但是请参阅使用 XQuery 更新自动递增?

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

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

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

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

上面,xquery:指的是 BaseX 模块。

相关内容

  • 没有找到相关文章

最新更新