跳至内容

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://127.0.0.1:8080/exist/rest/db/home/juser/test/data.xml" 
            replace="instance" instance="data-instance"/>
         <xf:submission id="save-to-file"
            method="put"
            action="https://127.0.0.1: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://127.0.0.1:8080/exist/rest/db/home/juser/test/data.xml"/>

在执行 HTTP PUT 时,请始终在 URL 路径中添加“webdav”一词。

 https://127.0.0.1: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
华夏公益教科书