REM Constants found in a Notes names.nsf DXL file
REM Node names
Const DOCUMENT_NODE_NAME = "document"
Const ITEM_NODE_NAME = "item"
REM Attribute names
Const FORM_ATTR_NAME = "form"
REM Attribute values
Const PERSON = "Person"
Const LASTNAME = "LastName"
Const FIRSTNAME = "FirstName"
Const COMPANY = "CompanyName"
Const JOBTITLE = "JobTitle"
Const OFFICE = "Office"
Dim docList As NotesDOMNodeList 'list of <document> nodes
Dim itemList As NotesDOMNodeList 'list of <item> nodes
Dim match As Variant 'used to process specific data in a Person document
Dim session As NotesSession
Dim inputStream As NotesStream
Dim outputStream As NotesStream, outputLog As NotesStream
Dim origXML As String, reportFile As String, logFile As String
Dim NL As String 'carriage return + line feed
Sub Initialize
%REM The relevant structure of the .NSF DXL file is:
<database...> the root element
<document form='Person'> the Person document
<item name='attribute name'>
<text>text value</text>
</item>
</document>
</database>
%END REM
Dim eNode As NotesDOMElementNode 'a <document form= > node
Dim iNode As NotesDOMNode 'an <item> node
Dim tNode As NotesDOMElementNode 'a <text> node; where we append new text data
Dim textChild As NotesDOMNode 'the actual data value
Dim attrNode As NotesDOMAttributeNode 'attributes of <item> node
Dim iAttr As Integer 'attribute counter
Dim iDoc As Integer 'counter for docList
Dim iItem As Integer 'counter for itemList
Dim thisPerson(4) As Variant 'local array stores data from the DOM tree
Dim label(4) As Variant 'corresponding attribute name for array
Const NDATA = 5 'number of items to report on; size of thisPerson array
Dim newData As String 'user input
Dim newChild As NotesDOMNode 'node used for the append operation
Dim m As Integer 'match list counter
Dim db As NotesDatabase
Dim domParser As NotesDOMParser
Dim docNode As NotesDOMDocumentNode
Dim rootElement As NotesDOMElementNode
origXML = "c:\dxl\ShortContacts.xml"
reportFile = "c:\dxl\Update.txt"
logFile = "c:\dxl\UpdateLog.txt"
NL = Chr(13) + Chr(10)
label(0) = FIRSTNAME 'refer to the Attribute values of (Declarations)
label(1) = LASTNAME
label(2) = COMPANY
label(3) = JOBTITLE
label(4) = OFFICE
Set session = New NotesSession
If Not createFiles( "Update Contacts List") Then Exit Sub
Set domParser=session.CreateDOMParser(inputStream)
domParser.Process
Set docNode = domParser.Document
Set rootElement = domParser.Document.DocumentElement
Set docList = rootElement.GetElementsByTagName (DOCUMENT_NODE_NAME)
If docList.NumberOfEntries = 0 Then Exit Sub
REM
REM Update "Person documents"
REM
For iDoc = 1 To docList.NumberOfEntries 'search <document...> nodes
Set eNode = docList.GetItem(iDoc)
If eNode.Attributes.NumberOfEntries > 0 Then
REM Search the node for 'Person' attritube
For iAttr = 1 To eNode.Attributes.NumberOfEntries
If eNode.GetAttribute(FORM_ATTR_NAME) = PERSON Then
REM The node has the right attribute name and value...
REM <document form='Person'>
Set itemList = eNode.GetElementsByTagName (ITEM_NODE_NAME)
If itemList.NumberOfEntries > 0 Then
REM ... and has <item> nodes, therefore,
REM a Person document <document form='Person'> has been found
outputLog.WriteText (NL+"Person document found -- ")
REM Update data in the node
REM Fill existing data into the thisPerson array;
REM items are unordered in the XML file
%REM The text we want is actually in the "grandchild" of iNode
iNode.NodeName = item
tNode.NodeName = text
textChild.NodeType = DOMNODETYPE_TEXT_NODE
textChild.NodeValue = text value, what we are looking for
%END REM
For iItem = 1 To itemList.NumberOfEntries
Set iNode = itemList.GetItem(iItem)
If Not iNode.FirstChild.FirstChild.IsNull Then
Set textChild = iNode.FirstChild.FirstChild
'we are only interested in the first attribute
Set attrNode = iNode.Attributes.GetItem(1)
match = matchList(attrNode.NodeValue)
If Not match(0) = 0 Then _
thisPerson(match(0)-1) = textChild.NodeValue
End If 'node has data
Next '<item> node - iItem
outputLog.WriteText("filled in data array for _
"+thisPerson(1)+NL)
REM Get missing data from the user & update the DOM tree
For iItem = 1 To itemList.NumberOfEntries
Set iNode = itemList.GetItem(iItem)
If iNode.FirstChild.FirstChild.IsNull Then
Set tNode = iNode.FirstChild
Set textChild = iNode.FirstChild.FirstChild
Set attrNode = iNode.Attributes.GetItem(1)
match = matchList(attrNode.NodeValue)
If Not match(0) = 0 Then
'display 'LastName' and get the data
newData = Inputbox(label(match(0)-1)+" for _
"+thisPerson(1))
If Not newData = "" Then
'update the tree
outputLog.WriteText("New data: "+newData+" for _
"+label(match(0)-1)+NL)
Set newChild = _
docNode.CreateTextNode(label(match(0)-1))
newChild.NodeValue = newData
Call tNode.AppendChild(newChild)
End If 'user supplied data
End If 'match found
End If 'no data here
Next '<item> node - iItem
REM write data to report
For m = 0 To NDATA-1
If Not thisPerson(m) = "" Then _
outputLog.WriteText(label(m)+": "+thisPerson(m)+NL)
Next
iAttr = eNode.Attributes.NumberOfEntries 'done with the node
End If 'there are <item> nodes
End If 'this is a "Person document"
Next ' "name" attribute - iAttr
End If 'eNode has Attributes
Next '<document> node - iDoc
REM Prove we updated the DOM tree - Report on it
Call writeDOMtree
outputLog.WriteText (NL + "File processed: " + origXML )
Call outputLog.Close
Messagebox "Log written to " + logFile
End Sub
'Uses docList-the list of <document> nodes in the XML-to process the DOM tree.
Sub writeDOMtree()
Dim enode As notesdomelementnode
Dim node As notesdomnode
Dim anode As notesdomattributenode
Dim text As notesdomnode
Dim i As Integer, j As Integer, k As Integer
Set outputStream = session.CreateStream
outputStream.Open (reportFile)
outputStream.Truncate
outputStream.WriteText("Report on updated DOM"+NL)
For i = 1 To docList.NumberOfEntries
Set enode = docList.GetItem(i)
For j = 1 To enode.Attributes.NumberOfEntries
outputStream.WriteText(NL+"<document form='Person'>"+NL)
Set itemList = enode.GetElementsByTagName (ITEM_NODE_NAME)
For k = 1 To itemList.NumberOfEntries
Set node = itemList.GetItem(k)
Set text = node.FirstChild.FirstChild
If Not text.IsNull Then
Set anode = node.Attributes.GetItem(1)
match = matchList(anode.NodeValue)
If match(0) > 0 Then _
outputStream.WriteText(anode.NodeValue+": "+text.NodeValue+NL)
End If
Next '<item> node
Next 'attribute
Next '<document> node
Call outputStream.Close
Messagebox "Report written to " + reportFile
End Sub
Function matchList(value As String)
matchList = Evaluate( "@Member (""" + value+ """; """ + _
FIRSTNAME + """: """ + LASTNAME + """: """ + _
COMPANY + """: """ + JOBTITLE + """: """ + OFFICE + """)" )
End Function
Function createFiles(title As String)
createFiles = True
'create the output file
Set outputLog = session.CreateStream
outputLog.Open (logFile)
outputLog.Truncate
'write report title
outputLog.WriteText (title + NL)
'open the XML file
Set inputStream = session.CreateStream
inputStream.Open (origXML)
If inputStream.Bytes = 0 Then createFiles = False
End Function