前回 は、DXL を使って文書を新規作成する方法を紹介しました。ただ、DXL の作成は文字列を連結しただけの単純な方法でした。今回は、その DXL の作成を DXL 関連の Notes DOM クラスを使用して作成する方法を整理します。
プログラムの構造は 前回 と揃えています。よって、修正するのは、DXL の文字列を作成する関数 xGetDXL だけとなります。関数で作成する DXL は前回と同じ構造の次の通りとします。
| <document form='DXL_SbS'> <item name='Title'> <text> #2 DOM クラスで DXL 文字列を作成 </text> </item> </document> |
DOMクラスの利用準備
まず、DOM クラスを利用して DXL を操作するためには、NotesDOMParser クラスが必要でした。このクラスは、DXL を LotusScript で扱いやすくなるよう、構造(DOM 文書ツリー)をオブジェクトに変換する役割を担います。
NotesDOMParser オブジェクトの Document プロパティにより取得できる NotesDOMDocumentNode が XML 全体を表し、文書ツリーのルートとなります。
| Dim ns As New NotesSession Dim dprs As NotesDOMParser Dim ddn As NotesDOMDocumentNode ・・・ Set dprs = ns.CreateDOMParser() Set ddn = dprs.Document |
今回は新規文書の作成ですので、DXL をゼロから作成することになります。よって、上記のシンプルなコードで OK です。
ちなみに ddn の値をデバッガで確認すると次の通り、中身は空っぽとなっています。
ノードの作成
ルートの準備ができたので、DXL の中身を追加します。最初は、文書を表す <document> ノードです。
DXL でノードを追加する方法は少し特殊です。
まず、ノードを作成するメソッドは、ルートである NotesDOMDocumentNode オブジェクトにしか存在しません。複数ある Create?????Node というメソッドで、それぞれタイプの違うノードを作成します。
これらメソッドを使って必要なノードを作成して、各ノードオブジェクトの AppendChild メソッドでそのノード配下のノードとしてセットします。
| Dim denCur As NotesDOMElementNode Dim denNew As NotesDOMElementNode ・・・ Set denNew = ddn.CreateElementNode("document") Call denNew.SetAttribute("form", "DXL_SbS") Set denCur = ddn.AppendChild(denNew) |
あえて例えるなら、一旦文書を作成しておいて、あとから返答文書にセットするイメージでしょうか?ノーツ屋としてわからなくもないですが、ちょっと回りくどいですね...
なお、<document> ノードは、フォーム名を form 属性で指定します。SetAttribute メソッドを使用してセットしています。属性はオブジェクトに直接追加できるようですね...
ここまで実行すると、ルートオブジェクトの ddn の NumberOfChildNodes が 1 となりノードの追加が成功したことがわかります。また、DocumentElement や FirstChild などの子ノードにアクセスするためのプロパティにも値がセットされています。
フィールドの作成
文書を表す <document> ノードが作成できたので、次は、フィールドである <item> ノードを追加します。
ノードの追加なので、<document> ノードと同様の手順で作成します。注意すべきは、親となるノードが <document> となるだけです。
|
Set denCur = ddn.AppendChild(denNew) Set denNew = ddn.CreateElementNode("item") Call denNew.SetAttribute("name", "Title") Set denCur = denCur.AppendChild(denNew) |
AppendChild メソッドの戻り値は、追加したノード自身となります。追加した <document> ノードは denCur 変数で受けていますので、これにフィールドを追加することになります。
このように、DOM クラスでノードを追加するには、親となるノードと追加するノードの2つを操作することになります。変数名を工夫するなど、見やすくしておかないと、あとで見た時に理解に時間がかかりそうです。
フィールドの中身の作成
フィールドを表す DXL は、値の型を表す <text> ノードがあり、そのタグの間に値がべた書きされています。この値を表す部分は、DOM クラスでは、NotesDOMTextNode となります。
具体的には次のように <text> ノードを作成し、それに対して、テキストノードを追加します。テキストノードは NotesDOMTextNode オブジェクトとなるので、別の変数 dtnNew で受け取っています。
| Dim dtnNew As NotesDOMTextNode ・・・ Set denCur = denCur.AppendChild(denNew) Set denNew = ddn.CreateElementNode("text") Set denCur = denCur.AppendChild(denNew) Set dtnNew = ddn.CreateTextNode("#2 DOM クラスで DXL 文字列を作成") Call denCur.AppendChild(dtnNew) |
DXL を文字列で取得
DXL の構造(DOM 文書ツリー)は、NotesDOMParser が管理していました。ここから、完成した DXL をテキスト文字列で抽出する必要があります。
|
Dim nst As NotesStream ・・・ Set nst = ns.CreateStream() Call dprs.SetOutput(nst) Call dprs.Serialize() xGetDXL = nst.ReadText() |
まず、SetOutput メソッドを使用して、NotesDOMParser クラスの出力先を指定します。今回は出力先に NotesStream クラスのオブジェクトを使用しました。
NotesStream クラスは、テキストデータやバイナリデータを効率よく扱うためのクラスです。今回は、NotesDOMParser の出力を NotesStream で受け取り、ReadText メソッドで DXL 全体を文字列として取得しています。
なお、NotesDOMParser クラスの Serialize メソッドは、DOM 文書ツリーを検索し XML を出力オブジェクトにストリーミングします。この命令を実行することにより、NotesStream クラスのオブジェクト nst に値がセットされます。
まとめ
xGetDXL 関数の全体を掲載します。
文書を作成して、フィールドを1つ作成するだけですが、なかなか長いコードとなります。NotesDocument クラスなど LotusScript 標準のクラスで実現できることは、わざわざDXL で実施する必要はなさそうですね...
|
Function xGetDXL() As String Dim ns As New NotesSession Dim dprs As NotesDOMParser Dim ddn As NotesDOMDocumentNode Dim denCur As NotesDOMElementNode Dim denNew As NotesDOMElementNode Dim dtnNew As NotesDOMTextNode ' DXL 作成準備 Set dprs = ns.CreateDOMParser() Set ddn = dprs.Document '<document>ノード作成 Set denNew = ddn.CreateElementNode("document") Call denNew.SetAttribute("form", "DXL_SbS") Set denCur = ddn.AppendChild(denNew) '<item>ノード作成 Set denNew = ddn.CreateElementNode("item") Call denNew.SetAttribute("name", "Title") Set denCur = denCur.AppendChild(denNew) '<text>ノード作成 Set denNew = ddn.CreateElementNode("text") Set denCur = denCur.AppendChild(denNew) '<text>ノードに値を作成 Set dtnNew = ddn.CreateTextNode("#1 DXLをDOMクラスから作成") Call denCur.AppendChild(dtnNew) '作成した DXL をテキストで抽出 Dim nst As NotesStream Set nst = ns.CreateStream() Call dprs.SetOutput(nst) Call dprs.Serialize() xGetDXL = nst.ReadText() End Function |
| 前回 | DXL Step-by-Step | 次回 |


0 件のコメント:
コメントを投稿