Das Notes Forum

Domino 9 und frühere Versionen => ND8: Entwicklung => Thema gestartet von: bikerboy am 15.07.09 - 09:16:57

Titel: Mit DXL Arbeiten
Beitrag von: bikerboy am 15.07.09 - 09:16:57
Hallo ich arbeite zur Zeit gerade an einem Projekt in dem ich viel DXL verwende,

leider blicke ich durch die Klassen nicht ganz durch.

Ich exportiere meine Sachen immer in DXL und mache eine aufwendige , aber fehleranfällige, Stringbearbeitung.

Gibt es da keine andere Möglichkeit ?

Titel: Re: Mit DXL Arbeiten
Beitrag von: MadMetzger am 15.07.09 - 09:24:01
Eine elegante aber auch nicht ganz einfache Möglichkeit wäre mit XSLT (http://de.wikipedia.org/wiki/Xslt) die DXL-Dateien zu bearbeiten. Die Klasse NotesXSLTransformer sollte dabei dein Freund sein, habe ich diesem Thread (http://atnotes.de/index.php/topic,45638.0.html) entnommen.
Titel: Re: Mit DXL Arbeiten
Beitrag von: pram am 17.07.09 - 11:20:32
Wir machen auch viel mit DXL, die Stringbehandlung übernimmt aber meist ein XSLT-Transoformer und/oder SAX-Parser. Ich habe anfangs auch Konstrukte der Art
Code
Strright("<tag>", strleft("</tag>",s))
verwendet, weil es "einfach" war, aber schnell festgestellt, dass es 1000 Sonderfälle gibt. Und so ein Parser ist doch relativ einfach, wenn man das SAX-Konzept mal verstanden hat  ;D

Gruß
Roland
Titel: Re: Mit DXL Arbeiten
Beitrag von: bikerboy am 20.07.09 - 16:04:53
Hast du denn einen Artikel für mich der sich damit beschäftigt, bin aus der Hilfe nicht schlau geworden.
Titel: Re: Mit DXL Arbeiten
Beitrag von: MadMetzger am 20.07.09 - 21:08:05
Hier (http://atnotes.de/index.php/topic,44896.0.html), hier (http://atnotes.de/index.php/topic,44845.0.html)  und hier (http://atnotes.de/index.php/topic,45638.0.html) findest du etwa ganz kleine Beispiele. Es lohnt sich aber auf allgemeiner Ebene mit XML, XSLT, XML-Schema und co auseinanderzusetzen.
Titel: Re: Mit DXL Arbeiten
Beitrag von: pram am 20.07.09 - 21:31:26
Einen Artikel hab ich leider nicht, aber ich kann in Etwa aufzeigen wie wir das gemacht haben (Bitte aber um Verständnis, dass ich nicht den kompletten Code posten werde, insbesondere das XSLT da doch relativ viel Know how darinsteckt. Der Code ist weiterhin stark verkürzt, ich hab mir erlaubt die meisten DIM's weg zu lassen  ;) )

Code
' also, als erstes brauchen wir hier eine Klasse die das als "Einheit" zusammenfasst
Public Class FocConvertRtfToMime As FocSldObject
  private state as integer ' Variable für die Statemachine
  currElement as string ' aktuelles Element

  ' Die DXL-Konvertierungsmethode
  Private Function doDxlConversion(doc As NotesDocument, item As String, htmlStream As NotesStream)
    Set  exporter 		=  session.CreateDXLExporter
    exporter.ConvertNotesbitmapsToGIF 	= True		' Pflicht
    Call exporter.SetInput(doc)
    Set  parser = session.CreateSAXParser(exporter)

    ' Hier werden die Callbacks des Sax-Parsers registriert
    On Event SAX_StartElement 	From parser Call SAXStart
    On Event SAX_Characters 		From parser Call SAXChar
    On Event SAX_EndElement 		From parser Call SAXEnd
    Set  xsltStream 	=  session.CreateStream
    Call xsltStream.WriteText(XSLT_TRANSFORM) ' hier das XSLT welches sich für die RTF->HTML-Übersetzung kümmert
    ' Die Idee die dahinter steckt stammen aus http://pd4ml.com/i/Dev_Spellman_Leverage%20DXL.pdf
    xsltStream.Position = 0
    Set  transformer	=  session.CreateXSLTransformer(parser,xsltStream,htmlStream)
    Call exporter.process() ' Stößt die Kette DXL-Export->SAX->XSLT an. Das fertige HTML steht nun in htmlstream
  end function

  ' Diese Sub wird immer dann aufgerufen, wenn der Saxparser an einen öffnenden Tag vorbei kommt
  Sub SAXstart (Source As Notessaxparser, Byval elementname As String, Attributes As NotesSaxAttributeList)
    Select Case (elementname)
      Case "item": 
        If Lcase(Attributes.GetValue("name"))="body" Then
          state = START_CONVERT
        End If
    End Select
    currElement = elementname ' aktuellen Elementnamen merken (für saxchar)
    if (state >= START_CONVERT) then
      Source.Output("<" + elementname) ' element 1:1 nach Output (sprich XSLT) schreiben
      i = Attributes.Length
      While(i > 0) ' Nun noch die Attribute schreiben (umständlich, geht leider nicht anders)
        Call source.Output(" " +Attributes.GetName(i)+"=")
        Call source.Output({"} +FocXMLTools.escape(Attributes.GetValue(i))+ {"})
        i = i - 1
      Wend
      Source.Output(">") ' fertig
    end if
  end sub	

  ' wird immer nach SaxStart aufgerufen, wenn Zeichen im jeweiligen Tag enthalten sind
  Sub SAXChar (Source As Notessaxparser, Byval Characters As String, Count As Long)
    if state < START_CONVERT then exit sub ' noch nichts zu tun
    Select Case currElement
    Case "gif","jpeg":	Source.Output(createImage(characters, currElement)) ' einen Anhang erzeuten
    Case Else:		Source.Output(FocXMLTools.escape(characters)) ' Stream 1:1 an den XSL-Transformer weitergeben
    End Select
  end sub

  ' wird beim schließenden Tag aufgerufen (Tags wie <par/> rufen unmittelbar saxStart + saxEnd auf)
  Sub SAXend (Source As Notessaxparser, Byval ElementName As String)
    if state < START_CONVERT then exit sub ' noch nichts zu tun
    if currElement = "item" then state = STOP_CONVERT
  end sub

  ' erzeugt Bild
  Private Function createImage(base64content As String, imagetype As String) As String
    call writeBase64ToMime(base64content, "image" + imgCount + "." +imagetype)  ' Das Bild in das Mime-Feld schreiben
    createImage = "<img src = 'image" + imgCount + "." +imagetype +"'/>" ' entsprechenden HTML-Tag generieren
  end function

end class

Im Wesentlichen ist dies also eine Pipeline aus DXL-Export->SAX->XSLT->Notesstream wobei der Sax-Parser hier eine vorverarbeitung macht, in dem er GIF/JPEG-Tags als Attachments eines MIME-Entities schreibt und den restl. DXL-Stream an den XSLT weiter leitet. Dieser macht dann die restl. Konvertierung von RTF->HTML (er macht es noch nicht perfekt, aber besser als der HTTP-Task in Notes  ;D)

Den SAX-Teil hab ich mit den notwendigen Callbacks und Statusvariablen in eine eigene Klasse gepackt (so wie es sich gehört  :) ), dann wirds übersichtlich(er)

Ich hoffe ich konnte dir und evtl ein paar anderen die zündende Idee liefertn

Gruß
Roland