Domino XML Language(DXL)简介

为了根据用户的需求实现数据库或模板定制,常常需要动态地在现有数据库中自动添加设计元素,比如代理、视图或文件夹,或者修改数据库中现有的设计元素。Domino XML Language (DXL) 是一种用于表示 IBM® Lotus® Domino® 数据和设计元素的 XML 格式,可以方便地捕捉设计元素和在数据库中导入或导出设计元素。在本文中,我们介绍 DXL 的概念,并通过用例和详细的实现讲解如何应用 DXL 来动态地添加或修改设计元素,从而完成用户的数据库或模板定制。

Lotus Domino 数据的 XML 表示格式称为 DXL。DXL 描述 Lotus Domino 特有的数据和设计元素,比如视图、表单和文档。XML 已经成为信息交换的标准格式,DXL 为在 Lotus Domino 应用程序中导入和导出数据的 XML 形式提供了基础。DXL 用来详细描述 Lotus Domino 数据库中包含的结构和数据。

DXL 的结构由 Lotus Domino 文档类型定义 (DTD) 文件描述,在默认情况下可以在 Lotus Notes 安装路径(比如 IBM/lotus/notes/xmlschemas)中找到这个文件。这个 DTD 包含 XML 标记的定义,在把外部 XML 数据转换到 Lotus Domino 数据库中时可以用它检验 XML 文档,在把内部 Lotus Domino 数据库导出为 XML 时可以用它理解产生的 XML 文档。

组成 Domino DTD 的实体和元素如下:

  • 核心实体。作为数据类型类别的实体,比如 binary、Boolean、float、hex、integer、notesid 和 unid。
  • 通用实体。在其他实体或多个元素中引用的实体,比如 acl.levels、color、image.formats、length 和 pixel。
  • Lotus Domino 元素。Lotus Domino DTD 中的所有元素。它们表示 Lotus Domino NSF 数据库或 NTF 模板中存储的数据的类型。表 1 列出主要的 Lotus Domino 元素。

表 1. 主要的 Lotus Domino 元素
aclaclentryactionactionbaractionbarstyleactionhotspotaddedtofileagent
anchorareabackgroundblockborderbreakbuttoncaption
codecolumncontrolcreateddatabasedatetimedoclinkdocument
endateendtimeentrydatafieldfieldchoice filefiledata folder
fontformformulaframegifglobalsimagerefimageresource
itemitemdatajavajavaappletjavaarchivejavaprojectjavaresourcejavascript
jpeg keywordlastaccessedlayoutlogentrylotusscriptmodifiedname
notenoteinfonotesbitmapnoteslaunchnumberobjectobjectrefpage
parpardefparstylepicturepoint popuppopuptextregion
revisedrichtextrichtextdatarolerunrundataschedulescriptlibrary
searchsectionsendbccsendccsendsubjectsendtoservletsharedfield
spanstartdatestartimesubformtabletablecelltexttextlist
textpropertiestitletriggerurllinkviewviewlinkweblaunchword

database 元素

database 元素是 DXL 文件中的重要元素。图 1 显示 XML 模式中的 database 元素。它包含一些属性和子元素。属性描述数据库本身,比如 title、version、path 和 replicaid。子元素包括两种类型:

  • 与数据库本身相关的子元素,比如 databaseinfo、acl、fulltextsetting 和 launchsetting。
  • database 元素中包含的子元素,比如 note、document、form、subform、page、view、folder 和 agent。

图 1. database 元素及其子元素和属性
database 元素及其子元素属性 

使用 DXL

在开发应用程序期间,可以使用 Java™ 或 LotusScript® 操作 DXL。它们提供以下功能:

  • 把 DXL 导入数据库或模板,以及从数据库或模板导出 DXL
  • 处理 DXL 流或文件

通过 Java 使用 DXL

DxlExporter 类把 Lotus Domino 数据转换为 DXL。在会话中使用 createDxlExporter 方法创建一个 DxlExporter 对象。使用 exportDxl 方法执行导出操作。exportDxl 的输入可以是 Database、Document、DocumentCollection 或 NoteCollection 对象。输出是一个 String 对象。

