XQuery/使用触发器分配标识符
外观
< XQuery
您希望自动地为所有新传入的文档或 XML 节点分配唯一的标识符:无论它们是由您编写的控制器创建的,还是由 REST 调用中的 HTTP PUT 操作产生的,还是由 webdav COPY 操作产生的,还是从 java 管理 RPC 客户端上传的。
我们将创建一个触发器,它将在所有文档存储操作上触发。触发器将修改要存储在数据库中的文档。我们的标识符将从 util:uuid() 函数的输出中获取。一个简单的赋值将尽职尽责。不需要特殊的权限,例如增量计数器。
此示例假设您要使用标识符标记的文档位于 /db/my-collection 下。eXist 触发器在 /db/system/config 区域中的配置文件中声明,上面路径添加到它。包含相关行的文件将如下所示
/db/system/config/db/my-collection/collection.xconf
<collection xmlns="http://exist-db.org/collection-config/1.0">
<triggers>
<trigger event="store" class="org.exist.collections.triggers.XQueryTrigger">
<parameter name="url" value="xmldb:exist://127.0.0.1/db/triggers/assign-id.xq"/>
</trigger>
</triggers>
</collection>
现在,每次对该集合发生存储或更新事件时,XQuery 脚本 /db/triggers/assign-id.xq 都会运行。
注意!由于当前(<=1.5dev)设计的限制,您不能将多个 xquery 脚本附加到同一个触发器事件。对于一个事件,最后声明的触发器将被使用。
该脚本将 uuid 作为属性添加到传入文档的 根 元素,覆盖任何已存在的 uuid 属性。
注意:这些示例不能可靠地工作:一旦您的 xquery 在它运行的线程中导致异常,那么它就会无限期地挂起,例如,如果您在它工作的路径下存储二进制资源。然后,对已处理资源的进一步操作将不会触发脚本,直到整个数据库重新启动。
xquery version "1.0";
(:
An XQueryTrigger that
adds a uuid to all documents
when they are stored in the database.
:)
declare namespace util="http://exist-db.org/xquery/util";
declare variable $local:triggerEvent external;
declare variable $local:eventType external;
declare variable $local:collectionName external;
declare variable $local:documentName external;
declare variable $local:document external;
declare variable $local:coll := "/db/my-collection";
declare variable $local:uuid := string($local:document/@uuid);
declare variable $local:match := collection($local:coll)/*[@uuid = $local:uuid];
(:
This is still the xquery prolog:
from my experiments, an xquery trigger MUST NOT hava an xquery body.
A severe limit: no conditionals allowed, just straight procedural action.
:)
util:log('debug', '### assign-id.xq trigger fired ###'),
update insert attribute {'uuid'} {util:uuid()} into doc($local:documentName)/*,
util:log('debug', '### assign-id.xq trigger done ###')