2024/12/28

DXL Step-by-Step:#46)添付ファイルの取得 ①

#44#45 で文書内の添付ファイルと DXL の関係をまとめました。この情報を使って、DXL 経由で添付ファイルのダウンロードに挑戦します。


エージェントの準備と仕様

DXL において、添付ファイルは Base64 でエンコードされた文字列で表現されます。ファイルとして取得するにはデコードする必要があります。この流れは、インラインイメージから画像を取得した処理と同様です。そこで、今回は『#42)インラインイメージの取得』で作成したエージェントをコピペしてスタート地点とします。

また、処理を単純にするため、リッチテキスト内の最初の添付ファイルをダウンロードするものとします。インラインイメージの取得でも最初の画像をダウンロードしていたので、この点も同じですね。


添付ファイルの取得

まずは、最初の添付ファイルをダウンロードする関数です。

#42 の xGetDXL_FirstInlineImage に相当する関数で、取得した添付ファイルを NotesStream オブジェクトで返します。戻り値はファイル名となっています。

Function xGetDXL_FirstAttachment(vnd As NotesDocument, ByVal vsFld As String, rns As NotesStream) As String
   'DXL の準備
   Dim dprs As NotesDOMParser
   Set dprs = xGetDOMParser(vnd)

   'DOM ツリーのルートを取得
   Dim ddn As NotesDOMDocumentNode
   Set ddn = dprs.Document

   'リッチテキストの取得
   Dim denRT As NotesDOMElementNode
   Set denRT = xGetDXL_item(ddn, vsFld)

   '添付情報の取得
   Dim denRef As NotesDOMElementNode
   Set denRef = xGetDXL_FirstNodeByName(denRT, "attachmentref")

   If Not (denRef Is Nothing) Then
      'ファイル名取得
      Dim sName As String
      Dim sDisp As String
      sName = denRef.GetAttribute("name")
      sDisp = denRef.GetAttribute("displayname")

      '$FILE フィールド取得
      Dim denFile As NotesDOMElementNode
      Set denFile = xGetDXL_FileItem(ddn, sName) 'Notes 内部の名称で検索

      If Not (denFile Is Nothing) Then
         'ファイルの中身を取得
         Dim denData As NotesDOMElementNode
         Set denData = xGetDXL_FirstNodeByName(denFile, "filedata")

         If Not (denData Is Nothing) Then
            Dim dtn As NotesDOMTextNode
            Dim nst As NotesStream
            Dim sB64 As String

            'エンコードされたファイルを取得
            Set dtn = denData.FirstChild
            sB64 = dtn.NodeValue

            'デコードしてストリームとして取得
            Set nst = xns.CreateStream()
            Call Base64ToBinary(sB64, nst)

            '戻り値セット
            Set rns = nst
            xGetDXL_FirstAttachment = sDisp
         End If
      End If
   End If
End Function

少し長いコードなので、ポイントを順に解説します。


添付ファイルの取得(リッチテキスト内)

リッチテキスト内に存在する最初の添付ファイルを取得する部分です。以前作成した関数 xGetDXL_FirstNodeByName を使用して、リッチテキスト配下の最初の attachmentref ノードを取得します。

   '添付情報の取得
   Dim denRef As NotesDOMElementNode
   Set denRef = xGetDXL_FirstNodeByName(denRT, "attachmentref")


添付ファイル名の取得

attachmentref ノードが取得できたら、そのノードの属性から添付ファイル名を取得します。name 属性は文書内で一意のファイル名、displayname 属性が添付時のファイル名となります。

   If Not (denRef Is Nothing) Then
      'ファイル名取得
      Dim sName As String
      Dim sDisp As String
      sName = denRef.GetAttribute("name")
      sDisp = denRef.GetAttribute("displayname")

      '$FILE フィールド取得
      Dim denFile As NotesDOMElementNode
      Set denFile = xGetDXL_FileItem(ddn, sName) 'Notes 内部の名称で検索

xGetDXL_FileItem 関数は文書内の添付ファイル($FILE フィールド)を探し出し、ファイルの実体(file ノード)取得する関数です(詳細は後述)。文書内で一意な名前 name 属性の値を引数に検索しています。


ファイルの実体の取得

確認する限り file ノード配下には filedata しか存在しないようなのですが、念のため xGetDXL_FirstNodeByName 関数を使用して検索しています。

      If Not (denFile Is Nothing) Then
         'ファイルの中身を取得
         Dim denData As NotesDOMElementNode
         Set denData = xGetDXL_FirstNodeByName(denFile, "filedata")

filedata ノードの配下はテキストノードで Base64 でエンコードされたファイルの実体でした。これをデコードして NotesStream のオブジェクトに変換しています。

この部分はインラインイメージの処理と全く同じですね。

         If Not (denData Is Nothing) Then
            Dim dtn As NotesDOMTextNode
            Dim nst As NotesStream
            Dim sB64 As String

            'エンコードされたファイルを取得
            Set dtn = denData.FirstChild
            sB64 = dtn.NodeValue

            'デコードしてストリームとして取得
            Set nst = xns.CreateStream()
            Call Base64ToBinary(sB64, nst)

            '戻り値セット
            Set rns = nst
            xGetDXL_FirstAttachment = sDisp
         End If

最後にこの関数の戻り値として、添付時のファイル名である sDisp (displayname 属性)をセットしています。


次回の予告

今回は添付ファイルをダウンロードする処理の全体像を解説しました。次回は、後述するとしていた $FILE フィールドを取得する関数 xGetDXL_FileItem を中心に説明します。


前回 DXL Step-by-Step 次回


0 件のコメント:

コメントを投稿