DXLImporter 类把 DXL 转换为 Lotus Domino 数据。在会话中使用 createDXLImporter 方法创建一个 DxlImporter 对象。DxlImporter 的输入可以是 String、Stream 或 NotesRichTextItem 对象。输出是一个 Database 对象。

Lotus Domino Designer 还包含 XML4J 解析器和 LotusXSL 处理器,可以使用它们访问对象的 XML 表示、解析和转换 XML 数据以及通过 Java 后端类中的属性和方法生成文档的 XML 表示。

通过 LotusScript. 使用 DXL

NotesDXLExporter 类把 Lotus Domino 数据转换为 DXL。在 NotesSession 中使用 CreateDXLExporter 方法创建一个 NotesDXLExporter 对象。导出过程的输入可以是 NotesDatabase、NotesDocument、NotesDocumentCollection 或 NotesNoteCollection 对象。输出是 NotesStream 或 NotesRichTextItem 对象或任何其他 XML 处理器。

NotesDXLImporter 类把 DXL 转换为 Lotus Domino 数据。在 NotesSession 中使用 CreateDXLImporter 方法创建一个 NotesDXLImporter 对象。导入过程的输入可以是 string、NotesStream 或 NotesRichTextItem 对象或任何其他 XML 处理器。输出是一个 NotesDatabase 对象。

可以使用 NotesDOMParser 和 NotesSAXParser 解析 DXL。NotesDOMParser 把 DXL 解析为标准的 Document Object Model (DOM) 树。可以使用其他 NotesDOM 类操作 DOM 树。NotesSAXParser 使用一个 Simple API for XML (SAX) 解析器以事件的形式处理 DXL。

用例和解决方案

在工作流系统中,常常需要定制用户的数据库或模板。有时候,无法在 Notes Java API 或 LotusScript. 中找到适当的接口,从而直接添加或修改数据库或模板。DXL 有助于解决这种难题;它可以添加设计元素或修改任何现有的设计元素和属性。下面讨论几个用例和与 DXL 相关的解决方案,您可以在实际开发中应用这些解决方案

用例 1:在现有数据库中添加代理

用户的数据库是从组织中的共享模板派生的。通过在 Lotus Domino Designer 中修改共享模板和添加代理,就可以添加与代理相关的函数。但是,这种方法有一些限制:

  • 代理的添加是静态的,不能通过用户的首选项控制。
  • 代理添加到所有用户的数据库中,所有用户都可以看到添加的函数。

为了解决这个问题,只让特定的用户能够使用函数,可以使用 DXL 技术在特定用户的现有数据库中动态地添加代理。对于这个场景,管理员可以编写一个电子邮件,其中包含一个热点和一个 DXL 文件,然后把电子邮件发送给特定的用户。这些用户接收电子邮件之后,他们可以单击热点并添加代理。

首先,我们来看看热点和 DXL 文件的内容,见清单 1 和清单 2。


清单 1. 热点中的 “AddMyAgent” LotusScript

1 Sub Click(Source As Button)
 2  Dim session As New NotesSession    
 3  Dim stream As NotesStream
 4  Dim importer As NotesDXLImporter
 5  Dim curdirname As String  
 6  
 7  REM Set current database  
 8  Set db = session.CurrentDatabase  
 9  curdirname = Curdir()  
