連載

.NETで簡単XML

第4回 DOM(Document Object Model)

株式会社ピーデー 川俣 晶
2003/05/08
Page1 Page2 Page3 Page4

DOMを用いたXML文書の読み込み

 さて、書き出しができたら、次は読み込みである。前のサンプル・プログラムで作成したXML文書を読み込むサンプル・プログラムを作成した。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Const xmlns As String = "http://www.atmarkit.co.jp/xmlns/sample/person"
  Dim document As New XmlDocument()

  document.Load("c:\sample.xml")
  Dim rootElement As XmlElement = document.DocumentElement

  Dim id As String = rootElement.GetAttribute("id")
  Trace.WriteLine(id)

  Dim comment1 As XmlComment = rootElement.FirstChild
  If Not comment1 Is Nothing Then
    Trace.WriteLine(comment1.Value)

    Dim nameElement As XmlElement = comment1.NextSibling
    If Not nameElement Is Nothing Then
      Dim nameText As XmlText = nameElement.FirstChild
      If Not nameText Is Nothing Then
        Trace.WriteLine(nameText.Value)
      End If
    End If
  End If

  Dim comment2 As XmlComment = rootElement.ChildNodes.Item(2)
  If Not comment2 Is Nothing Then
    Trace.WriteLine(comment2.Value)
  End If

  Dim ageList As XmlNodeList = rootElement.GetElementsByTagName("age", xmlns)
  If ageList.Count > 0 Then
    Dim ageElement As XmlElement = ageList.Item(0)
    Trace.WriteLine(ageElement.InnerText)
  End If

  Dim addressList As XmlNodeList = rootElement.GetElementsByTagName("address", xmlns)
  If addressList.Count > 0 Then
    Dim addressElement As XmlElement = addressList.Item(0)
    Trace.WriteLine(addressElement.InnerXml)
  End If
