Examples: CreateTextNode method

This agent parses the origXML file, which is an exported Notes names.nsf file. It walks the node tree looking for specific information [refer to "Attribute values" in the (Declarations) object] in each "Person document." If the information is missing, prompt the user for input, then update the node tree. These transactions are reported in the logFile. Information from the updated node tree is written to reportFile.

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