2017-03-15 83 views
1

我正在使用eXist-db創建基於Web的數據庫應用程序。 我的願望是將用戶在用XForms創建的公式中插入的數據保存到數據庫中。對於整個數據結構保存在變量$content我在數據庫中存儲與一個XQuery模塊,這樣的:在使用eXist-db和XQuery存儲數據之前更新內存中節點

declare 
    %rest:PUT("{$content}") 
    %rest:path("/items") 
function ffdb:change-items($content as node()*) { 
    let $data := <items> 
      { $content/items/* } 
     </items> 

    let $stored := xmldb:store($config:app-root, "1234.xml", $data) 

    return 
     doesnotmatter:function() 
}; 

在這個例子$內容包含以下節點集:

<items> 
    <item1>A</item> 
    <item2>B</item> 
    <itemlist> 
     <item3>C</item3> 
    <itemlist/> 
<items> 

這一工程精細。我現在的問題是,我想在將內容存儲到數據庫之前,將內容爲'D'的節點插入到$ content/items/itemlist中。存儲結果應該是:

<items> 
    <item1>A</item> 
    <item2>B</item> 
    <itemlist> 
     <item3>C</item3> 
     <item3>D</item3> 
    <itemlist/> 
<items> 

這似乎是更困難的,因爲我認爲。我試圖改變查詢一百次,我想。 當我嘗試直接在$content中插入節點集時,我收到XQuery更新表達式無法應用於內存節點的消息。 當我嘗試在聲明它存儲數據之後嘗試插入節點集$data時,但不幸的是沒有節點集。

我也是從https://github.com/ryanjdew/XQuery-XML-Memory-Operations安裝的模塊,然後在開始插入這樣的:

let $content2 := mem:copy($content) ! 
    ( 
    mem:insert-child(., $content/items/itemlist, attribute new-attribute {"item3"}), 
    mem:execute(.)) 

之後我插入$內容2,而不是$content同時宣佈$的數據。我得到的消息是:

org.exist.xquery.XPathException: mem-op:MIXEDSOURCES The nodes to change are coming from multiple sources [at line 249, column 3, source: /db/apps/myapp/modules/memoryoperations/memory-operations-pure-xquery.xqy] 

真的不知道該怎麼辦。我也嘗試在存儲它之後加載文檔並在此處插入節點集,以便我不更改內存數據,但這也不起作用。節點集沒有被插入。

+0

哪版本o親愛的? – joewiz

+0

請注意,您提供的示例XML格式不正確。 – joewiz

回答

0

您確定eXist的XQuery Update工具不支持內存中操作。另外一個身份變換(例如,使用XSLT或a recursive application of XQuery's typeswitch expression,瑞安J.露的圖書館,你發現了「純XQuery的」版本是一個可行的選擇。

假設你已經下載了https://github.com/ryanjdew/XQuery-XML-Memory-Operations庫,解壓縮它,並上傳所產生的文件夾/db/apps,該代碼會產生你所描述的預期效果(我使用了eXist 3.1.0和測試中的Exide代碼):

xquery version "3.1"; 

import module namespace mem-op="http://maxdewpoint.blogspot.com/memory-operations" at 
    "/db/apps/XQuery-XML-Memory-Operations-master/memory-operations-pure-xquery.xqy"; 

let $content := 
    <items> 
     <item1>A</item1> 
     <item2>B</item2> 
     <itemlist> 
      <item3>C</item3> 
     </itemlist> 
    </items> 
let $copy := mem-op:copy($content) 
let $insert := mem-op:insert-child($copy, $content/itemlist, element item3 {"D"}) 
return 
    mem-op:execute($insert) 

這將返回:

<items> 
    <item1>A</item1> 
    <item2>B</item2> 
    <itemlist> 
     <item3>C</item3> 
     <item3>D</item3> 
    </itemlist> 
</items> 
+0

感謝您的回答!真的沒有用。當我嘗試這個時,我在urlrewrite.log中獲得以下條目:'2017-03-16 08:46:06,402 [eXistThread-40]錯誤(XQueryURLRewrite.java [service]:382) - 處理/存在/應用程序時出錯/ myapp/items/item:mem-op:MIXEDSOURCES要更改的節點來自多個來源[在第249行,第3列,來源:/ db/apps/myapp/modules/memoryoperations/memory-operations-pure-xquery。 xqy]' – Felix

+1

哦,我的錯我在這裏插入了錯誤的路徑。而不是:'let $ insert:= mem-op:insert-child($ copy,$ content/itemlist,element item3 {「D」})''我寫了'let $ insert:= mem-op:insert-child $ copy,$ content/items/itemlist,element item3 {「D」})'現在可行。非常感謝! – Felix