End Sub
DOMを用いてXML文書を読み込むサンプル(VB.NET版)
DOMを用いてXML文書を読み込むサンプル(C#版)

 これを実行すると出力ウィンドウに以下のように表示される。

0011
サンプルプログラムの出力
山田一郎
個人情報
17
<country:code xmlns:country="http://www.atmarkit.co.jp/xmlns/sample/country">jp
</country:code>東京都杉並区1-2-3 (実際には1行)
XML文書を読み込むサンプルの出力

■XML文書を読み込むプログラムの内容

 さて、内容を説明しよう。XmlDocumentクラスのインスタンス(文書オブジェクト)を作成するところまでは同じである。しかし、今回は、このオブジェクトに何かを追加するのではなく、外部からXML文書ファイルを読み込むのである。それには、Loadメソッドを使う(document.Load("c:\sample.xml"))。引数にはURLを指定するだけでよい。ほとんどの場合、単純にファイル名を指定すれば機能する(一部URLに使用できない文字を含むファイル名を渡すと受け付けられない場合がある)。

Dim rootElement As XmlElement = document.DocumentElement
 次は、文書要素(ルート要素)の取得である。それには、文書オブジェクトのDocumentElementプロパティを使用する。これはまったく難しいことではない。

Dim id As String = rootElement.GetAttribute("id")
Trace.WriteLine(id)

 続いて、属性の取得である。これには、いくつかの方法があるが、要素オブジェクトのGetAttributeメソッドを使用するのが最も簡単である。これは引数にローカル名や名前空間名を指定して、その属性の値を得るものである。ここでは、名前空間の情報は必要ないので、引数1つの最もシンプルなものを使用している。もし、指定した属性がなければ、長さゼロの文字列が返ってくる。

Dim comment1 As XmlComment = rootElement.FirstChild
If Not comment1 Is Nothing Then
  Trace.WriteLine(comment1.Value)

 今度は最初のコメントの取得である。これは、文書要素の最初の子ノードとなるが、最初の子ノードはFirstChildプロパティで取得することができる。この値が、Nothing(VB.NETの場合)またはnull(C#)の場合は、最初の子ノードは存在しないことを示す。

 FirstChildプロパティの型はXmlNodeクラスである。しかし、コメント・ノードはXmlCommentクラスである。すべてのノードはXmlNodeクラスを継承したクラスで表現されるので、XmlNodeクラスの型を通してやり取りすることができ、XmlCommentクラスのインスタンスも受け取ることが可能だ。なお、コメントの内容は、Valueプロパティで参照することができる。

  Dim nameElement As XmlElement = comment1.NextSibling
  If Not nameElement Is Nothing Then
    Dim nameText As XmlText = nameElement.FirstChild
    If Not nameText Is Nothing Then
      Trace.WriteLine(nameText.Value)
    End If
  End If
End If

 次は、person:name要素の内容の取得である。これは、上のコメント・ノードと同じく文書要素の子ノードであって、コメント・ノードの次に位置するものである。同じノードの子ノード同士の中で、あるノードの次にあるノードは、NextSiblingプロパティで取得することができる。これはFirstChildプロパティの親戚のようなプロパティといえる。もし、次のノードがなければ、Nothing(VB.NETの場合)またはnull(C#)を返す。

 これで要素ノードが得られるが、それだけではまだ不足である。要素の内容を得るには、さらに要素のオブジェクトにFirstChildプロパティを使用して、その子ノードにあるテキスト・ノードを取得しなければならない。そして、テキスト・ノードの内容となる文字列を参照するには、Valueプロパティを使用しなければならない。

Dim comment2 As XmlComment = rootElement.ChildNodes.Item(2)
If Not comment2 Is Nothing Then
  Trace.WriteLine(comment2.Value)
End If

 さて、ここまでに使ったのは、FirstChildプロパティとNextSiblingプロパティを使用し、前から順番にアクセスする方法であるが、もっと直接的に子ノードの何番目、と指定する方法もある。次に出てくるのはそれを使用した例である。ここでは2番目のコメント・ノードを取得しているが、その際、そのノードが2番目にあることを知っている前提で記述している。rootElement.ChildNodes.Item(2)という部分がそれである。ChildNodesプロパティは、すべての子ノードを持つXmlNodeListクラスのインスタンスを参照する。これのItemメソッドを使うことで、指定した順番の子ノードを直接取り出せる。ここでは2を指定することで、0から数えて2番目のノードを直接取り出している。

 ここで1つ疑問を持った読者もいると思う。ここまでは、あるノードの出現順番が子ノードの中で常に一定で、それがあらかじめ分かっているという前提のコードを紹介してきた。しかし、現実のXML文書は、コメントがあったりなかったり、省略可能な要素があったり、そう簡単に順番が決まらないものが多い。順番が分からない情報を簡単に取り出す方法はないだろうか。続く部分でその方法を使っている。

Dim ageList As XmlNodeList = rootElement.GetElementsByTagName("age", xmlns)
If ageList.Count > 0 Then
  Dim ageElement As XmlElement = ageList.Item(0)

 GetElementsByTagNameメソッドを用いて、指定タグ名の要素を、順番を指定することなく取得している。ここでGetElementsByTagNameメソッドの引数に指定されているものは、要素のローカル名と名前空間である。この要素は、指定した文書ノードまたは要素ノードの子孫の中から指定した名前を持つ要素を返す。返す値はXmlNodeListクラスのインスタンスである。これは、ノードの集合を含むクラスとなっているので、もし複数のノードが指定条件を満たした場合でも、そのすべてを知ることができる。XmlNodeListクラスでは、Countプロパティで含まれるノードの数を知ることができ、Itemメソッドで個々のノードの内容を知ることができる。

  Trace.WriteLine(ageElement.InnerText)
End If

 次に、InnerTextプロパティを値の取得に使用している例を記述してみた。要素ノードの内容のテキストを知るために、子ノードを取得する手順を飛ばして、InnerTextプロパティ1つで実現している。このような使い方も可能である。また、さらにそのあとには、同様にInnerXmlプロパティを使用した例(Trace.WriteLine(addressElement.InnerXml))も記述している。


 INDEX
  .NETで簡単XML
  第4回 DOM(Document Object Model)
    1.DOM(Document Object Model)とは何か?
    2.DOMを用いてXML文書を作成するプログラム
  3.DOMを用いてXML文書を読み込むプログラム
    4.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 記事ランキング

本日 月間