10  
11  Dim workspace As New NotesUIWorkspace
12  Dim uidoc As NotesUIDocument
13  Dim doc As NotesDocument
14  Dim db As NotesDatabase
15  
16  REM Get the DXL file from current document
17  Set uidoc = workspace.CurrentDocument
18  Set doc= uidoc.Document
19  Set rtitem = doc.GetFirstItem("Body")   
20  
21  Forall eo In rtitem.EmbeddedObjects         
22    Call eo.ExtractFile( curdirname + eo.source )          
23  End Forall        
24  
25  REM Open DXL file
26  Set stream = session.CreateStream
27  If Not stream.Open(curdirname + "AddMyAgent.dxl") Then
28    Msgbox "Cannot open AddMyAgent.dxl", , "Error"
29    Exit Sub
30  End If
31  If stream.Bytes = 0 Then
32    Msgbox "File did not exist or was empty", , "Error"
33    Exit Sub
34  End If  
35  
36  REM Import DXL into new database
37  Set importer = session.CreateDXLImporter
38  importer.ReplaceDBProperties = True
39  importer.ReplicaRequiredForReplaceOrUpdate = False
40  importer.ACLImportOption = DXLIMPORTOPTION_REPLACE_ELSE_IGNORE
41  importer.DesignImportOption = DXLIMPORTOPTION_CREATE
42  Call importer.Import(stream, db)
43  
44  REM Sign agents with current user
45  Call db.sign(DBSIGN_DOC_AGENT)
46  Call stream.Close
47 End Sub

这个过程是用 LotusScript. 编写的。也可以使用 Java 编写它。从第 16 行到第 23 行,它把 DXL 文件从电子邮件中分离出来并保存到磁盘上。从第 25 行到第 42 行,把 DXL 文件读入流中并导入数据库。在第 42 行之后,把名为 MyAgent 的新代理添加到用户的数据库中。在第 45 行,用当前用户签名代理,让代理可以正确地运行。


清单 2. AddMyAgent DXL 文件

<?xml version="1.0"?>
20080402T061930,91-0720080901T151520,50-0720080901T151520,49-0720080901T151520,49-0720080402T061930,91-07CN=Administrator/O=ibm20080901T151520,48-07
      
    
      
    20080901T151520,48-0720080328T172442,06+08


图 2. 特定用户的用户界面
特定用户的用户界面

在重新打开数据库之后,用户可以在操作菜单中看到名为 MyAgent 的新代理,见图 2。在窗口的右下部是管理员发来的电子邮件的预览,其中包含热点和 DXL 文件。除了 agent 设计元素之外,还可以把任何其他设计元素导入数据库或模板,见图 3。在这个 DXL 文件中包含 agent、view 和 imageresource 设计元素。把这个文件导入数据库之后,可以在数据库中添加两个代理、两个视图和四个 GIF 资源文件。


图 3. 包含 agent、view 和 imageresource 的 DXL 文件
包含 agent、view 和 imageresource 的 DXL 文件 

用例 2:修改数据库中的属性

注意,Java API 和 LotusScript. 提供了许多访问数据库属性及其子集的方法,但是这些方法并不能修改所有属性。可以使用 DXL 技术解决这个问题。可以在 DXL 文件中表示所有数据和设计元素。可以在 DXL 文件中修改属性值,然后把修改后的 DXL 文件导入数据库。这样就可以修改数据库中的属性。

我们来看一个简单的示例。如果希望修改数据库的 launch 属性,可以通过 DXL 技术来实现。

表 2 列出在 Lotus Notes 客户机中打开数据库时可用的选项。如果希望在打开 Lotus Notes 数据库时自动地显示一个框架集(比如 MailFS),那么可以导入清单 3 所示的 Modifydatabaseproperty DXL 文件。


表 2. noteslaunch 元素设置

在 Notes 客户机中打开时common.whenopened 或 notes.whenopened 框架集或导航器名
Restore as lastviewed by userRestorelastview 不可应用
Open About database documentOpenaboutdocument不可应用
Open designated framesetOpenframesetMailFS、BorderFrame、ToDoFS 等
Open designated navigatorOpennavigatorFolders、Page 等
Open designated navigator in its own windows OpennavigatorwindowStandard Navigator、Page 等
Launch first attachment in About database Openfirstaboutattachment不可应用
Launch first doclink in About databaseOpenfirstdoclink不可应用

清单 3. Modifydatabaseproperty DXL 文件
<?xml version="1.0"?>

用例 3:修改数据库的默认事件处理函数

在使用 Lotus Notes 设计元素时,Lotus Notes 以事件的形式跟踪它们的操作(例如,打开数据库、打开视图或打开文档)。数据库的事件处理函数保存在 databasescript. 元素的 code 元素下面,databasescript. 元素是 database 元素的子元素,见图 4。


