XForms/eXist
eXist 是一個具有完整 REST 介面的原生 XML 資料庫。 這使您可以使用 eXist 儲存表單資料,而無需編寫任何中介軟體粘合程式碼。
eXist 提供了一個完整的 REST 介面,可以輕鬆地從 XForm 呼叫。
eXist 還提供了一個完整的 WebDAV 介面。 這使您可以直接從表單執行 HTTP “PUT” 操作。
在本示例中,我們將建立一個名為“juser”(Jane User)的使用者,並設定一個集合來讀取和寫入表單資料。
要執行此程式,只需從 [1] 網站安裝 eXist。 使用 eXist 管理選單建立一個名為“juser”的使用者。 然後在 /db/home/juser 為 juser 建立一個主頁集合。 然後以 juser 身份登入並建立一個名為“test”的集合。 您將在此檔案中放置表單和例項資料。
要將例項資料讀寫到表單中,只需使用以下示例
<html>
<head>
<xf:model>
<xf:instance id="data-instance" src="data.xml" xmlns=""/>
<xf:submission id="read-from-file"
method="get"
action="https://:8080/exist/rest/db/home/juser/test/data.xml"
replace="instance" instance="data-instance"/>
<xf:submission id="save-to-file"
method="put"
action="https://:8080/exist/webdav/db/home/juser/test/data.xml"
replace="instance" instance="data-instance"/>
</xf:model>
</head>
...
請注意,如果資料與表單位於同一個集合中(不是一個好的長期設計),則可以使用相對路徑引用。 還要注意,我們正在對 eXist 的webdav(而不是 rest)介面執行 HTTP PUT 操作。
將 XML 資料直接載入到您的 XForms 應用程式中很容易。 在模型中的例項語句中,只需新增一個src 屬性,並放置您要編輯的檔案的路徑名。 關鍵是將“rest”一詞放在 URL 中,當您將資料讀入表單時
<xf:instance id="my-form-data" xmlns="" src="https://:8080/exist/rest/db/home/juser/test/data.xml"/>
在執行 HTTP PUT 時,請始終在 URL 路徑中新增“webdav”一詞。
https://:8080/exist/webdav/db/home/juser/test/data.xml
就這麼簡單!
有關更多資訊,請參閱 eXist 手冊,瞭解如何使用 eXist 的 REST 和 WebDAV 介面。
使用 XML 資料庫時,有時您希望資料庫接收 XML 文件並根據業務規則(例如 XML 文件的內容和日期)將其儲存在正確的位置。 這可以在關係資料庫中使用儲存過程來完成。
XQuery 可以被認為是面向 XML 的儲存過程。 eXist 允許您直接儲存到 XQuery 的 URL,並且 XQuery 可以根據許多規則儲存文件。
這是一個 eXist XQuery 示例,它接收 HTTP POST 並根據輸入文件中的縣和日期建立一個集合的路徑名。 在儲存檔案並檢查儲存是否成功後,它會增加一個計數器,類似於某些關係資料庫的 AUTOINCREMENT 屬性。
xquery version "1.0";
(: Save-crv.xq Version 0.1, Dan McCreary, March 2nd 2007:)
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xmldb="http://exist-db.org/xquery/xmldb";
declare namespace c="http://niem.gov/niem/common/1.0" ;
declare namespace u="http://niem.gov/niem/universal/1.0" ;
declare namespace mn="http://data.state.mn.us" ;
declare namespace mnr="http://revenue.state.mn.us" ;
declare namespace mnr-ptx="http://propertytax.state.mn.us" ;
declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";
(: to store a CRV into the right location in exist we need 1) the county ID, 2) the date, 3) the sequence number :)
(: get the data from an HTTP post :)
let $crv := request:get-data()
let $count := count($crv//node())
let $county-id := $crv//eCRVDocument/RealProperty/RealPropertyLegalDescriptions/mnr-ptx:MNCountyID/text()
(: let $county-id := '19' :)
let $current-year := substring(string(current-date()),1, 4)
let $current-year-2 := substring(string(current-date()),3, 2)
(: let $collection := xmldb:collection(concat('xmldb:exist:///db/crv/data', $county-id, '/', $current-year), "dan", "dan123") :)
let $county-name := doc('/db/crv/data/admin/next-county-crvid.xml')//County[CodeID=$county-id]/Code
(: get the next-id from the sequence counter :)
let $next-id := doc('/db/crv/data/admin/next-county-crvid.xml')//County[CodeID=$county-id]/NextID
let $file-name := concat($next-id, '.xml')
let $collection-string := concat('xmldb:exist:///db/crv/data/', $county-name, '/', $current-year)
let $full-path := concat($collection-string, '/', $file-name)
(: ready to login and store a file :)
let $collection := xmldb:collection($collection-string, "login", "password")
let $retStore := xmldb:store($collection-string, $file-name, <eCRVDocument>{$crv/*}</eCRVDocument>)
(: If the file that we attempted to store does eXist, then now it is OK to increment the sequence counter for the next user :)
let $retCode1 := if (doc($full-path))
then ( update replace doc("/db/crv/data/admin/next-county-crvid.xml")//County[CodeID=$county-id]/NextID with
<NextID>{$next-id + 1}</NextID> )
else ()
return
<data>
<county-id>{$county-id}</county-id>
<current-year>{$current-year-2}</current-year>
<sequence-id>{$next-id - 1}</sequence-id>
</data>
此 XQuery 返回一個 XML 訊息,例如以下內容
<data>
<county-id>19</county-id>
<current-year>07</current-year>
<sequence-id>47</sequence-id>
</data>
假設您已設定主機名、埠和應用程式名稱變數,則 XForms 應用程式將包含以下程式碼
<xf:model>
...
<xf:submission id="submit-validate-a1" method="post"
action="http://{$hostname}:{$exist-port}/{$application-name}/submit"
replace="instance" instance="submit-result">
<xf:toggle case="case-busy" ev:event="xforms-submit" />
<xf:toggle case="case-submit-error" ev:event="xforms-submit-error" />
<xf:toggle case="case-done" ev:event="xforms-submit-done" />
</xf:submission>
...
</xf:model>
...
<body>
...
<xf:case id="case-done">
<xf:group ref="instance('submit-result')">
<h1 class="result-text">Your ID is =
<xf:output ref="county-id"/>-<xf:output ref="current-year"/>-<xf:output ref="sequence-id"/></h1>
</xf:group>
...
</xf:case>
如果您希望您的 XQuery 返回正確的 mime 型別,請在序言中新增以下內容
declare option exist:serialize "method=xhtml media-type=text/xml indent=yes omit-xml-declaration=no";
declare namespace util="http://exist-db.org/xquery/util";
...
let $ret-code := util:declare-option("exist:serialize", "media-type=text/xml")
(Kurt Cagle 的建議)
declare option exist:serialize "method=3Dxhtml indent=3Dyes
omit-xml-declaration=3Dno
doctype-public=3D-//W3C//DTD XHTML 1.1//EN
doctype-system=3Dhttp://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd";