跳至內容

XForms/eXist

來自華夏公益教科書

eXist 是一個具有完整 REST 介面的原生 XML 資料庫。 這使您可以使用 eXist 儲存表單資料,而無需編寫任何中介軟體粘合程式碼。

eXist REST 介面

[編輯 | 編輯原始碼]

eXist 提供了一個完整的 REST 介面,可以輕鬆地從 XForm 呼叫。

eXist WebDAV 介面

[編輯 | 編輯原始碼]

eXist 還提供了一個完整的 WebDAV 介面。 這使您可以直接從表單執行 HTTP “PUT” 操作。

eXist 示例

[編輯 | 編輯原始碼]

在本示例中,我們將建立一個名為“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 操作。

使用 eXist URL

[編輯 | 編輯原始碼]

將 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 介面。

使用 XQuery 返回文件 ID

[編輯 | 編輯原始碼]

使用 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 型別

[編輯 | 編輯原始碼]

如果您希望您的 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&#160;XHTML&#160;1.1//EN
doctype-system=3Dhttp://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd";


下一頁: IBM DB2 | 上一頁: XML 資料庫
首頁: XForms
華夏公益教科書