图 4. databasescript. 元素及其子元素和属性
database.. 元素及其子元素和属性

数据库事件表示数据库范围内的活动,比如打开和关闭数据库或删除和恢复文档。下面是一些示例:

  • PostOpen。打开特定的视图,将用户指引到操作项。
  • QueryDocumentDelete。当操作项上的状态字段值是 open 时,禁止用户删除特定的文档。
  • PostDocumentDelete。对删除的文档进行存档。
  • QueryClose。当分配给数据库的操作项视图中仍然有操作项时,禁止用户关闭数据库。

通过修改 PostOpen 过程,可以改变数据库打开事件的默认处理行为。例如,通过使用 DXL 技术而不是 Lotus Domino Designer,可以添加一个欢迎窗口,让这个欢迎窗口在用户打开数据库时显示出来。使用 DXL 技术的优点是,可以把用于修改 PostOpen 过程的逻辑封装在热点或按钮中。用户可以通过单击按钮应用修改,不需要手工打开 Lotus Domino Designer 进行修改。

为了修改 PostOpen 过程,需要先导出现有的 PostOpen。可以使用 DXL 导出器和 SAX 解析器完成这一步。使用 DXL 导出器把 databasescript. 元素导出到 DXL 流中;见清单 4 中的第 19 行到第 54 行。然后,使用 SAX 解析器解析 DXL 流并找到 databasescript. 元素的 code 元素,见第 77 行到第 164 行。如果找到了处理 PostOpen 的代码,就把显示欢迎窗口的代码插入现有的 PostOpen 过程,见第 124 行到第 141 行。最后,可以使用 DXL 导入器把修改后的 DXL 文件导入数据库,见第 57 行到第 73 行。


清单 4. ModifyDatabaseScript. LotusScript. 文件
  1 (Declarations)
  2 Dim isPostOpenEvent As Boolean
  3 Dim isPostOpenCode As Boolean
  4 Dim isCode As Boolean
  5
  6 Sub Initialize
  7  
  8  Dim session As New NotesSession
  9  Dim db As NotesDatabase
 10  Dim streamIn As NotesStream 
 11  Dim streamOut As NotesStream
 12  Dim dxlExporter As NotesDXLExporter 
 13  Dim dxlImporter As NotesDXLImporter
 14  Dim saxParser As NotesSAXParser 
 15  
 16  REM get current database
 17  Set db = session.CurrentDatabase
 18  
 19  REM Create DXL exporter
 20  Set dxlExporter = session.CreateDXLExporter
 21  
 22  REM Create the stream that will store the DXL
 23  Set streamIn = session.CreateStream 
 24  Call streamIn.Truncate
 25  Set streamOut = session.CreateStream
 26  Call streamOut.Truncate
 27  
 28  REM Create note collection
 29  Dim nc As NotesNoteCollection
 30  Set nc = db.CreateNoteCollection(False)
 31  nc.SelectDatabaseScript. = True  
 32  Call nc.BuildCollection
 33  
 34  REM Export note collection as DXL  
 35  Set dxlExporter = session.CreateDXLExporter(nc)
 36  dxlExporter.OutputDOCTYPE = True
 37  
 38  filename$ = "c:\" & Left(db.FileName, Len(db.FileName) - 3) & "xml"
 39  If Not streamIn.Open(filename$) Then
 40    Messagebox "Cannot open " & filename$,, "Error"
 41    Exit Sub
 42  End If
 43  streamIn.Truncate
 44  
 45  REM Create the SAX Parser, the results of the parse will be 
       pushed into stream (streamIn)
 46  Set saxParser = session.CreateSAXParser(dxlExporter, streamIn)
 47  On Event SAX_Characters From saxParser Call SAXCharacters
 48  On Event SAX_EndElement From saxParser Call SAXEndElement
 49  On Event SAX_StartDocument From saxParser Call SAXStartDocument
 50  On Event SAX_StartElement From saxParser Call SAXStartElement
 51  
 52  REM Initiate parsing, by doing this the SAX events are called
 53  REM It is in there that the DXL is rewritten and the 
       PostOpen() method was modified.
 54  Call dxlExporter.Process()  
 55  streamIn.Close  
 56  
 57  REM Open xml file named after current database 
 58  If Not streamOut.Open(filename$) Then
 59    Messagebox "Cannot open " & filename$,, "Error"
 60    Exit Sub
 61  End If
 62  If streamOut.Bytes = 0 Then
 63    Messagebox "File did not exist or was empty",, filename$
 64    Exit Sub
 65  End If
 66  
 67  REM Import DXL into new database
 68  Dim importer As NotesDXLImporter
 69  
 70  Set importer = session.CreateDXLImporter(streamOut, db)
 71  importer.ReplaceDBProperties = ture 
 72  importer.DesignImportOption =DXLIMPORTOPTION_REPLACE_ELSE_CREATE 
 73  Call importer.Process
 74  
 75 End Sub
 76
 77 Sub SAXStartDocument (Source As Notessaxparser)
 78  REM Write DXL header
 79  Source.Output("<?xml version='1.0'?>" & Chr(10))  
 80 End Sub
 81
 82 Sub SAXStartElement (Source As NotesSAXParser,_
 83 Byval strElementName As String, Attributes As NotesSaxAttributeList)  
 84  
 85  Dim i As Integer  
 86  REM Open Element
 87  Source.Output("<" & strElementName) 
 88  If Attributes.Length > 0 Then
 89    For i = 1 To Attributes.Length
 90      REM Get the name and value of the attribute
 91      strAttrName = Attributes.GetName(i)
 92      strAttrValue = Attributes.GetValue(i)     
 93      REM Check whether current element is code
 94      If strElementName = "code" Then
 95        bCode = True
 96        If  strAttrName = "event" Then          
 97          If strAttrValue = "postopen" Then
 98            REM found postopen event
 99            bPostOpenEvent = True           
