Domino XML Language(DXL)簡介

genusBIT發表於2009-03-30
為了根據使用者的需求實現資料庫或模板定製,常常需要動態地在現有資料庫中自動新增設計元素,比如代理、檢視或資料夾,或者修改資料庫中現有的設計元素。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 元素
acl aclentry action actionbar actionbarstyle actionhotspot addedtofile agent
anchor area background block border break button caption
code column control created database datetime doclink document
endate endtime entrydata field fieldchoice file filedata folder
font form formula frame gif globals imageref imageresource
item itemdata java javaapplet javaarchive javaproject javaresource javascript
jpeg keyword lastaccessed layout logentry lotusscript modified name
note noteinfo notesbitmap noteslaunch number object objectref page
par pardef parstyle picture point popup popuptext region
revised richtext richtextdata role run rundata schedule scriptlibrary
search section sendbcc sendcc sendsubject sendto servlet sharedfield
span startdate startime subform table tablecell text textlist
textproperties title trigger urllink view viewlink weblaunch word

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 檔案




  
  
    
      
        20080402T061930,91-07
      
      
        20080901T151520,50-07
      
      
        20080901T151520,49-07
      
      
        20080901T151520,49-07
      
      
        20080402T061930,91-07
      
    
    
      CN=Administrator/O=ibm
    
    
      20080901T151520,48-07
    
    
    
    
      
      
    
    
      

    
    
      
        20080901T151520,48-07
      
    
    
      20080328T172442,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 user Restorelastview 不可應用
Open About database document Openaboutdocument 不可應用
Open designated frameset Openframeset MailFS、BorderFrame、ToDoFS 等
Open designated navigator Opennavigator Folders、Page 等
Open designated navigator in its own windows Opennavigatorwindow Standard Navigator、Page 等
Launch first attachment in About database Openfirstaboutattachment 不可應用
Launch first doclink in About database Openfirstdoclink 不可應用

清單 3. Modifydatabaseproperty DXL 檔案



  

用例 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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章