連載

.NETで簡単XML

第2回 プログラムでXML文書を作成する

株式会社ピーデー 川俣 晶
2003/03/21

Page1 Page2 Page3

 以下は、実際にXmlTextWriterクラスを使用したサンプル・ソースである。Windowsアプリケーションのテンプレートでプロジェクトを作成し、フォームのLoadイベントに実行するコードを書き込んでいる。結果は、System.Diagnostics名前空間のTraceクラスのWriteメソッドで出力している。これは、統合開発環境内で実行したとき、出力ウィンドウに文字列を出力するので、そこを見て結果を確認できる。

 自動生成されたコードをすべて掲載しても意味がないので、ソースは要所のみを掲載する(以下、記事中ではVB.NETでのサンプル・コードを掲載する。同様の処理を行うC#のコードについては、コードは掲載せずにコードへのリンクだけを示す)。

 次に示すのは、使用するクラスの名前空間のImportsステートメントである(C#ではusingディレクティブ)。これをソースの先頭に追加しておく。

Imports System.IO
Imports System.Xml
VB.NETでXmlTextWriterクラスを使用するためのImportsステートメント
C#でXmlTextWriterクラスを使用するためのusingディレクティブ

 そして、以下がサンプル・ソースの本体である。フォームのLoadイベントに書き込んである。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim stringWriter As StringWriter = New StringWriter()
  Dim xmlWriter As XmlTextWriter = New XmlTextWriter(stringWriter)
  Try
    xmlWriter.WriteStartDocument()
    xmlWriter.WriteStartElement("a")

    xmlWriter.WriteStartAttribute("attr1", "")
    xmlWriter.WriteString("sample1")
    xmlWriter.WriteEndAttribute()

    xmlWriter.WriteAttributeString("attr2", "", "sample2")

    xmlWriter.WriteStartElement("b")
    xmlWriter.WriteEndElement()

    xmlWriter.WriteString(Chr(13) & Chr(10))

    xmlWriter.WriteStartElement("c")
    xmlWriter.WriteString("sample3")
    xmlWriter.WriteEndElement()

    xmlWriter.WriteElementString("d", "sample4")

    xmlWriter.WriteEndElement()

    xmlWriter.WriteWhitespace(Chr(13) & Chr(10))
    xmlWriter.WriteComment("end of document")

    xmlWriter.WriteEndDocument()
  Finally
    xmlWriter.Close()
  End Try
  Trace.Write(stringWriter.ToString())
End Sub
XmlTextWriterクラスを利用する例(VB.NET版)
XmlTextWriterクラスを利用する例(C#版)

 これを実行すると以下のような結果が得られる。

<?xml version="1.0" encoding="utf-16"?><a attr1="sample1" attr2="sample2"><b />
<c>sample3</c><d>sample4</d></a>

<!--end of document-->
作成されたXML文書

 さて、ソースの中身を見てみよう。

Dim xmlWriter As XmlTextWriter = New XmlTextWriter(stringWriter)
 最初のポイントは、XmlTextWriterクラスのコンストラクタである。このコンストラクタは3種類ある。1つ目は、TextWriterクラスのインスタンスを引数に取るもの。2つ目はStreamクラスとEncodingクラスのインスタンスを引数に取るもの。3つ目はファイル名の文字列とEncodingクラスのインスタンスを引数に取るものである。ここでは、最初のものを使っている。引数には、StringWriterクラスのインスタンスを渡しているが、もちろんStringWriterクラスはTextWriterクラスを継承しているので、これで機能する。これによって、XmlTextWriterクラスの出力メソッドを使って書き込まれた内容は、StringWriterクラスのインスタンス内部に記録されていくことになる。このサンプルは結果を表示したいだけなので、特にファイルなどに出力しないで蓄積するだけでOKである。

 次のポイントは、「Write」で始まる名前を持つ多数のXmlTextWriterクラスのメソッドである。出現順に見ていこう。

xmlWriter.WriteStartDocument()
 WriteStartDocumentメソッドはXML宣言を出力するメソッドである。引数に何も指定していないが、たいていはこれで問題ない。利用時に変更する可能性があるのは、符号化方式の名前と非依存文書宣言の指定だけである。符号化方式の名前は、出力に使用するエンコーディング情報から取得できるので指定する必要はない。この例では、utf-16という文字列になっているが、.NET Frameworkの文字列型の内部表現はUTF-16なので、これで問題ないことになる。非依存文書宣言の内容を指定したい場合は、それを指定できる引数付きのWriteStartDocumentメソッドを使用する。

xmlWriter.WriteStartElement("a")
 次はWriteStartElementメソッドである。これは、要素の始まりを出力する。注意することは、要素の始まりであって、開始タグではないことである。このメソッドの呼び出しだけでは開始タグの出力は完結しない。これに引き続いて、属性を出力するメソッドを呼び出すことができ、それらは開始タグの内部に出力されるわけである。WriteStartElementメソッドには次の3つのバリエーションがある。

  • 開始タグの名前として、1つだけの文字列(ローカル名)のみを指定するもの
  • ローカル名と名前空間URIを指定するもの
  • 名前空間接頭辞(プリフィックス)とローカル名と名前空間URIを指定するもの

 2番目のものは、名前空間URIに対応する名前空間接頭辞をXmlTextWriterクラスのインスタンスが知っている場合に使用できるものである。今回の例では、名前空間を使用していないので、引数が1つのメソッドを使っている。

xmlWriter.WriteStartAttribute("attr1", "")
 次に登場するのはWriteStartAttributeメソッドである。これは、属性を開始する文字列を出力するメソッドである。属性には名前と値が必ず存在する。このメソッドは値の直前までを出力する。そこには属性の名前が含まれるので、このメソッドの引数にはそれを指定する必要がある。このメソッドには次の2つがある。

  • 属性の名前として、ローカル名と名前空間URIを指定するもの
  • 名前空間接頭辞(プリフィックス)とローカル名と名前空間URIを指定するもの

 ここでは前者を使用している。しかし、このサンプル・ソースでは名前空間を使わないので、空文字列「""」を指定している。XMLの名前空間では、空文字列は名前空間なしを意味する。

xmlWriter.WriteString("sample1")
 次はWriteStringメソッドである。これは単純に文字データを出力するメソッドである。いろいろな場面で利用するもので、属性の値を出力するのは、使い方の1つにすぎない。後で、要素の内容の文字データを出力するために使用している例が出てくる。ここで注意してほしいのは、このメソッドは文字列をそのまま出力するわけではなく、変更してしまう可能性があるということだ。XMLではいくつかの特別な文字をそのまま記述できない制約がある。そのような文字は、定義済み実体の参照などに置き換えられる。

xmlWriter.WriteEndAttribute()<
 続いて出てくるのはWriteEndAttributeメソッドである。このメソッドは、属性の終わりを出力する。具体的には属性の値を閉じる引用符を出力することになる。

xmlWriter.WriteAttributeString("attr2", "", "sample2")
 属性を出力するにはもっと便利なメソッドもある。WriteAttributeStringメソッドは1回のメソッド呼び出しで、名前と値を含む属性全体を出力してくれる。このメソッドも、WriteStartElementメソッドなどと同じように、名前空間の指定方法の違いにより3種類のバリエーションが存在する。しかし、出力する値も渡すので引数の数は1つ多い。

xmlWriter.WriteStartElement("b")
 ここで再びWriteStartElementメソッドが記述されている。サンプル・ソースでは、WriteStartElementメソッドで開始タグを書き始めて属性を出力してきたが、ここまで開始タグを閉じるためのメソッドを呼び出していない。それなのに、次の要素の開始タグを書き始めさせてよいのだろうか。実はよいのである。XmlTextWriterクラスは、現在の状態をしっかり把握していて、WriteStartElementメソッドが呼び出された時点で、まだ閉じていなかった開始タグを閉じる文字列を自動的に出力してくれるのである。

xmlWriter.WriteEndElement()
 次に、WriteEndElementメソッドが記述されている。これは、要素を閉じる内容を出力するものである。一見、終了タグを書いてくれる機能のように思えるが、実際に出力されるものはそれに限らない。開始タグの直後に内容を何も出力しないで、このWriteEndElementメソッドを呼び出すと、開始タグは空要素タグに化ける。つまり、まだ開始タグが閉じられていないなら、WriteEndElementメソッドは終了タグの代わりに「/>」を出力するだけで、空要素タグとして終わらせることが可能なのである。ここで記述されているWriteEndElementメソッドは、WriteStartElementメソッドの直後なので、空要素タグを出力する。


 INDEX
  .NETで簡単XML
  第2回 プログラムでXML文書を作成する
    1.XML文書をプログラムから読み書きする方法
  2.XmlTextWriterクラスを使用したサンプル(1)
    3.XmlTextWriterクラスを使用したサンプル(2)

更新履歴
【2003/03/24】本ページの冒頭にあるVB.NETでXmlTextWriterクラスを使用するためのImportsステートメントにおいて、「Imports System.Xml」の前に「Imports System.IO」が抜けていました。お詫びして訂正させていただきます。
 
インデックス・ページヘ  「連載 :.NETで簡単XML」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間