我们正在开发一个带有 xforms(带有 XSLTForms 客户端)和 BaseX 的应用程序,用于管理历史实体(参与者)并进行网络分析。在我们的一个表单中,我们填写了演员与其亲属之间的关系,我们希望在提交表单时为每个亲属创建并提交一个预填充的实例……</p>
…但我们对多次提交有问题。
基本上,我们有 3 个实例:
instance('entity')
, 为主要形式
<xf:instance id="entity">
<entity xmlns="">
<name>John Doe</name>
<age>35</age>
<address>North Cap</address>
<relations>
<relation ref="" type="sibling">Elisa Doe</relation>
<relation ref="" type="parent">Richard Doe</relation>
</relations>
</entity>
</xf:instance>
instance('newEntity')
relation
, 为每个in依次填写和发送instance('entity')
(例如我们只是复制 name 值)
<xf:instance id="newEntity">
<entity xmlns="">
<name/>
<age/>
<address/>
<relations>
<relation ref="" type=""/>
</relations>
</entity>
</xf:instance>
instance('iterate')
, 用于循环提交instance('newEntity')
(when instance('iterate') = 1, we processrelation[position() = 1]
等
<xf:instance id="iterate">
<iterate xmlns=""/>
</xf:instance>
这是我们的提交过程:
首先,我们用触发器启动循环,同时我们提交的relation
值超过 ; 发送完所有关系后,我们提交主表单。instance('iterate')
instance('newEntity')
<xf:trigger>
<xf:label>submit</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('iterate')" value="1"/>
<xf:setvalue ref="instance('newEntity')/name" value="instance('entity')/relations/relation[position() = instance('iterate')]"/>
<xf:action while="count(//relation) >= instance('iterate')">
<xf:send submission="submitNewEntity"/>
<xf:action if="count(//relation) < instance('iterate')">
<xf:send submission="submitEntity"/>
</xf:action>
</xf:action>
</xf:action>
</xf:trigger>
然后我们提交了“新实体”。这里没什么特别的,提交完成后,我们relation/@ref
根据服务器的响应,设置上一次提交对应的值,然后在instance('iterate')
for循环中加“+1”。
<xf:submission ref="instance('newEntity')" id="submitNewEntity" resource="/test/form/put" method="put" replace="none">
<xf:action ev:event="xforms-submit-done">
<xf:message level="modal">
OK
Status : <xf:output value="event('response-status-code')"/>;
URI : <xf:output value="event('resource-uri')"/>;
Headers : <xf:output value="event('response-headers')"/>;
Reason : <xf:output value="event('response-reason-phrase')"/>;
Body : <xf:output value="event('response-body')"/>.
</xf:message>
<xf:setvalue value="event('response-body')//*:id" ref="instance('entity')//relation[position() = instance('iterate')]/@ref"/>
<xf:setvalue ref="instance('iterate')" value="instance('iterate') + 1"/>
<xf:setvalue ref="instance('newEntity')/name" value="instance('entity')/relations/relation[position() = instance('iterate')]"/>
</xf:action>
<xf:action ev:event="xforms-submit-error">
<xf:message level="modal">
Error : <xf:output value="event('error-type')"/>;
Status : <xf:output value="event('response-status-code')"/>;
URI : <xf:output value="event('resource-uri')"/>;
Headers : <xf:output value="event('response-headers')"/>;
Reason : <xf:output value="event('response-reason-phrase')"/>
Body : <xf:output value="event('response-body')"/>.
</xf:message>
</xf:action>
</xf:submission>
最后,当所有关系都已保存后,我们将提交主表单
<xf:submission ref="instance('entity')" id="submitEntity" resource="/test/form/put" method="put" replace="none">
<xf:action ev:event="xforms-submit-done">
<xf:message level="modal">
OK !
Status : <xf:output value="event('response-status-code')"/>;
URI : <xf:output value="event('resource-uri')"/>;
Headers : <xf:output value="event('response-headers')"/>;
Reason : <xf:output value="event('response-reason-phrase')"/>;
Body : <xf:output value="event('response-body')"/>.
</xf:message>
</xf:action>
<xf:action ev:event="xforms-submit-error">
<xf:message level="modal">
Error : <xf:output value="event('error-type')"/>;
Status : <xf:output value="event('response-status-code')"/>;
URI : <xf:output value="event('resource-uri')"/>;
Headers : <xf:output value="event('response-headers')"/>;
Reason : <xf:output value="event('response-reason-phrase')"/>
Body : <xf:output value="event('response-body')"/>.
</xf:message>
</xf:action>
</xf:submission>
一切都很好,除了在每次提交之前 instance('newEntity')
,我们都有一个提交错误,并显示一条错误消息:“submission-in-progress”。
事实上,在这个例子中,我不知道为什么,我们有 5 个提交而不是 3 个:
- 2 关系“Elisa Doe”(第一个失败,第二个没问题)
- 2 关系“Richard Doe”(第一个失败,第二个没问题)
- 1 代表 John Doe(“主要”形式)
我们不知道如何避免这种情况,如果有人有想法,我们正在寻求帮助?
下面是两个完整的文件。
表格 :
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
<title>Submission</title>
<xf:model>
<xf:instance id="entity">
<entity xmlns="">
<name>John Doe</name>
<age>35</age>
<address>North Cap</address>
<relations>
<relation ref="" type="sibling">Elisa Doe</relation>
<relation ref="" type="parent">Richard Doe</relation>
</relations>
</entity>
</xf:instance>
<xf:instance id="newEntity">
<entity xmlns="">
<name/>
<age/>
<address/>
<relations>
<relation ref="" type=""/>
</relations>
</entity>
</xf:instance>
<xf:instance id="iterate">
<iterate xmlns=""/>
</xf:instance>
<xf:submission ref="instance('entity')" id="submitEntity" resource="/test/form/put" method="put" replace="none">
<xf:action ev:event="xforms-submit-done">
<xf:message level="modal">
OK !
Status : <xf:output value="event('response-status-code')"/>;
URI : <xf:output value="event('resource-uri')"/>;
Headers : <xf:output value="event('response-headers')"/>;
Reason : <xf:output value="event('response-reason-phrase')"/>;
Body : <xf:output value="event('response-body')"/>.
</xf:message>
</xf:action>
<xf:action ev:event="xforms-submit-error">
<xf:message level="modal">
Error : <xf:output value="event('error-type')"/>;
Status : <xf:output value="event('response-status-code')"/>;
URI : <xf:output value="event('resource-uri')"/>;
Headers : <xf:output value="event('response-headers')"/>;
Reason : <xf:output value="event('response-reason-phrase')"/>
Body : <xf:output value="event('response-body')"/>.
</xf:message>
</xf:action>
</xf:submission>
<xf:submission ref="instance('newEntity')" id="submitNewEntity" resource="/test/form/put" method="put" replace="none">
<xf:action ev:event="xforms-submit-done">
<xf:message level="modal">
OK
Status : <xf:output value="event('response-status-code')"/>;
URI : <xf:output value="event('resource-uri')"/>;
Headers : <xf:output value="event('response-headers')"/>;
Reason : <xf:output value="event('response-reason-phrase')"/>;
Body : <xf:output value="event('response-body')"/>.
</xf:message>
<xf:setvalue value="event('response-body')//*:id" ref="instance('entity')//relation[position() = instance('iterate')]/@ref"/>
<xf:setvalue ref="instance('iterate')" value="instance('iterate') + 1"/>
</xf:action>
<xf:action ev:event="xforms-submit-error">
<xf:message level="modal">
Error : <xf:output value="event('error-type')"/>;
Status : <xf:output value="event('response-status-code')"/>;
URI : <xf:output value="event('resource-uri')"/>;
Headers : <xf:output value="event('response-headers')"/>;
Reason : <xf:output value="event('response-reason-phrase')"/>
Body : <xf:output value="event('response-body')"/>.
</xf:message>
</xf:action>
</xf:submission>
</xf:model>
</head>
<body>
<xf:input ref="name">
<xf:label>name : </xf:label>
</xf:input>
<br />
<xf:input ref="age">
<xf:label>age : </xf:label>
</xf:input>
<br />
<xf:input ref="address">
<xf:label>address : </xf:label>
</xf:input>
<br />
<xf:repeat nodeset="relations/relation" id="repeatRelation">
<xf:input ref=".">
<xf:label>Name : </xf:label>
</xf:input>
<xf:select1 ref="@type">
<xf:item>
<xf:label>parent</xf:label>
<xf:value>parent</xf:value>
</xf:item>
<xf:item>
<xf:label>sibling</xf:label>
<xf:value>sibling</xf:value>
</xf:item>
</xf:select1>
<xf:trigger>
<xf:label>X</xf:label>
<xf:action ev:event="DOMActivate">
<xf:delete ref="." at="1" if="count(//relation) > 1"/>
</xf:action>
</xf:trigger>
</xf:repeat>
<xf:trigger>
<xf:label>Add relation</xf:label>
<xf:action ev:event="DOMActivate">
<xf:insert nodeset="relations/relation" at="last()"/>
<xf:setvalue ref="relations/relation[index('repeatRelation')] | relations/relation[index('repeatRelation')]/@*"/>
</xf:action>
</xf:trigger>
<br/>
<xf:trigger>
<xf:label>submit</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('iterate')" value="1"/>
<xf:setvalue ref="instance('newEntity')/name" value="instance('entity')/relations/relation[position() = instance('iterate')]"/>
<xf:action while="count(//relation) >= instance('iterate')">
<xf:send submission="submitNewEntity"/>
<xf:action if="count(//relation) < instance('iterate')">
<xf:send submission="submitEntity"/>
</xf:action>
</xf:action>
</xf:action>
</xf:trigger>
</body>
</html>
BaseX 的 Xquery 请求
xquery version "3.0";
module namespace test = "test";
declare namespace rest = "http://exquery.org/ns/restxq";
declare namespace file = "http://expath.org/ns/file";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare namespace web = "http://basex.org/modules/web";
declare namespace update = "http://basex.org/modules/update";
declare namespace db = "http://basex.org/modules/db";
declare namespace xf = "http://www.w3.org/2002/xforms";
declare namespace ev = "http://www.w3.org/2001/xml-events";
declare default element namespace "test";
declare default function namespace "test";
declare default collation "http://basex.org/collation?lang=fr";
declare variable $test:xsltFormsPath := "/test/files/xsltforms/xsltforms.xsl";
(:~
: this function defines a static files directory for the app
:
: @param $file file or unknown path
: @return binary file
:)
declare
%rest:path('test/files/{$file=.+}')
function test:file($file as xs:string) as item()+ {
let $path := file:base-dir() || 'files/' || $file
return
(
web:response-header( map {'media-type' : web:content-type($path)}),
file:read-binary($path)
)
};
(:~
: install db
: @return create the db
:
: @todo create the prosopo db
:)
declare
%rest:path("/test/install")
%output:method("xml")
%updating
function install() {
if (db:exists("test"))
then (
update:output("db 'test' already exists !")
)
else (
update:output("db 'test' has been created"),
db:create( "test", <root/>, "test.xml")
)
};
(:~
: This function returns db "test"
:
:)
declare
%rest:path("/test")
%output:method("xml")
function opendb() {
db:open('test')
};
(:~
: This function returns the entity form
:
:)
declare
%rest:path("test/form")
%output:method("xml")
function test() {
fn:doc('files/submission.xml')
};
(:~
: This function sends entity instance to db "test"
: an @xml:id is created and sent to the form as http response
: @param $param content
:)
declare
%rest:path("test/form/put")
%output:method("xml")
%rest:header-param("Referer", "{$referer}", "none")
%rest:PUT("{$param}")
%updating
function entityPut($param, $referer) {
let $db := db:open("test")
return
let $id := 'person' || fn:format-integer(fn:count($db/*:root/*:entity) + 1, '0000')
let $param :=
copy $d := $param
modify insert node attribute xml:id {$id} into $d/*
return $d
return (
insert node $param into $db/*:root,
update:output(
(
<rest:response>
<http:response status="200" message="">
<http:header name="Content-Language" value="fr"/>
<http:header name="Content-Type" value="text/plain; charset=utf-8"/>
</http:response>
</rest:response>,
<result>
<id>{$id}</id>
</result>
)
)
)
};
非常感谢你的帮助 !!