2012-10-02 62 views
1

爲了模擬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代碼中定義節點,然後bind作爲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 Update過程在變量本身中包含一個封閉的表達式?

(任何其他奇思妙想XQuery中使用自動增量值都非常歡迎過,但後來看到Auto increment with XQuery Update?)注射

回答

1

說起......爲什麼不直接通過該節點作爲一個字符串,並使用basex:的eval()?

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

以上,xquery:refers to a BaseX module

+0

啊,我不知道'basex:'函數。它會爲BaseX引入一個鎖定,但它可能確實是要走的路。我想我會先插入一個空節點來獲取'id = ...'固定的,然後在第二次調用數據庫更新時,用常規方式用實際用戶生成的數據來避免注入。或者,我也可以首先插入一個Java生成的UUID作爲id = ...的整個節點,然後在第二次調用數據庫時替換這個(已知的)UUID。 – Arjan

+0

這[現在可能是'xquery:eval'](http://docs.basex.org/wiki/XQuery_Module)? *「該模塊在7.3版本中引入,功能已從廢棄的實用程序模塊中採用。」* – Arjan

+0

啊,事實上'basex:'不再是了; BaseX 6.3.2發行說明狀態:* [ADD] XQuery:新的「db:」和「util:」函數,取代「basex:」* – Arjan

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 

transform表達式的當前語法是一個東西需要去適應第一。更好的可讀語法可能會受到官方規範的未來版本的影響。

+0

非常非常好!我認爲這實際上答案[使用XQuery更新的自動增量?](http://stackoverflow.com/questions/2561067/auto-increment-with-xquery-update)(而不是實際使XQuery從XQJ語句解釋封閉的表達式在我的Java代碼中)。 – Arjan

+0

真的!我已經添加了對此線程的反向引用。 –