100          End If
101        End If                  
102      End If                
103               REM Write the attribute
104      Source.Output(| | & strAttrName & |="| & strAttrValue & |"|) 
105    Next        
106  End If
107  
108  If strElementName = "lotusscript"  And bPostOpenEvent  Then
109    REM found postopen code
110    bPostOpenCode = True
111  End If
112  
113     REM Close the element tag here
114  Source.Output(">")  
115 End Sub
116
117 Sub SAXCharacters (Source As Notessaxparser, Byval Characters As String, _
118 Count As Long)
119  
120  If  isCode Then
121    Source.Output("<![CDATA[")    
122  End If  
123  
124  If (isPostOpenCode)  Then
125    REM insert code into this place
126    Dim header As String
127    Dim pos As Integer
128    Dim newchar As String
129    
130    header = "Notesuidatabase"
131    pos = Instr(Characters,header)
132    
133    If (pos = 1) Then
134      REM at the begining 
135    Else    
136      REM found the patten, and insert the code
137      newchar = Left(Characters, pos+16)        
138      newchar = newchar + Chr(13) + "Msgbox" + Chr(34) + "Welcome"+ Chr(34) + Chr(13)
139      newchar = newchar + Mid(Characters, pos+ 17)      
140    End If    
141    Source.Output(newchar)
142  Else 
143    Source.Output(Characters) 
144  End If
145  
146  If  bCode Then
147    Source.Output("]]>")    
148 End If
149  
150 End Sub
151
152 Sub SAXEndElement (Source As NotesSAXParser, Byval ElementName As String)
153  
154  REM Terminate the element
155  Source.Output("</" & ElementName & ">" & Chr(10))
156  
157  If ElementName = "lotusscript"  And isPostOpenEvent  Then
158    isPostOpenCode = False
159    isPostOpenEvent = False
160  Elseif elementName = "code" Then
161    isCode = False
162  End If
163  
164 End Sub					

这样就改变了数据库打开事件的处理行为,打开数据库时将会显示一个欢迎窗口。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14751907/viewspace-580655/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14751907/viewspace-580655/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值