级别: 初级 Raj Balasubramanian, 咨询 IT 架构师, IBM
2005 年 6 月 16 日 使用 Domino XML (DXL) 可以使其他应用程序能够创建、查看和更新 Lotus Notes/Domino 6.x 中的 Notes 文档。通过 LotusScript 代理,可以查看 DXL 格式的 Notes 文档,从 DXL 创建文档,还可以从 DXL 更新文档。
Domino XML (DXL) 是 Domino 设计元素的 XML 格式表示,这种 XML 使用 Notes\xmlschemas 目录中的 Domino DTD。(Lotus Notes/Domino 7 还将包括 XML 模式文档。)DXL 为将 Domino 应用程序数据暴露给其他平台提供了一种很好的方式。例如,DXL 允许以 XML 格式导出和导入 Domino 数据和设计元素。DXL 最初是在 Lotus Domino 5 中引入的,在更新的版本中,DXL 已成为 Lotus Domino 的核心的一部分。(developerWorks: Lotus 文章 "Lotus Domino 与 IBM WebSphere 集成解决方案: Domino XML" 对 DXL 作了很好的介绍)。
在本文中,我们讨论了 Lotus Domino 6.5.x 中创建的 DXL 框架的一些关键组件,这些组件用于浏览、创建和更新 Domino 数据。这个框架由一个 Domino 数据库组成,该数据库包含三个 LotusScript 代理,分别用于浏览、更新和创建 Notes 文档。本文假设您是一名有经验的应用程序开发人员,拥有使用 Lotus Domino 和 XML 的经验。
DXL 框架
我们的定制 DXL 框架简化了任何客户机对 Notes 对象的访问。有很多方法可以从不同的编程平台访问 Domino 对象。然而,面对某种给定的场景,每种访问方法都呈现着其特有的挑战。例如,常规 Java 应用程序使用的 DIIOP 访问方法不能穿越传统的防火墙,因为这些防火墙只允许 HTTP 传输。因此,不存在与应用程序无关的开箱即用的方式来创建或读取文档。这就说明了为什么 XML 是很好的选择。如果您正在构建有特殊需求(例如防火墙)的 Microsoft .Net 客户机或常规 Java 客户机,那么这里的 DXL 框架可以提供一个良好的解决方案。
例如,您可以使用 DXL 框架来构建一个应用程序,这个应用程序允许用户:
- 在 Notes 视图中查看一组 Notes 文档。
- 从该组文档中选择一个文档,并查看该 Notes 文档的细节。
- 在选定的文档上更新值。
- 创建新的 Notes 文档。
图 1 说明了组成这个 DXL 框架的关键设计元素。
图 1. DXL 框架
如图 1 所示,我们的 DXL 框架由一个 Domino 数据库(database.nsf)组成,该数据库包含三个 LotusScript 代理:
- [DXLUpdateDoc] 接受 DXL 格式的 XML,并处理来自客户机的请求,以更新具有给定 UNID 的选定文档。
- [DXLCreateDoc] 接受 DXL 格式的 XML,并处理客户机请求,以创建一个新的文档。
- [DXLViewDoc] 返回具有给定 UNID 的选定文档的 XML。
我们将在后面描述这些代理的内部工作原理。此外,您可以使用 Notes 视图的本地功能通过?ReadViewEntries URL 命令呈现 XML 数据,从选定的 Notes 视图中请求 XML 数据。
在本文中,我们主要关注 DXL 框架的服务器端组件。(要下载图 1 中所示的样本代理,请查看本文后面的下载小节)。
视图和文档的 DXL 格式
现在让我们看看如何安排视图和文档的 DXL 格式。图 2 展示了一个视图的 DXL。
图 2. 一个 Notes 视图 DXL 格式
在图 2 中:
- 蓝色的圆圈表示元素。
- 灰色的椭圆表示属性。
- 黄色的矩形表示字符数据。
- 绿色的箭头表示“含有一个……”。
- 黑色的箭头表示聚合。
如图 2 所示,viewentries 是顶层元素。它包含一个或多个 viewentry 元素,这些元素又各自包含一个或多个 entrydata 元素。每个 entrydata 元素可以包含以下几个元素中的一个:text、number、datetime 和 numberlist。
注:在这一节中,我们讨论 DXL viewentries 元素,该元素含有 DXL 格式的视图的内容。不要将它与 DXL 视图元素混淆,后者是 DXL 格式的视图的实际描述。
图中还给出了我们在 XML 处理过程中使用的关键属性。对于 viewentries 元素,我们使用 toplevelentries 来得到一个视图中所有文档的计数。从 viewentry 我们可以得到 UNID (存储起来供以后使用),从 entrydata 可以得到 columnnumber 属性,以便用于查找需要的字段值。
下面是视图 DXL 代码的一个片段:
<?xml version="1.0" encoding="UTF-8"?>
<viewentries toplevelentries="26">
<viewentry position="1" unid="F0C7DF1BE84F48B685256F0800720716" noteid="1392" siblings="26">
<entrydata columnnumber="0" name="$18">
<number>0</number></entrydata>
<entrydata columnnumber="1" name="$17">
<text>Styles, Ron</text></entrydata>
<entrydata columnnumber="2" name="$12">
<text></text></entrydata>
<entrydata columnnumber="3" name="CompanyName">
<text></text></entrydata>
<entrydata columnnumber="4" name="$16">
<text>R Styles@ABC</text></entrydata>
<entrydata columnnumber="5" name="$21">
<text>NotesMail/HQ/ABC</text></entrydata>
</viewentry>
......
</viewentries>
|
图 3 演示了 Notes 文档 DXL (在这里就是 database.nsf 中的一个 Person 文档)。
图 3. 一个 Notes 文档的 DXL 格式
在本文中,我们主要关注上面关于 DXL Notes 文档的图中所显示的元素和属性。(我们不使用 noteinfo 和 updatedby 元素,所以图 3 没有给出这两个元素)。如演示所示,document 是顶层元素,它包含一个或多个 item 元素。每个 item 元素各自又可以包含以下元素中的一个:text、number、datetime、numberlist 和 textlist。item 元素的关键属性是 name,用于查看我们感兴趣的字段值。
下面是一个例子文档的 DXL 代码的片段:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE document SYSTEM 'xmlschemas/domino_6_5_1.dtd'>
<document xmlns="http://www.lotus.com/dxl" version='6.5' maintenanceversion='1.0'
replicaid='85256F080071E637' form='Person'>
<noteinfo >......</noteinfo>
<updatedby>......</updatedby>
<item name='Title'><text/></item>
......
<item name='Owner' authors='true' names='true' protected='true'><text>
CN=Ron Styles/OU=HQ/O=ABC</text></item>
</document>
|
打开一个视图
至此我们对视图和文档的 DXL 格式已经有所理解,现在让我们看看,当一个客户机查看样本数据库的 All Documents 视图中的文档列表时在内部所发生的一系列事件:
- 用户打开常规客户机应用程序,输入用户 ID 和密码。(或者,也可以在配置文件中提供)。
- 客户机应用程序使用 ?ReadViewEntries 查询字符串,针对目标数据库视图创建到 Domino 服务器的一个 HTTP 请求。在这里,这个视图就是样本 All Documents 视图,该视图显示例子数据库中的所有文档。
- Domino 服务器验证用户,处理请求,并在 HTTP 响应中将 XML 数据返回给客户机。
- 客户机应用程序处理从服务器收到的 XML 数据,并显示 All Documents 视图中的文档列表。
图 4 演示了这个过程。
图 4. 查看文档
打开一个文档
当一个客户机打开 All Documents 视图中的一个 Notes 文档时,将进行以下步骤:
- 像上一节中描述的那样,用户打开 All Documents 视图。
- 用户选择一个要打开的文档。
- 客户机应用程序获得所选文档的 UNID,并发送一个针对 URI 为 /ViewDXLDoc?Open&unid=<doc UNID> 的目标数据库的 HTTP 请求到 Domino 服务器。
- Domino 服务器处理该请求,验证用户并处理代理请求,输出 DXL 格式的文档(文档的 UNID 是在请求中发送的)。
- 常规客户机收取 DXL 文档的 XML 数据并加以处理。
- 为用户显示所选文档的一个细节视图。
图 5 展示了这个过程。
图 5. 打开一个文档
创建一个文档
当用户创建一个新的 Notes 文档时,将进行以下步骤:
- 用户启动客户机应用程序,选择用于创建新文档的菜单选项。
- 用户在应用程序中看到一个常规的表单。用户填好该表单,并提交/保存表单。
- 应用程序提取表单数据,将其格式化为 XML(遵从 DXL 文档格式),然后调用 DXLCreateDoc 代理。这样将在 HTTP 请求中发送 DXL 内容。
- Domino 服务器验证用户,并处理代理请求。
- DXLCreateDoc 代理处理 DXL 文档中的 XML 数据,返回的消息被发送到客户机。
- 用户看到关于表单提交动作的成功/失败消息。
图 6 展示了这些步骤。
图 6. 创建一个文档
定制的 DXL 代理
在这一节中,我们研究 [DXLViewDoc]、[DXLUpdateDoc] 和 [DXLCreateDoc] 这几个 LotusScript 代理的内部工作原理。这些代理是 DXL 框架的关键组件。我们研究每个代理的代码片段,解释每个片段所做的工作。(要下载这些代理的完整代码,请查看下载小节)。
[DXLViewDoc]
[DXLViewDoc] 代理返回选定文档的 XML。该代理首先设置一些标准变量。我们使用会话文档上下文方法获得文档对象。对 HTTP 请求的响应是通过标准打印语句来处理的。首先将响应内容类型初始化为 text/xml。还要捕捉错误。
Sub Initialize
Dim s As New notessession
Dim db As notesdatabase
Dim doc As notesdocument
Dim doc1 As notesdocument
Set doc1 = s.DocumentContext
Print "Content-type: text/xml"
On Error Goto err1
Set db = s.currentdatabase
Dim stg As String
|
然后通过请求 URL 的查询字符串查找传入的 UNID,并进行最小错误检查。
stg = doc1.Query_String(0)
If Len(stg) < 5 Then
Goto err1
End If
If Instr(stg,"unid=") < 1 Then
Goto err1
Else
stg = Right(stg,Len(stg)-Instr(stg,"="))
End If
|
得到一个有效的 UNID 后,首先获取 Notes 文档的一个句柄,接着使用 NotesDXLExporter 将内容导出到 XML,并确保 XML 中不需要提供 DTD。
Set doc = db.GetDocumentByUnID(stg)
Dim exporter As NotesDXLExporter
Dim stream As notesstream
Set exporter = s.CreateDXLExporter
exporter.OutputDOCTYPE=False
Set stream = s.CreateStream
Call exporter.SetInput(doc)
Call exporter.SetOutput(stream)
Call exporter.Process
|
然后从 stream 对象获得文本,并将文本输出到客户机。
Print stream.ReadText()
End
err1:
Print "You reached in error"
Resume
End Sub
|
[DXLUpdateDoc]
[DXLUpdateDoc] 代理处理客户机请求,以更新所选定的文档。我们使用请求的 Request_Content 属性来获得由客户机发送的实际 XML 的句柄,并将其输送到 stream 对象。
Dim x As NotesItem
Dim stream As NotesStream
Set x =doc.GetFirstItem("Request_Content")
...........
.....
Call stream.WriteText(x.Text)
|
然后实例化 NotesDXLImporter,以便在数据库上下文中使用 stream,并规定这次的导入是更新而不是创建。
Dim imp As NotesDXLImporter
Set imp = session.CreateDXLImporter(stream, db)
imp.DocumentImportOption=DXLIMPORTOPTION_UPDATE_ELSE_IGNORE
imp.ReplicaRequiredForReplaceOrUpdate = False
Call imp.Process
|
[DXLCreateDoc]
[DXLCreateDoc] 代理处理客户机请求,以创建一个新的文档。该代理与 DXLUpdateDoc 代理很相似。它们之间的主要区别是,在使用 stream (在数据库上下文中)的过程中,我们规定了这次的导入类型是创建,从而可以创建一个新的文档。
imp.DocumentImportOption=DXLIMPORTOPTION_CREATE
....
结束语
在本文中,我们描述了如何利用 Lotus Notes/Domino 6 中提供的 DXL 特性,然后描述了如何用定制的 LotusScript 代理创建一个框架,用于查看和更新已有的 Notes 文档。这个框架被设计用来简化对 Notes 对象的访问。它使用 XML 而不是 HTML,因此,对于任何知道如何处理 XML 的应用程序来说,它处理起来比较简单。由于它是通过 HTTP 协议传输的,因此可以通过防火墙。
本文的目的是为您提供必要的预备知识,以便能够使用我们描述的 DXL 框架来设计用来访问和处理 Domino 数据的应用程序。在设计用于 Web(JSR168 portlets)和丰富客户机(Eclipse RCP)的应用程序时,也可以使用这个框架。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| Sample agents code | agents.ZIP | 1.52KB | HTTP |
|---|
参考资料
关于作者  | |  | Raj Balasubramanian 是 IBM Software Services for Lotus (ISSL)部门的咨询 IT 架构师。他现在致力于客户履约交付应用程序及与基础设施相关的项目。他兴趣广泛,从技术到历史以至物理学的各个范畴都有所涉猎。除了浏览客户站点和阅读数学书籍,他还乐于跟儿子们谈论机器人和相关的新技术。 |
对本文的评价
|