Das Notes Forum

Domino 9 und frühere Versionen => ND9: Entwicklung => Thema gestartet von: platzebo am 17.06.20 - 15:14:29

Titel: Problem beim DXL-Import gelöst - betrifft V9, V10 und v11
Beitrag von: platzebo am 17.06.20 - 15:14:29
Hallo,

ich hatte ein Problem beim Import von einigen DXL-Dateien. Bei einigen funktionierte das nicht.
Es handelt sich dabei um Emails von externen System mit Tabellen.
Einzige Möglichkeit war bis dato die DXL-Datei im Texteditor zu öffnen und mit dem Ytria-Tool ScanEZ den DXL-Import zu versuchen. Die dort ausgegebene Fehlermeldung verwies immer auf die Zeile und das Problem im DXL-File.
Dann habe ich die "<pardef>-Tags manuell so lange entfernt, bis ich die Datei importieren konnte.

Die HCL hat das Problem bestätigt und einen funktionierenden Workarround geliefert :)
Vielleicht kann das ja jemand brauchen

https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0076341

Issue
When using the NotesDXLImporter class to import DXL data, some docuemnts may fail with the error "DXL importer operation failed".  Further investigation using on-line validators indicate that the issue appears to be with the DXL containing a <pardef> tag after a <TableCell>.   

Cause
Our NotesDXLExporter is creating output that the NotesDXLImporter is unable to import do to incorrect <pardef> lines in a TablCell definition.  SPR PALTBL3MK5 has been created for this issue.

Resolution
Development is still looking into a fix for this in the Domino code but we have a work around Import agent that can be used to fix the incorrect lines before being imported and allow the problem documents to be imported correctly.
 
The following agent can be used to import the problem documents.  It is set to run and import any dxl files from c:\     Please note that this code is to be used "As Is" and support can not modify it for use in a customers environment.
 
 
%REM
    Agent APG Import
    Created Feb 19, 2020 by Support Admin/HCL
%END REM
Option Public
Option Declare

Sub Initialize
   
    Dim s As New NotesSession, wksp As New NotesUIWorkspace
    Dim db As NotesDatabase
   
    Dim sfilename As String
       
    Set db = s.Currentdatabase

    REM Open file
    On Error GoTo oops
    sfilename = Dir$("C:\*.dxl")
    Do Until sfilename = ""
        Rem Import DXL into new database
        ProcessFile "C:\" & sfilename, db
        sfilename = Dir$
    Loop
    Exit Sub

oops:
    MsgBox "Error " & Err & ": " & Error & { //}& GetThreadInfo(1) & {:} & Erl
    Exit Sub
End Sub

%REM
    Sub ProcessFile
    Description: Comments for Sub
%END REM
Sub ProcessFile(ByVal filepath$, db As NotesDatabase)
    Dim s As New NotesSession
    Dim stream As NotesStream
    Dim importer As NotesDXLImporter, dom As NotesDOMParser
    Dim streamTmp As NotesStream, domdecl As NotesDOMXMLDeclNode, domdeclNew As NotesDOMXMLDeclNode
    Dim domd As NotesDOMDocumentNode, ns As NotesDOMNodeList, elParstyle As NotesDOMElementNode, i%, cFixed%
   
    Set stream = s.CreateStream
    Call stream.open(filepath, "UTF-8")
    Set dom = s.Createdomparser(stream)
    dom.Inputvalidationoption = VALIDATE_NEVER
    Call dom.Parse(stream)

    Set domd = dom.Document
    Set ns = domd.Getelementsbytagname("parstyle")
    For i = ns.Numberofentries To 1 Step -1
        Set elParstyle = ns.Getitem(i)
        If elParstyle.Getattribute("name") = "" Then
            cFixed = cFixed + 1
            Call elParstyle.Setattribute("name", "untitled")
        End If
    Next
    Dim elPardef As NotesDOMElementNode, elTmp As NotesDOMElementNode, elParent As NotesDOMElementNode
    Dim loosePardefs List As NotesDOMElementNode, cLoose As Long
    Set ns = domd.Getelementsbytagname("pardef")
    For i = 1 To ns.Numberofentries
        Set elPardef = ns.Getitem(i)
        Set elParent = elPardef.Parentnode
        If elParent.nodename = "tablerow" Then
            Set loosePardefs(cLoose) = elPardef
            cLoose = cLoose + 1
        End If
    Next
    Delete ns
    If cLoose Then
        ' some erroneous pardefs were found. Move them to a better location.
        Dim elTablerow As NotesDOMElementNode, nTmp As NotesDOMNode, elCell As NotesDOMElementNode
        ForAll aPardef In loosePardefs
            Set elPardef = aPardef
            Set elTablerow = elPardef.Parentnode
            Set nTmp = elTablerow.lastchild
            ' every tablerow must contain at least one tablecell. Find the last cell in this row and move the pardef to the end of it.
            Set elCell = Nothing
            Do Until ntmp.isnull
                If ntmp.nodename = "tablecell" Then
                    Set elCell = ntmp
                    Exit Do
                End If
                Set ntmp = ntmp.previousSibling
            Loop
            elTablerow.Removechild elPardef
            elCell.Appendchild elPardef
        End ForAll
    End If
    Set importer = s.CreateDXLImporter(dom, db)
    importer.Inputvalidationoption = VALIDATE_NEVER
    importer.Documentimportoption = DXLIMPORTOPTION_CREATE
    Set streamTmp = s.Createstream
    If DOMNODETYPE_XMLDECL_NODE = domd.Firstchild.Nodetype Then
        Set domdecl = domd.Firstchild
        Set domdeclNew = domd.Createxmldeclnode(domdecl.Version, "Unicode", domdecl.Standalone)
        domd.Replacechild domdeclNew, domdecl
    End If
    Call dom.Setoutput(streamTmp)
    dom.Serialize
    streamTmp.Position = 0
    On Error GoTo importFail
    Call importer.Import(streamTmp, db)
    On Error GoTo oops
    Exit Sub
importfail:
    MsgBox "Error " & Err & " line " & Erl & ": " & Error & " (" & StrToken(filepath, "\", -1)& ")" & {} & importer.Log, 0, "Import error"
    Exit Sub
oops:
    Error Err, Error & { //}& GetThreadInfo(1) & {:} & Erl
End Sub