DomParser AND serialize

I am trying to write an operation that does the following:

  1. export dxl from a database

  2. convert dxl to dom

  3. loop through nodes, and change nodeValue depending on nodeName

  4. import dxl to a database (preferably an existing one).

I realize there are some other steps that are involved in doing the above. I realize that I must:

create a string from the stream of dxl generated from the exporter to create the domparser object.

this stream must be formatted in the correct characterset.

when this stream is fed into the domparser, i must rebuild and output the dxl, node by node, as I am looping through it.

<this is where I am having trouble… i simply don’t know how to format the output so that it will be properly formatted dxl in the end>

so… I tried to serialize the domparser output, but this, no matter what i do, gives me a file much larger than the original dxl i put in. i have tried a number of charactersets, ASCII & UTF-8. it also fails on the import with an error msg stating that there is a missing “=”

Does anyone have any advice for me??

Thanks.

T

i will paste my code in a response to this doc.

Subject: DomParser AND serialize

Sub Initialize Set session = New NotesSession

Set db = session.CurrentDatabase



Set stream = session.CreateStream

path$ = "c:\data\dxl\"

filename$ = "stream.dxl"

filename$ = path$ & filename$

If Not stream.Open(filename$,  "UTF-8") Then

	Messagebox "Cannot open " & filename$,, "Error"

	Exit Sub

End If

Call stream.Truncate



Set stream2 = session.CreateStream

path$ = "c:\data\dxl\"

filename$ = "stream2.dxl"

filename$ = path$ & filename$

If Not stream2.Open(filename$,  "UTF-8") Then

	Messagebox "Cannot open " & filename$,, "Error"

	Exit Sub

End If

Call stream2.Truncate



Dim dbCopy As NotesDatabase

Dim streamDXL As String

Dim docNode As NotesDOMDocumentNode



Set exporter = session.CreateDXLExporter

Call exporter.SetInput(db)

Call exporter.SetOutput(stream)

exporter.ConvertNotesBitmapsToGIF = True

Call exporter.Process

streamDXL = stream.readText(EOL_ANY)

Set domParser=session.CreateDOMParser(streamDXL, stream2)	

domParser.AddXMLDeclNode = True

domParser.InputValidationOption = VALIDATE_NEVER

Call domParser.Process

Call domParser.Serialize( )



filename$ = Left(db.FileName, Len(db.FileName) - 4)

Set dbCopy = New NotesDatabase("", "")

Call dbCopy.Create("", filename$ & "Copy05", True)



Set importer = session.CreateDXLImporter		

Call importer.SetInput( stream2)

Call importer.SetOutput(dbCopy)

importer.ReplaceDBProperties = True

importer.ReplicaRequiredForReplaceOrUpdate = False

importer.ACLImportOption = DXLIMPORTOPTION_REPLACE_ELSE_IGNORE

importer.DesignImportOption = DXLIMPORTOPTION_REPLACE_ELSE_CREATE

Call importer.Process

End Sub

Subject: dxl → dom → serialize() → dxl

just one more thing… when i try a more simple test of just a domparser with input of a previously exported dxl file (3405kb), and output to an empty dxl file, I get a file that is 5009kb. I have tried with different character sets, but the file always comes out larger… and, as stated in my previous post, does not successfully import through the notesdxlimporer.

am i doing something wrong? please advise. thanks.

here is my simple code:

Sub Initialize

Dim session As NotesSession

Dim stream As NotesStream

Dim stream2 As NotesStream

Dim domParser As NotesDOMParser

Dim streamDXL As String



Set session = New NotesSession

Set stream = session.CreateStream

path$ = "c:\data\dxl\"

filename$ = "stream.dxl"

filename$ = path$ & filename$

If Not stream.Open(filename$,  "ASCII") Then

	Messagebox "Cannot open " & filename$,, "Error"

	Exit Sub

End If

’ Call stream.Truncate

Set stream2 = session.CreateStream

path$ = "c:\data\dxl\"

filename$ = "stream2.dxl"

filename$ = path$ & filename$

If Not stream2.Open(filename$,  "UTF-8") Then

	Messagebox "Cannot open " & filename$,, "Error"

	Exit Sub

End If

Call stream2.Truncate



streamDXL = stream.readText(EOL_LF) 

Set domParser=session.CreateDOMParser(streamDXL, stream2)	

domParser.AddXMLDeclNode = True

domParser.ExpandEntityReferences = True

domParser.InputValidationOption = VALIDATE_NEVER

Call domParser.Process

Call domParser.Serialize( )

End Sub

Subject: DomParser AND serialize

