連載

.NETで簡単XML

第4回 DOM(Document Object Model)

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

DOMを用いたXML文書の作成

 それでは、まず、DOMを用いて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()

  Dim xmlDecl As XmlDeclaration = document.CreateXmlDeclaration("1.0", "UTF-8", Nothing)
  document.AppendChild(xmlDecl)

  Dim rootElement As XmlElement = document.CreateElement("person", "record", xmlns)
  document.AppendChild(rootElement)

  Dim idAttr As XmlAttribute = document.CreateAttribute("id")
  idAttr.Value = "0011"
  rootElement.Attributes.Append(idAttr)

  Dim nameElement As XmlElement = document.CreateElement("person", "name", xmlns)
  rootElement.AppendChild(nameElement)

  Dim nameText As XmlText = document.CreateTextNode("山田一郎")
  nameElement.AppendChild(nameText)

  Dim ageElement As XmlElement = document.CreateElement("person", "age", xmlns)
  rootElement.AppendChild(ageElement)
  ageElement.InnerText = "17"

  Dim addressElement As XmlElement = document.CreateElement("person", "address", xmlns)
  rootElement.AppendChild(addressElement)
  addressElement.InnerXml = "<country:code xmlns:country=" _
    & Chr(34) & "http://www.atmarkit.co.jp/xmlns/sample/country" & Chr(34) _
    & " >jp</country:code>東京都杉並区1-2-3"

  Dim comment1 As XmlComment = document.CreateComment("サンプルプログラムの出力")
  rootElement.InsertBefore(comment1, nameElement)

  Dim comment2 As XmlComment = document.CreateComment("個人情報")
  rootElement.InsertAfter(comment2, nameElement)

  document.Save("c:\sample.xml")
