跳转到内容

XQuery/同步远程集合

来自维基教科书,开放世界中的开放书籍

您想要更新在集合中比另一个集合更新或新的项目。

许多数据库将创建日期和上次修改日期与资源一起存储。这些日期可以用来查看本地集合是否与远程集合不同步。可以编写一个 XQuery 脚本,它将只列出比本地集合上的创建日期更新或新的文件。

对于 eXist 数据库,以下是用来访问时间戳的两个函数。

  xmldb:last-modified($collection, $resource)
  xmldb:created($collection, $resource)
  

其中

  $collection is the path to the collection (xs:string)
  $resource is the name of the resource (xs:string)

例如

   let $my-file-last-modified := xmldb:last-modified('/db/test', 'myfile.xml')

将返回集合 /db/text 中文件 myfile.xml 的上次修改日期和时间。时间戳的格式为 XML Schema dateTime 格式

  "2009-06-04T07:50:04.828-05:00"

例如,这表示时间为 2009 年 6 月 4 日上午 7:50,对于比协调世界时 (UTC) 落后 5 小时的中央标准时间。

递归集合最后修改日期示例函数

[编辑 | 编辑源代码]

您可以将 xmldb:last-modified() 函数与另一个函数 xmldb:get-child-collections($collection) 相结合,该函数返回当前集合的所有子集合。通过使用尾递归调用自身,您可以找到集合及其所有子集合中所有最后修改的日期和时间。

这是一个示例 XQuery 函数,它返回集合及其所有子集合中所有资源的最后修改日期和时间列表。

declare function local:collection-last-modified($collection as xs:string) as node()* {
<collection>
   {attribute {'cid'} {$collection} }
   {for $resource in xmldb:get-child-resources($collection)
      return
      <resource>
        {attribute {'id'} {$resource}}
        {attribute {'last-modified'} {xmldb:last-modified($collection, $resource)}}
      </resource>,
      if (exists(xmldb:get-child-collections($collection)))
        then (
           for $child in xmldb:get-child-collections($collection)
           order by $child
           return
              (: note the recursion here :)
              local:collection-last-modified(concat($collection, '/', $child))
           )
         else ()
  }
</collection>
};

请注意,向每个资源添加了两个属性。一个是资源 ID,它在每个集合中必须是唯一的,另一个是资源上次修改的日期。

示例驱动程序

[编辑 | 编辑源代码]

您可以通过简单地传递要开始的集合根来调用此函数。

xquery version "1.0";
let $collection := '/db/test'

return
<last-modified-report>
  {local:collection-last-modified($collection)}
</last-modified-report>

这将返回以下文件

<last-modified-report>
   <collection cid="/db/test">
      <resource id="get-remote-collection.xq" last-modified="2009-04-29T08:16:06.104-05:00"/>
      <collection cid="/db/test/views">
         <resource id="get-site-mod-dates.xq" last-modified="2009-04-30T09:01:58.599-05:00"/>
         <resource id="site-last-modified.xq" last-modified="2009-04-30T09:07:10.016-05:00"/>
      </collection>
   </collection>
</last-modified-report>

使用 Apache Ant 驱动同步

[编辑 | 编辑源代码]

您现在可以使用这些转换来创建批处理文件,这些文件将只传输已更改或新的文件。

许多数据库提供 Apache Ant 任务,这些任务具有提取和存储操作的功能。

这是一个示例 Apache Ant 目标,它在本地文件上执行提取操作,并将结果存储在远程文件上。

<target name="push-bananas">
      <xdb:extract 
         xmlns:xdb="http://exist-db.org/ant" 
         uri="xmldb:exist://${local-host}/exist/xmlrpc/db/test/sync" 
         resource="bananas.xml" 
         destfile="C:/backup/db/test/sync/bananas.xml"
         user="${local-user}"
         password="${local-pass}"
      />
      <xdb:store 
         xmlns:xdb="http://exist-db.org/ant" 
         uri="xmldb:exist://${remote-host}/exist/xmlrpc/db/test/sync" 
         srcfile="/backup/db/test/sync/bananas.xml" createcollection="true"
         user="${remote-user}"
         password="${remote-pass}"
        />
     </target>

请注意,此 Ant 文件中必须设置以下属性。

   <property name="local-host" value="localhost"/>
   <property name="local-user" value="admin"/>
   <property name="local-pass" value="put-local-pw-here"/>
   
   <property name="remote-host" value="example.com"/>
   <property name="remote-user" value="admin"/>
   <property name="remote-pass" value="put-remote-pw-here"/>
华夏公益教科书