I have not read everything you posted, so this might not answer all your questions.Steps 1 - 4 seem OK to me. You do not need a stream. Notes connects the objects and passes the data along the pipeline that you set up.

If you do write the data to a file for some reason, the size of the file depends on whether all the default values of all the attributes are included.

For example, here is very basic code that exports a document, changes the Subject, and imports it again (creating a new document). To add error-handling, use the Log properties of the processor objects to find out what went wrong.

     ' set session, db and doc
     
     Dim dxp As NotesDXLExporter
     Set dxp = session.CreateDXLExporter(doc)
     
     Dim par As NotesDOMParser
     Set par = session.CreateDOMParser(dxp)
     On Event PostDOMParse From par Call ProcessDOM
     
     Dim dip As NotesDXLImporter
     Set dip = session.CreateDXLImporter(par, db)
     
     dxp.Process
End Sub


Sub ProcessDOM(Source As NotesDOMParser)
     Dim items As NotesDOMNodeList
     Set items = Source.Document.GetElementsByTagName("item")
     
     For i& = 1 To items.NumberOfEntries
          Dim item As NotesDOMElementNode
          Set item = items.GetItem(i&)
          If item.GetAttribute("name") = "Subject" Then _
          item.FirstChild.FirstChild.NodeValue = "Rhubarb"
     Next
     
     Source.Serialize
End Sub

Subject: RE: DomParser AND serialize

I need to loop through all documents in a database. For each document old urllinks needs to be replaced by new. These are listed in a config doc.

I’ve tried this way, but have some weird behavior. Bedugging, when returning from the ProcessDOM-sub, the yellow indicator is positionned on the next line (If blnChanged Then), but when I push ‘step into’, the code ends without any reason. No error, no end function… nothing.

Second problem: I don’t want to do the import for documents that don’t need to be changed because no urllinks to replace have been found. I don’t know how to do that…

This is my code (reduced).

Dim blnChanged as Boolean

Sub ProcessDOM(Source As NotesDOMParser)

Dim rootElement As NotesDOMElementNode

Set rootElement = Source.Document.DocumentElement

Dim docList As NotesDOMNodeList

Set docList = rootElement.GetElementsByTagName(“urllink”)

If docList.NumberOfEntries > 0 Then

Dim i As Integer

For i = 1 To docList.NumberOfEntries

Dim eNode As NotesDOMElementNode

Set eNode = docList.GetItem(i)

Dim strAtt As String

strAtt = eNode.GetAttribute(“href”)

Dim strAdjAtt As String

strAdjAtt = strAtt

Dim y As Integer

For y = 0 To Ubound(varOldlink)

strAdjAtt = ReplaceSubstring(Lcase(strAdjAtt), Lcase(Trim(varOldLink(y))), Lcase(Trim(varNewLink(y))))

Next y

If strAtt <> strAdjAtt Then

Call eNode.SetAttribute(“href”, strAdjAtt)

blnChanged = True

End If

Next i

End If

Source.Serialize

End Sub

Function ProcessDatabase(db As NotesDatabase) As Boolean

REM **** INITIALIZE LOCAL ERROR HANDLER

On Error Goto ErrorHandler

ProcessDatabase = False

REM **** DECLARE LOCAL VARIABLES

REM **** WALK THROUGH ALL DOCUMENTS IN THE DATABASE

Set dc = db.AllDocuments

Set doc = dc.GetFirstDocument

Do While Not doc Is Nothing

REM ***** EXPORT DOCUMENT TO DXL AND ADJUST LINKS

blnChanged = False

Dim exporter As NotesDXLExporter

Set exporter = session.CreateDXLExporter(doc)

exporter.ExitOnFirstFatalError = False

Dim parser As NotesDOMParser

Set parser = session.CreateDOMParser(exporter)

On Event PostDOMParse From parser Call ProcessDOM

Dim importer As NotesDXLImporter

Set importer = session.CreateDXLImporter(parser, db)

importer.DocumentImportOption = DXLIMPORTOPTION_REPLACE_ELSE_IGNORE

exporter.Process

REM ***** IF CHANGED, LOG REPLACE LINK ACTION

If blnChanged Then

Call LogDocument (LOGTITLE, " Old link(s) have been adjusted in document with docID " & doc.UniversalID, db.Title & " (" & db.FileName & “)”, “”, doc)

End If

NextDocument:

Set doc = dc.GetNextDocument(doc)

Loop

REM **** FUNCTION ENDED SUCCESSFULLY

ProcessDatabase = True

Exit Function

REM **** ERROR HANDLER

ErrorHandler:

Call LogError(LOGTITLE, Err, "ProcessDatabase: " & Error$ & " in line " & Erl)

Resume NextDocument

End Function