End Sub
DOMを用いてXML文書を作成するサンプル(VB.NET版)
DOMを用いてXML文書を作成するサンプル(C#版)

 このサンプル・プログラムを実行すると、c:\sample.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>17</person:age>
  <person:address>
    <country:code xmlns:country="http://www.atmarkit.co.jp/xmlns/sample/country">jp
</country:code>東京都杉並区1-2-3</person:address> (実際には1行)
</person:record>
サンプルを実行して作成されるXML文書

■XML文書を作成するプログラムの内容

 さてプログラムの内容を解説しよう。

Dim document As New XmlDocument()
 まず最初にXmlDocumentクラスのインスタンス(文書オブジェクト)を作成していることが分かるだろう。これが、1つのXML文書に対応するオブジェクトである。とはいえ、このオブジェクト内にXML文書に含まれるあらゆる情報が含まれるわけではない。これは、文書ノードと呼ばれるノード、つまり木構造の根になるオブジェクトであり、そこから枝が伸び、他のノードを表現するオブジェクトと接続されていくのである。

 さて、XmlDocumentクラスのインスタンスを作成しても、中身は空である。そこに、様々な情報を付け加えていかないと、必要なXML文書は得られない。以下は、情報を付け加える手順の説明である。

Dim xmlDecl As XmlDeclaration = document.CreateXmlDeclaration("1.0", "UTF-8", Nothing)
 まず最初に出てくるのが、XML宣言である。XML宣言はXmlDeclarationクラスで表現するが、XmlDeclarationクラスのインスタンスを直接作成したりはしない。その代わりに、文書オブジェクトのCreateXmlDeclarationメソッドを使用して作成する。このメソッドの引数には、XMLのバージョン、エンコード名、非依存文書宣言の3つの情報を付加する。XMLのバージョンは今のところ"1.0"以外ありえない。エンコード名は必要なものを指定する。

 非依存文書宣言は"yes"、"no"で指定するが、不用ならNothing(VB.NET)またはnull(C#)を指定することで生成させないこともできる。たいていは生成させないという選択で済むだろう。

document.AppendChild(xmlDecl)
 次のポイントは、CreateXmlDeclarationメソッドで作成したインスタンスを、文書オブジェクトのAppendChildメソッドで追加している個所である。

 当然、XML宣言オブジェクトを作成したところで、それだけでは何の意味もない。XML文書の一部に含めるためには、それが木構造の一部であることを教えてやらねばならない。そのためには、具体的に、木構造のどこに入れるかを明示しなければならない。AppendChildメソッドは、そのノードの子ノード、つまり枝として伸びるノードの最後に指定ノードを追加する機能を持つ。文書オブジェクトにはどんな枝もまだないので、これによってXML宣言は、文書オブジェクトの最初で唯一の子ノードになる。

 XML宣言はXML文書の先頭になければならないので、文書オブジェクトの子ノードの最初の1個という位置以外には置くことができないことに注意が必要である。

Dim rootElement As XmlElement = document.CreateElement("person", "record", xmlns)
document.AppendChild(rootElement)

 さて、次に行こう。次は、文書に必要不可欠な文書要素(ルート要素)の作成である。XML文書は少なくとも1つの要素を持たねばならないので、これは必須となるものである。それには、文書オブジェクトのCreateElementメソッドを用いて、XmlElementクラスのインスタンスを作成している。このメソッドには、引数の数によっていくつかのバリエーションがある。ここで使用しているのは、名前空間接頭辞、ローカル名、名前空間URIの3つの文字列を渡すものである。

 そして、作成されたインスタンスは、そのままXML宣言と同じく、文書オブジェクトのAppendChildメソッドで追加している。この要素オブジェクトは、子ノードとして追加されるので、文書オブジェクトの子ノードは2個に増える。順番は、必ず、最初にXML宣言オブジェクトであり、次が要素オブジェクトとなる。

Dim idAttr As XmlAttribute = document.CreateAttribute("id")
idAttr.Value = "0011"
rootElement.Attributes.Append(idAttr)

 次は属性を追加する例である。属性は文書オブジェクトのCreateAttributeメソッドで作成する。この属性には名前空間を付けないので、名前空間の指定を含まない引数1つのものを使っている。これにより、XmlAttributeクラスのインスタンスを作成している。しかし、これをここまでの例と同じように文書オブジェクトにAppendChildメソッドで追加してはならない。なぜなら、属性は、文書に付くものではなく、要素に付くものだからである。

 ここでは、rootElement.Attributes.Append(idAttr)というように、要素のAttributes属性を呼び出し、さらに、それに対してAppendメソッドを呼び出して属性を追加している。属性には順番がないので、順番を意識する必要はない。

Dim nameElement As XmlElement = document.CreateElement("person", "name", xmlns)
rootElement.AppendChild(nameElement)

 次は、person:name要素の追加である。これは、person:record要素の子要素としたいので、文書オブジェクトにAppendChildメソッドで追加してはならない。そのかわり、親要素となるオブジェクトのAppendChildメソッドで追加する。

Dim nameText As XmlText = document.CreateTextNode("山田一郎")
nameElement.AppendChild(nameText)

 続いて、person:name要素の内容となるテキストの追加である。要するに単なる文字列であるが、DOMではそれも1つのノードとして表現されるので、XmlTextクラスのインスタンスを作成する必要がある。そのためには、文書オブジェクトのCreateTextNodeメソッドを使用する。引数はテキスト・ノードに含める文字列である。これを、person:name要素のオブジェクトにAppendChildメソッドで追加する。

Dim ageElement As XmlElement = document.CreateElement("person", "age", xmlns)
rootElement.AppendChild(ageElement)
ageElement.InnerText = "17"

 今度はperson:age要素の追加である。これは、person:name要素と同じ方法でやってもよいのだが、別の方法を使ってみた。テキスト・ノードを作成してAppendChildメソッドで追加する代わりに、InnerTextプロパティを使用している。要素のノードに対して、InnerTextプロパティを使用すると、その内容となるテキストを読み書きすることができる。この例のように、文字列を代入すると自動的に要素の内容に文字列が設定される。よく使われる操作を短い手間で完了するためのサービス的な機能といえる。

Dim addressElement As XmlElement = document.CreateElement("person", "address", xmlns)
rootElement.AppendChild(addressElement)
addressElement.InnerXml = "<country:code xmlns:country=" _
  & Chr(34) & "http://www.atmarkit.co.jp/xmlns/sample/country" & Chr(34) _
  & " >jp</country:code>東京都杉並区1-2-3"

 次は、person:address要素だが、ここではまた別の方法を使っている。InnerTextプロパティと似たものに、InnerXmlプロパティがある。これは、要素の内容を文字列として読み書きすることは同じだが、単なるテキストではなく、XML文書の一部を文字列表記したものを扱う。つまり、この例のように、開始タグや終了タグを書いた文字列を代入すると、それがXML文書の一部として解釈され、取り込まれるわけである。すでにXML文書の形式になっている文字列をDOMで扱うときに便利である。

 なお、InnerXmlプロパティには、それぞれ似た機能を持つものとして、OuterXmlプロパティが存在する。こちらの方は内容ではなく、そのノードを含む全体を表現する文字列を扱う点で異なる。つまり、この場合なら、person:address要素の開始タグと終了タグを含む文字列を扱うということである。また、OuterXmlプロパティは値の取得のみで設定ができない点でもInnerXmlプロパティと異なっている。

Dim comment1 As XmlComment = document.CreateComment("サンプルプログラムの出力")
rootElement.InsertBefore(comment1, nameElement)
Dim comment2 As XmlComment = document.CreateComment("個人情報")
rootElement.InsertAfter(comment2, nameElement)

 次は、コメントを2つ追加している。ここまでは行儀よく順番にノードを追加してきたが、この2つのコメントは、その順番と無関係に追加を行っている。

 第1のコメントは、InsertBeforeメソッドを用いてXML文書に挿入している。これは、指定されたノードの手前に新しいノードを挿入する機能を持つ。ここでは、person:name要素の手前に、コメントを挿入するように記述している。

 第2のコメントは、InsertAfterメソッドを使用して挿入している。このメソッドはInsertBeforeメソッドとは逆に、指定ノードの後ろに新しいノードを挿入する機能を持つ。これらのメソッドを活用すれば、XML文書に記述される順番とは無関係に、ノードを挿入していくことができるわけである。

document.Save("c:\sample.xml")
 そして最後は、文書オブジェクトのSaveメソッドである。これにより、指定ファイル名に作成したXML文書ツリーをXML文書として保存することができる。もし、Saveメソッドを呼ばないで終了すると、どこにもXML文書は残らないまま終わることになる。


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

本日 月間