NotesDXLExporter and attachments

We have an application that exports documetns with attachments to xml using the LotusScript NotesDXLExporter. Som of our docs have large attachments which we don’t want to include in the exported data in their base64 representation. Pipelining the dxl exported to a simple transformer that removes the attachments in xml is easy enough but ideally the attachments should not be included in the dxl output at all. Yes they are easily removed prior to dxl export but that requires saving the document therefore permanently losing the attachments.

My main concern with my current approach is that it will not cope with very large attachments. Does anyone have any experience of the LS dxl exporter in this area and if so could you perhaps post maximum doc /attachment sizes that are doable in your experience.

Thanks in advance

Subject: NotesDXLExporter and attachments

Sean,

I am having the same issue.

How do you strip out the attachment binary data when doing the export?

Did you resovle a way to do the export with the attachments exported as seperate files?

Kevin

Subject: RE: NotesDXLExporter and attachments

I did this by piping the output of the dxl export to a simple stylesheet (built on the fly in the ls agent) which removed the base64 encoded attachment data. I can give you the stylesheet if u need it (don’t have it to hand) though it is very straightforward. The Lotus XML toolkit, which was the only way to export dxl pre release 6, allowed you to set an option that caused the export process to ignore attachments. Seems this facility is no longer available. Of course you might want to save the attachments to the filesystem separately which again is easy yo do.

Subject: RE: NotesDXLExporter and attachments

Sean,

Thank you. I’m sure it is easy, once you have the insight. Can you post a code snipt, or send me a sample?

khoffman@efrogg.com

Thank you.

Subject: RE: NotesDXLExporter and attachments

I have just given u the complete LotusScript agent code here so much will be irrelevant. However, you should be able to see how the xsl that removes attachments is built and applied

Option Public

Sub Initialize

Dim session As New NotesSession

Dim db As NotesDatabase

Dim doc As NotesDocument

Dim tempDir As String

Dim exporter As NotesDXLExporter

Dim xslStream As NotesStream

Dim dxlStream As NotesStream

Dim dxlTransformer As NotesXSLTransformer

Dim configDoc As NotesDocument

Set db = session.CurrentDatabase

On Error Goto general_err

On Error 4604 Goto transform_err

'get the temp dir

tempDir = Environ("Temp")

If tempDir="" Then

	'we must be on unix

	tempDir = "/tmp"

End If

Set configDoc = db.GetProfileDocument("GCSConfig")

'create the transformer to process the dxl

'it'll just remove the attachments, grl is made with a java agent

Set dxlTransformer = session.CreateXSLTransformer

Set xslStream = session.CreateStream()

Call WriteRemoveAttachmentsStylesheet(xslStream)

Call dxlTransformer.SetStylesheet(xslStream)

Set exporter = session.CreateDXLExporter

Set collection = db.UnprocessedDocuments

Set doc = collection.GetFirstDocument()

While Not(doc Is Nothing)

	Print "dxl exporting doc, unid=" & doc.UniversalID & ",size=" & doc.Size

	' save  all the attachments to disk

	Call SaveAttachmentsToDisk(doc,tempDir)

	' create a stream for to write the grl to

	Set dxlStream = session.CreateStream

	dxlfile$ = tempDir & "/" & doc.UniversalID & ".dxl"

	If Not dxlStream.Open(dxlfile$) Then

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

	Else

		Call doc.ReplaceItemValue("gcs_dbid",configDoc.GetItemValue("DatabaseID")(0))

		Call doc.ReplaceItemValue("gcs_srcid",configDoc.GetItemValue("SourceId")(0))

		Call dxlStream.Truncate()

		Call dxlTransformer.SetOutput(dxlStream)

		Call dxlTransformer.SetInput(exporter)

		Call exporter.SetInput(doc)

		Call exporter.SetOutput(dxlTransformer)

		Call exporter.Process()

		Call dxlStream.close()

	End If	

	Call session.UpdateProcessedDoc(doc)

transform_err_continue:

	Set doc = collection.GetNextDocument(doc)

Wend

Exit Sub

'export_err:

'filedetatch_err:

transform_err:

Msgbox dxlToGrlTransformer.log

Resume transform_err_continue

general_err:

Msgbox Err & ":" & Error

End Sub

Sub WriteRemoveAttachmentsStylesheet(stream As NotesStream)

Call stream.writetext({<?xml version="1.0"?>})

Call stream.writetext({<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   xmlns:DXL="http://www.lotus.com/dxl" version="1.0">})

Call stream.writetext({<xsl:output method="xml"/>})

Call stream.writetext({<xsl:template match="@* | node()">})

Call stream.writetext({<xsl:copy>})

Call stream.writetext({<xsl:apply-templates select="@* | node() "/>})

Call stream.writetext({</xsl:copy>})

Call stream.writetext({</xsl:template>})

Call stream.writetext({<xsl:template match="/DXL:document/DXL:item/DXL:richtext/DXL:par/DXL:attachmentref/DXL:picture">})

Call stream.writetext({</xsl:template>})

Call stream.writetext({<xsl:template match="/DXL:document/DXL:item[@name='$FILE']">})

Call stream.writetext({</xsl:template>})

Call stream.writetext({</xsl:stylesheet>})

End Sub

Sub SaveAttachmentsToDisk(doc As NotesDocument, tempDir As String)

If doc.HasEmbedded Then

	Forall item In doc.Items

		attachDir$ = tempDir & "/" & doc.UniversalID

			'should probably do something better with the error handling here

			'but if the dir already exists that is good enough

		On Error Resume Next

		Mkdir attachDir$

		On Error Goto 0

			'remove all the files in the attachment directory

		fileName$ = Dir$(attachDir$, 0)

		Do While fileName$ <> ""

			fileName$ = Dir$()

			Kill fileName$

		Loop

		If item.Type = RICHTEXT Then

			If Not Isempty(item.EmbeddedObjects) Then

				Forall eo In item.EmbeddedObjects

					If eo.type = EMBED_ATTACHMENT Then

						Call eo.ExtractFile(attachDir$ & "/" & eo.name)

					End If

				End Forall

			End If

		End If

	End Forall

End If

End Sub

Sub DetatchXslsToTempDir(doc As NotesDocument, tempDir As String)

If doc.HasEmbedded Then

	Forall item In doc.Items

		If item.Type = RICHTEXT Then

			If Not Isempty(item.EmbeddedObjects) Then

				Forall eo In item.EmbeddedObjects

					If eo.type = EMBED_ATTACHMENT Then

						Call eo.ExtractFile(tempDir & "/" & eo.name)

					End If

				End Forall

			End If

		End If

	End Forall

End If

End Sub