Notes rich text manipulation using DXL

The NotesDXLExporter and NotesDXLImport Lotus script classes are very powerful when dealing with Lotus Notes rich text content that requires some tampering here and then.

DXL Source Document

What is happening? The example above is showing a template that can be used to create individualised email messages for each recipient.
There are a number of placeholders starting with ## and an upper case description that are later replaced with meaningful content similar to mail merge. So far there is nothing new. Everything could also be achieved utilising the various text manipulation methods of the NotesRichTextItem class. However, this piece of code goes a step further end even allows the manipulation of the three action hotpots at the bottom of the message at runtime.

DXL Lotusscript Source

The resulting message contains the first name, a document link, the manipulated action hot spots and a customised signature. Selecting the first action hotspot opens a dialogue displaying a message and the title of the database. Also shown below is the resulting script code of the first action hotspot.

DXL Output Document

DXL Lotusscript Output

There are a number of subsequent actions that have to be performed to achieve above result:

  1. The rich text item containing the template information is first separated into a temporary document. This keeps the resulting DXL (Domino XML) code tiny and clean end ensures that there are no other interfering items from the source document.
  2. The bare temp document, which only exists is in memory is subsequently exported using the NotesDXLExporter class. The result is stored in a string variable containing the DXL data.
  3. Now a simple search/replace is used to find the ## placeholders and to convert them to the expected output. In order to insert a document link at the ##DOCLINK position an additional XML node element is inserted.
  4. The manipulated DXL source solely contains the description of a notes document holding our manipulated rich text content. It is now imported back into a notes document. The import method of the NotesDXLImporter requires a destination database to be specified. As in step 1 the imported document is only temporary but also requires to be removed after the process. The cache.ndk, existing on each client appears to be a really good candidate to store these document temporary.
  5. Once the manipulated rich text item is imported back it can be appended to the document that is sent out to the recipient.
  6. The final step is the removal of the temporary document previously stored in the cache.ndk. With -Default- set to manager in the ACL there is no need to worry about deletion rights. Although careful consideration should be taken in cases where the temporary stored rich text content is of confidential nature.

Only very few Lotus script code is required to implement the steps described above. Please note that, for the clarity of the example, no special error handling code is displayed and the source document is defined via the document unique ID.

Sub SendManipulatedRichText
' The document unique id of the document containing the source rtitem
Const SOURCEDOC="9056AF7C51E7A4E7CC2574AC001B5D6A"

‘ Declarations
Dim session As New NotesSession
Dim db As NotesDatabase
Dim dbTemp As NotesDatabase
Dim docSource As NotesDocument
Dim docTemp As NotesDocument
Dim newDoc As NotesDocument
Dim importer As NotesDXLImporter
Dim exporter As NotesDXLExporter
Dim rtitem As NotesRichTextItem
Dim rtitemTemp As NotesRichTextItem
Dim sOutput As String
Dim sActionCode1 As String

‘ Get hold of the source rich text item in the current database
Set db = session.CurrentDatabase
Set docSource = db.GetDocumentByUNID(SOURCEDOC)
If docSource Is Nothing Then Error 1120, “Unable to access source document”
Set rtitem = docSource.GetFirstItem (“Body”)
If rtitem Is Nothing Then Error 1130, “Source item not found”

‘ STEP 1 Create temporary document to store the items for export
‘ the document used for exporting must ‘live’ in the same database as the re-imported document
Set dbTemp = session.GetDatabase(“”,”cache.ndk”,False)
If dbTemp Is Nothing Then Error 1110, “Unable to open temp database”
Set docTemp = dbTemp.CreateDocument
Set rtitemTemp = docTemp.CreateRichTextItem (“Body”)
Call rtitemTemp.AppendRTItem (rtitem)
rtitemTemp.Update ‘ rtitem.Update required to write changes to the in memory item

‘ STEP 2 Create DXL Exporter object and export temporary document including all items to a string
Set exporter = session.CreateDXLExporter
sOutput = exporter.Export (docTemp)

‘ Clean up temporary objects used for exporting – will be reused for importing
Delete rtitemTemp
Delete docTemp

‘ STEP 3 Do the string manipulation
sActionCode1 = |dim s as new NotesSession| + Chr(10)
sActionCode1 = sActionCode1 + |Messagebox “This code has been inserted into action 1″,64,s.CurrentDatabase.Title|
‘ add additional code for remaining actions
sOutput = Replace(sOutput,”##FIRSTNAME”,”Klabautermann”)
sOutput = Replace(sOutput,”‘##ACTION1″,sActionCode1)
sOutput = Replace(sOutput,”##SMARTLINK1″,”Smart link”)
sOutput = Replace(sOutput,”##DOCLINK”,|<doclink document=’| + docSource.UniversalID + |’ database=’| + docSource.ParentDatabase.ReplicaID + |’ description=’| + docSource.Subject(0) + |’ />|)
sOutput = Replace(sOutput,”##SIGNATURE”,Session.CommonUserName)

‘ STEP 4 Reimport string to a temporary document
Set importer = session.CreateDXLImporter
Call importer.Import (sOutput,dbTemp)
Set docTemp = dbTemp.GetDocumentByID (importer.GetFirstImportedNoteId)
Set rtitemTemp = docTemp.GetFirstItem(“Body”)

‘ STEP 5 Create mail document, append imported rtitem and send to recipient
Set newDoc = New NotesDocument (db)
newDoc.form = “Memo”
newDoc.Subject = “RT Manipulation Demo”
newDoc.sendTo=”Christian Petters”
Set rtitem = newdoc.CreateRichTextItem(“Body”)
Call rtitem.AppendRTItem (rtitemTemp)
newDoc.Send False

‘ STEP 6 Remove temporary document from cache.ndk
docTemp.Remove (True)
End Sub

5 thoughts on “Notes rich text manipulation using DXL

  1. Well you do not need the NotesDXLexporter and NotesDXLimport Classes to achieve this particular goal.
    You can do this with NotesRichTextNavigator and NotesRichTextRange too. What would really be funny is to handle embedded Objects and Attachments with this.

  2. Hi Thomas,

    grüsse in die alte Heimat 🙂

    Are you able to elaborate a bit on how to create am action hotspot within a richtext item using the NotesRichTextNavigator and NotesRichTextRange? I was looking for an easier solution than DXL export and import to achieve the same but could not source anything.

    And yes, you can use the same functionality to handle embedded objects and attachments. Although you may want to have a look to Andrei’s Blog to find out about some restrictions with regards to attachments.

  3. Pingback: Christian Petters

  4. Hi Christian,

    thanks for this example. But why do you use cache.ndk as a temp database ?

    Whith it, i encounterred error message with templates containing attachments. By creating the tempdoc in the current database, everything works fine.

    Anyway, your code is very usefull and saved me hours of works.


  5. You can use any database you like to store the temporary document. Just keep in mind that the user running the script must have the rights to create documents and, if you want to clean-up (delete) the temporary document afterwards, deletion rights to the document. This may require an author field, containing the name of the user, on the imported document if the highest access to the database is author.

Leave a Reply

Your email address will not be published. Required fields are marked *