#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 件のコメント:
コメントを投稿