Link to home
Start Free TrialLog in
Avatar of p_partha
p_partha

asked on

Richtext find and replace

Hi Guys
Anybody has a quick code to find and replace a text in richtext using NotesDXL . If yes, can it be shared :). I had to do some stuff quickly and i don't want the headache of writing the entire code. Any ideas, and oh i know about Midas, but i specifically need NotesDXL and NotesDomParser code.

TIA
Partha
Avatar of Sjef Bosman
Sjef Bosman
Flag of France image

Hi Bro, yours is a difficult question... I'd be happy to develop something with you, but since you asked for a quicky I didn't respond. You suggest that, to write the code, you'll end up with a headache, but is it really that difficult? Let's dive into it!

First, let's have some design. How id you think to attack this interesting problem? Something like

    get document
    get richtext field
    dump richtext to file using Notes' DXL methods
    parse DXL and make alterations
    reload richtext from DXL
    save document
Avatar of p_partha
p_partha

ASKER

Bro, if you are with me on this, we can easily crack it  .....

But here is some code i got from notes.net, but couldn't make it to work, as it was throwing a error that Domparser is not initialized, i must be doing something silly , dont' know what , may be another pair of eyes would do :

      Dim session As New notessession
      Dim db As notesdatabase
      Set db = session.currentdatabase
      Dim ws As New notesuiworkspace
      Dim uidoc As notesuidocument
      Dim doc As notesdocument
      Set uidoc = ws.currentdocument
      Set doc = uidoc.document
      
      
      
      Dim exporter As NotesDXLExporter ' exports notes doc to XML code
      Dim domParser As NotesDOMParser ' transforms XML code to a DOM tree
      Dim importer As NotesDXLImporter ' imports XML code as notes document
      Dim itemList As NotesDOMNodeList ' a list of <item>-nodes
      Dim node As NotesDOMNode 'an <item> node
      Dim aNode As NotesDOMAttributeNode 'a "name" attribute
      
      
'create a temporary RichText field in the notes doc you want to work with
      
      Set rt = doc.createRichTextItem("TMPXML")
      
      
      
      
      Set exporter = session.CreateDXLExporter
      Set domParser = session.createDOMParser
      Set importer = session.CreateDXLImporter
      
'set the NotesDocument as input for the exporter:
      
      Call exporter.SetInput(doc)
      
'set the exporter as input and the rt as output for the domParser:
      
      Call domParser.setInput(exporter)
      Call domParser.SetOutput(rt)
      
'set some options for the importer:
      
      importer.ACLImportOption = DXLIMPORTOPTION_IGNORE
      importer.DesignImportOption = DXLIMPORTOPTION_IGNORE
      importer.DocumentImportOption = DXLIMPORTOPTION_REPLACE
      
'run the exporter:
      
      Call exporter.process
'---
'get the list of <item> elements:
      
      Set docNode = domParser.Document
      Set rootElement = domParser.Document.DocumentElement
      Set itemList = rootElement.GetElementsByTagName ("item")
      
'and search the itemList for your RichText field, f.g. "Body":
      
      For k = 1 To itemList.NumberOfEntries
            Set node = itemList.GetItem(k)
            Set aNode = node.Attributes.GetItem(1)
            If (Ucase(aNode.AttributeValue) = Ucase("BLASTEMAILBODY")) Then
' here we have the node which represents the BODY-field of the notes document
' and we're delegating the work to a sub-function
                  Call parseChild(node.FirstChild, doc)
            End If
      Next '<item> node
' the parseChild() has done all work, now we have a modifed tree of XML data in the
' domParser object
' now we order the domParser to put out his data to the temporary RichText field
      Call domParser.serialize()
' and set this RichText field as input for the importer
      Call importer.setInput(rt)
' the output is for sure this current database
      Call importer.setOutput(db)
' and tell the importer to do the import-process
      Call importer.process()
' finally we're removing the temporary RichText field
      Call doc.RemoveItem("TMPXML")
      
      
'the sub "parseChild" does the work (and does some recursion to walk down the DOM tree):
Oh, here is other functions :
Private Sub parseChild(node As NotesDOMNode, doc As NotesDocument)
      Dim child As notesdomnode
      Dim numChildNodes As Integer
      
      If Not (node.isNull) Then
            
            numChildNodes = node.NumberOfChildNodes
            
            If Not ( node.HasChildNodes) And (node.NodeType = DOMNODETYPE_TEXT_NODE) Then
                  Call doWork(node, doc)
            End If
            
            Set child = node.FirstChild
            While numChildNodes > 0
                  Call parseChild(child, doc)
                  Set child = child.NextSibling ' Get next node
                  numChildNodes = numChildNodes - 1
            Wend
      End If
End Sub


Private Sub doWork(node As NotesDOMTextNode, doc As NotesDocument)
      Dim s As String
      s = node.nodeValue
      l = Len(s)
      s = "Partha"
      Call node.replaceData(1, l, s)
End Sub
I left my eyes on the couch downstairs... Maybe later today. ;-)
Ah, oh, no, can't be true... Don't you use
    Option Declare
in your Options section?? Otherwise you would have found out that DXLIMPORTOPTION_REPLACE has no value. Unless of course your code above isn't complete, and there is an include-file missing. The same probaly goes for the other constants. Ah, no, it's the only one: it just doesn't exist, it's either DXLIMPORTOPTION_REPLACE_ELSE_IGNORE or DXLIMPORTOPTION_REPLACE_ELSE_CREATE

Tsk, tsk, tsk!
It stops on the line
    Call domParser.SetOutput(rt)
indeed with the error you mentioned, but there's more:
    DomParser output object is invalid, uninitialized, or not explicitly declared and strongly typed.

I assume therefore that you must do something with rt. What? That will be discussed in the episode after my dinner ;)
I did declare rt and it replaces kind of now... which is a good sign:) i will keep you posted abt the other learnings. This process has taken most of my time (although i don't have any :(( )


Partha
ASKER CERTIFIED SOLUTION
Avatar of Sjef Bosman
Sjef Bosman
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Bro
So it works (kind of)... ;)

Thanks for the grade, and you're always welcome!