連載

.NETで簡単XML

第4回 DOM(Document Object Model)

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

文字列からDOMツリーへの読み込み

 XML文書は、ファイルから読み込むだけではない。通信機能で受信したり、データベースからXML文書そのものの文字列を取り出す場合もある。これらのような場合には、ファイルに書き出してからDOMツリーに読み込むのではなく、直接文字列からDOMツリーを構築させることができる。以下はそれを示す簡単なサンプル・プログラムである。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim document As New XmlDocument()
  document.LoadXml("<message>Hello!</message>")
  Trace.WriteLine(document.DocumentElement.InnerText)
End Sub
文字列からXML文書を読み込むサンプル(VB.NET版)
文字列からXML文書を読み込むサンプル(C#版)

 これを実行すると、出力ウィンドウに“Hello!”と表示する。

 このサンプル・プログラムのポイントは、Loadメソッドの代わりに使用されているLoadXmlメソッドである。これは引数の文字列をXML文書そのものと見なして、DOMツリーを構築してくれる。

データの書き換え

 ここまでの説明で、DOMを用いたXML文書の作成と読み込みは実現できた。だが、これで終わりではない。XmlReader/XmlWriterには、純粋に読み書きの機能しか存在しないので、作成と読み込みができればそれで終わりである。しかしDOMはすでに作成済みのDOMツリーをさらに加工していく作業が可能である。そのため、既存のノードを削除する、あるいは置き換える機能も用意されている。以下はそれを使用した例である。

1: Private Sub removeComment(ByVal parent As XmlNode)
2:   Dim node As XmlNode = parent.FirstChild
3:   Do
4:     If node Is Nothing Then Exit Do
5:     Dim nextNode As XmlNode = node.NextSibling
6:     If node.NodeType = XmlNodeType.Comment Then
7:       parent.RemoveChild(node)
8:     Else
9:       removeComment(node)
10:     End If
11:     node = nextNode
12:   Loop
13: End Sub
14:
15: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
16:   Const xmlns As String = "http://www.atmarkit.co.jp/xmlns/sample/person"
17:   Dim document As New XmlDocument()
18:
19:   document.Load("c:\sample.xml")
20:
21:   removeComment(document)
22:
23:   Dim ageList As XmlNodeList = document.GetElementsByTagName("age", xmlns)
24:   Dim ageNode As XmlNode
25:   For Each ageNode In ageList
26:     ageNode.InnerText = (Integer.Parse(ageNode.InnerText) + 1).ToString()
27:   Next
28:
29:   Dim addressList As XmlNodeList = document.GetElementsByTagName("address", xmlns)
30:   Dim i As Integer
31:   For i = 0 To addressList.Count - 1
32:     Dim warnComment As XmlComment = document.CreateComment("住所情報は削除されました")
33:     addressList.Item(i).ParentNode.ReplaceChild(warnComment, addressList.Item(i))
34:   Next
35:
36:   document.Save("c:\sample2.xml")
37: End Sub
データを書き換えるサンプル(VB.NET版)
データを書き換えるサンプル(C#版)

 最初のサンプル・プログラムで作成したファイル(c:\sample.xml)が存在する状態でこれを実行すると、以下のような内容を持つc:\sample2.xmlファイルを作成する。

<?xml version="1.0" encoding="UTF-8"?>
<person:record id="0011" xmlns:person="http://www.atmarkit.co.jp/xmlns/sample/person">
  <person:name>山田一郎</person:name>
  <person:age>18</person:age>
  <!--住所情報は削除されました-->
</person:record>
XML文書のデータを書き換えるサンプルの出力

■XML文書のデータを書き換えるサンプルの内容

 さて、ここでは3つの作業を行っている。1つ目は、既存のXML文書ツリーの中からコメント・ノードをすべて探しだし、取り除く作業(1〜13行目、21行目)。2つ目は、person:age要素に含まれれる数値を1加算する作業(23〜27行目)。3つ目は、pserson:address要素をコメントに置き換える作業である(29〜34行目)。

 最初のコメント・ノードの探索と削除は、再帰呼び出しのテクニックを使って記述している。DOMツリーを巡回する場合には、再帰呼び出しはよく使われる手法である。ここでは、NodeTypeメソッドでノードの種類を識別し、指定された子ノードを削除するRemoveChildメソッドを用いて削除することでその機能を実現している。ここで注意すべきことは、データの集まりに順番にアクセスする処理を行っているとき、処理対象の項目を使用中に列挙対象の項目を削除すると意図しない動作をする可能性があることである。そのため、ここでは削除する前に、削除する対象のノードの次のノードをNextSiblingプロパティで取得するという方法を使っている。

 次のperson:age要素に含まれる数値を1加算する作業はそれほど難しくないだろう。要するにInnerTextプロパティの値を読んで、加工して、再びInnerTextプロパティに代入しているだけである。テキストを書き換えるだけなら難しいことはないということを示す例である。

 最後は、pserson:address要素をコメントに置き換える作業だが、これはReplaceChildメソッドを用いて、要素ノードをコメント・ノードに置き換える方法で実現している。この方法なら、ノードの種類が変わっても対応できるのである。しかし、削除するノードと追加するノードの数が異なる場合は使えない。その場合は、RemoveChildメソッドなどを用いて削除を行い、そのあとでInsertBeforeメソッドなどを使って追加する必要がある。

次回予告

 今回は、.NET FrameworkのDOMが持っているさまざまな機能を紹介した。しかし、これらはDOMのすべての機能というわけではない。興味のある方はもっと深く調べてみるとよいだろう。今回紹介しなかった機能の中には、非常に強力で有益なものもある。例えば、XPathと呼ばれる式を指定して、もっと高度にXML文書中の情報を取り出す方法が用意されている。これはXPathという別の言語を知らねば扱えない高度な機能だが、使いこなせば非常に便利である。次回はそれを紹介したいと考えている。End of Article


 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 記事ランキング

本日 月間