連載

.NETで簡単XML

第3回 XML文書を読み書きするプログラムの作成

株式会社ピーデー 川俣 晶
2003/04/08

Page1 Page2 Page3 Page4 Page5

 では具体的な説明に入ろう。IsStartElementメソッドは、現在のノードが指定した名前の要素の開始位置かどうかを判定する機能を持っている。その位置であれば、trueを返す。ノードの種類がElementであるかどうかを調べて、それからノードのNameプロパティなどを調べる手順を1回で行うものであるといえる。次に、ReadElementStringメソッドは、WriteElementStringメソッドの読み込み版とでもいうべきものである。指定された名前の要素とその内容のテキストを読み取る。基本的には、「開始タグ+テキスト+終了タグ」という一連のシーケンスを読み取って、タグの名前が指定された名前に一致しているかを確認し、テキストを返すわけである。これを使えば、単純な「開始タグ+テキスト+終了タグ」という形式の情報を1回のメソッド呼び出しで読み取ることができる。順番は前後するが、次にGetAttributeメソッドにも注目しておこう。このメソッドは、ノードが要素の開始位置にあるときに、指定した名前の属性の値を取り出す機能を持っている。通常は名前を指定して属性の値を読み取ることが多いので、MoveToFirstAttributeメソッドとMoveToNextAttributeメソッドを繰り返すよりも使い勝手がよいだろう。

 最後にEOFプロパティにも触れておこう。前の例では(XmlReaderクラスの)Readメソッドの戻り値で終了を判定していたが、EOFプロパティを調べることでも終了を判定できる。EOFプロパティはすべてのデータを読み込んだあとにtrueの値を取るようになる。このサンプル・プログラム内にはノードの位置を進めるメソッドが複数あるので、個別に判定させずに、EOFプロパティを用いて判定処理を1個所に集めているというわけである。なお、このサンプル・プログラムでは名前空間を使用している。名前空間URIを「http://www.atmarkit.co.jp/ns/sample/person/」として、これを文字列定数「ns」で参照して指定している。

 さて、ここで重要な説明に入る。ReadElementStringメソッドは「開始タグ+テキスト+終了タグ」という形式の情報を読み取るが、読み取りが終わったときに、readerは終了タグの次のノードを指し示しているのである。もし、ループの最初に必ず(XmlReaderクラスの)Readメソッドを呼び出す仕様だと、ReadElementStringメソッドを実行後にReadメソッドをすぐ実行することになり、ノードは終了タグの次の次を示すようになってしまう。そうすると、終了タグの次のノードを処理するチャンスが永遠になくなってしまう。そこで、このサンプル・プログラムでは、ReadElementStringメソッドを実行した場合は、(XmlReaderクラスの)Readメソッドを実行することなく、ループの最初に戻るように配慮している。それを実現するために、(XmlReaderクラスの)Readメソッドがちょっと変に見える位置に記述されているわけである。なお、最初のノードは、(XmlReaderクラスの)Readメソッドを呼び出さないと読み込まれないので、ループの開始前に1回だけ呼び出している。

 読み取り後にreaderが終了タグの次のノードを指し示すというReadElementStringメソッドの挙動は、「開始タグ+テキスト+終了タグ」というシーケンスが繰り返し出てくる場合に便利である。こういうシーケンスが2回繰り返されている場合、ReadElementStringメソッドを2回連続して実行すると、それだけで情報が読み取れるのである。そのようなテクニックを使ってPersonクラスのReadメソッドを書き換えたのが以下の例である。

  Public Sub Read(ByVal reader As XmlReader)
    reader.MoveToContent()
    reader.MoveToAttribute("id")
    ID = reader.Value
    reader.ReadStartElement("person", ns)
    Name = reader.ReadElementString("name", ns)
    Age = Integer.Parse(reader.ReadElementString("age", ns))
  End Sub
簡略化したReadメソッド(VB.NET版)
簡略化したReadメソッド(C#版)

 これを見ると、非常にコンパクトになったと驚くかもしれないが、元のReadメソッドと完全に等価の機能を持ったメソッドというわけではない。前の例は、どんなXML文書を読み込んだ場合でも必要な情報だけを処理して、不明の情報は処理しないという構造になっている。それに対して、この例は、すべての要素と属性は意図した通りの順番に記述されていて、関係ない要素などは含まれないことが前提となっている。

 さて、ここで使われているメソッドについても簡単に説明しておこう。MoveToContentメソッドは、現在のノードが内容となるノードであるかどうか確認し、そうでないならそのようなノードが出現するまで読み込む機能を持つ。ここではXML宣言や空白、コメントなどを読み捨てて、最初の要素の開始のノードまで進めるために記述している。次のMoveToAttributeメソッドは、指定した名前の属性までノードを進める機能を持つ。そして、ReadStartElementメソッドは指定した要素の開始を読み込む機能を持つ。これにより、ノードはperson要素の開始位置の次を示すようになる。

次回予告

 2回にわたってXmlReader/XmlWriterについて解説してきたが、これらを使うと単なるテキスト・データとして読み書きするよりもはるかに簡単にXML文書を扱えるようになる。しかし、これは.NET Frameworkのクラス・ライブラリでXML文書を読み書きする方法の1つに過ぎない。ほかにもやり方は存在する。次回は、最もメジャーなXML文書へのアクセス手段である。DOM(Document Object Model)について解説する予定である。End of Article


 INDEX
  .NETで簡単XML
  第3回 XML文書を読み書きするプログラムの作成
    1.XML文書を読み込む
    2.XML文書を読み込むサンプル・プログラム
    3.文書の妥当性を検証するXmlValidatingReaderクラス
    4.XML文書を読み書きするサンプル
  5.XML文書を読み書きするサンプルの解説
  
インデックス・ページヘ  「連載 :.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 記事ランキング

本日 月間