ステップ 7 ハンズオン : XML を利用したプログラミング形式の永続化
マイクロソフト株式会社 デベロッパーマーケティング本部
デベロッパーエバンジェリスト 辻郷 隆史
目標 | XML を利用したプログラミング形式の永続化 |
使用技術 |
|
取り上げるトピックス
|
|
前提知識 |
|
関連記事 |
|
プログラミング形式によるデータの永続化
System.Xml 名前空間内のXml 関連クラスを使用することにより、 XML を利用したプログラミング形式の永続化を行うことが可能です。
今回のサンプル アプリケーションでは、下記の 2種類のプログラミング形式の永続化と復元の実装を行います。
図 1. サンプル アプリケーション
- XmlTextReader / XmlTextWriter による永続化と復元
- XmlDocument による永続化と復元
プロジェクトの種類
|
プロジェクトテンプレート
|
プロジェクト名
|
---|---|---|
[Visual Basic プロジェクト] | [Windows アプリケーション] | ProgramToXmlApp |
ツールボックスから、 Button コントロールを 4 つ、フォーム上に配置し以下のようにプロパティを設定します。
図 2. アプリケーションのデザイン
コントロール ID
|
プロパティ名
|
設定値
|
---|---|---|
Button1 | Text | XmlTextWriter 永続化 |
Button2 | Text | XmlTextReader 復元 |
Button3 | Text | XmlDocument 永続化 |
Button4 | Text | XmlDocument 復元 |
永続化を行うデータとして 「 ステップ 7 ハンズオン : XML を利用したオブジェクトの永続化」にて使用した 2つのクラス ( Employee / Team )を作成します。
プロジェクトへ 1つ目のクラスを追加( Employee.vb )し、クラスを下記の通り実装します。
Imports System.Xml.Serialization
<XmlRoot(ElementName:="Emp")> _
Public Class Employee
<XmlElement(ElementName:="ID")> _
Public EmployeeID As Integer
Private mFullName As String
Private mBirthDate As DateTime
Public Property FullName() As String
Get
Return Me.mFullName
End Get
Set(ByVal Value As String)
Me.mFullName = Value
End Set
End Property
Public Sub New()
End Sub
Public Sub New(ByVal id As Integer, ByVal name As String, ByVal bDate As DateTime)
Me.EmployeeID = id
Me.mFullName = name
Me.mBirthDate = bDate
End Sub
End Class
プロジェクトへ 2つ目のクラスを追加( Team.vb )し、クラスを下記の通り実装します。
Imports System.Xml.Serialization
Public Class Team
GetType(Employee))> _
Public Employees As New ArrayList
End Class
フォーム( Form1.vb )のコードを表示し、先頭に名前空間のインポートを追加します。
Imports System.Xml
Public Class Form1
Inherits System.Windows.Forms.Form
…
Button1 / Click イベント ハンドラへ XmlTextWriter を使用した永続化処理を実装します。
Private Sub Button1_Click(…) Handles Button1.Click
Dim myTeam As New Team ' 永続化するオブジェクト
For i As Integer = 1 To 3 ' 永続化するオブジェクトへデータ設定
myTeam.Employees.Add(New Employee(i, "社員" + CStr(i), New DateTime(1970, 1, 1)))
Next
' XmlTextWriter を使用した永続化
Dim myWriter As New XmlTextWriter("ReadWriter.xml", System.Text.Encoding.UTF8)
myWriter.WriteStartDocument()
myWriter.WriteStartElement("Team") ' <Team>
For Each emp As Employee In myTeam.Employees
myWriter.WriteStartElement("Emp") ' <Emp>
myWriter.WriteElementString("ID", CStr(emp.EmployeeID)) ' <ID>x</ID>
myWriter.WriteElementString("FullName", emp.FullName) ' <FullName>xxxx</FullName>
myWriter.WriteEndElement() ' </Emp>
Next
myWriter.WriteEndElement() ' </Team>
myWriter.WriteEndDocument()
myWriter.Close()
End Sub
ここでは、 XmlTextWriter を使用し、ReadWriter.xml へ XML ドキュメントを永続化しています。
XmlTextWriter では、永続化する XML の形式を考慮し、順番にタグやデータなどの書き込みを行い、永続化を実施しています。
Button4 / Click イベント ハンドラへ XmlDocument を使用した復元処理を実装します。
Private Sub Button2_Click(…) Handles Button2.Click
Dim myTeam As Team ' 復元するオブジェクト
' XmlTextReader を使用した復元
Dim myReader As New XmlTextReader("ReadWriter.xml")
Dim objEmp As Employee ' Employee オブジェクト
Dim path As String ' カレントパス格納用
While myReader.Read() ' 次ノード(要素/属性/テキストなど)の読込
Select Case myReader.NodeType
Case XmlNodeType.Element ' 要素の開始
path &= "/" & myReader.Name ' パスへ要素名を追加
Select Case path
Case "/Team"
myTeam = New Team
Case "/Team/Emp"
objEmp = New Employee
End Select
Case XmlNodeType.EndElement ' 要素の終了
Select Case path
Case "/Team/Emp"
myTeam.Employees.Add(objEmp)
End Select
path = path.Substring(0, path.LastIndexOf("/")) ' パスから最下位要素を削除
Case XmlNodeType.Text ' テキスト(データ)
Select Case path
Case "/Team/Emp/ID"
objEmp.EmployeeID = CInt(myReader.Value) ' データ(ID) の取得
Case "/Team/Emp/FullName"
objEmp.FullName = myReader.Value ' データ(FullName)の取得
End Select
End Select
End While
myReader.Close()
' 復元したオブジェクトのデータ表示
Dim message As String
For Each emp As Employee In myTeam.Employees
message += String.Format("{0} / {1}", emp.EmployeeID, emp.FullName) + vbCrLf
Next
MessageBox.Show(message)
End Sub
ここでは、 XmlTextReader を使用し、ReadWriter.xml から XML ドキュメントを復元しています。
XmlTextReader では、順方向への読み込みが可能です。
今回は Read メソッドを使用し、ノード単位(要素/属性/テキストなど)での読み込みを行い、NodeType および Value プロパティより要素やテキストを特定し、復元を実施しています。
Button3 / Click イベント ハンドラへ XmlDocument を使用した永続化処理を実装します。
Private Sub Button3_Click(…) Handles Button3.Click
Dim myTeam As New Team ' 永続化するオブジェクト
For i As Integer = 1 To 3 ' 永続化するオブジェクトへデータ設定
myTeam.Employees.Add(New Employee(i, "社員" + CStr(i), New DateTime(1970, 1, 1)))
Next
' ==== XmlDocument の作成(Team オブジェクトのデータを設定) ====
Dim xmlDoc As New XmlDocument ' Xml ドキュメント オブジェクト
xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", Nothing)) ' XML 宣言の追加
Dim teamElement As XmlElement ' Team 要素
Dim empElement As XmlElement ' Emp 要素
Dim element As XmlElement ' 要素格納用(ID / FullName 作成時使用)
teamElement = xmlDoc.CreateElement("Team") ' Team 要素作成
xmlDoc.AppendChild(teamElement) ' Team 要素の追加
For Each emp As Employee In myTeam.Employees
empElement = xmlDoc.CreateElement("Emp") ' Emp 要素作成
teamElement.AppendChild(empElement) ' Team 要素へ Emp 要素の追加
element = xmlDoc.CreateElement("ID") ' ID 要素作成
element.InnerText = CStr(emp.EmployeeID) ' ID 要素内のテキスト設定
empElement.AppendChild(element) ' Emp 要素へ ID 要素の追加
element = xmlDoc.CreateElement("FullName") ' FullName 要素作成
element.InnerText = emp.FullName ' FullName 要素内のテキスト設定
empElement.AppendChild(element) ' Emp 要素へ FullName 要素の追加
Next
' ==== XmlDocument の永続化 ====
xmlDoc.Save("XmlDocument.xml")
End Sub
ここでは、 XmlDocument 関連の処理として、大きく分けて XmlDocument の作成と XmlDocument の永続化の 2つの処理を行っています。
【XmlDocument の作成】
始めにルート要素である Team 要素を作成後、その後 子 / 孫要素を作成および追加し、 XmlDocument を作成しています。
【XmlDocument の永続化】
Save メソッドを使用し、 作成済みの XmlDocumentを XmlDocument.xml ファイルへ永続化しています。
Button4 / Click イベント ハンドラへ XmlDocument を使用した復元処理を実装します。
Private Sub Button4_Click(…) Handles Button4.Click
Dim myTeam As New Team ' 復元するオブジェクト
Dim xmlDoc As New XmlDocument ' Xml ドキュメント オブジェクト
' ==== XmlDocument の復元 ====
xmlDoc.Load("XmlDocument.xml")
' ==== XmlDocument の参照(Team オブジェクトの作成) ====
Dim node As XmlNode ' ノード格納用(ID / FullName 参照時使用)
Dim objEmp As Employee ' Employee オブジェクト
For Each empNode As XmlNode In xmlDoc.SelectNodes("/Team/Emp") ' /Team/Emp ノード検索
objEmp = New Employee
node = empNode.SelectSingleNode("ID") ' /Team/Emp/ID ノード検索
objEmp.EmployeeID = CInt(node.InnerText) ' /Team/Emp/ID 内のテキスト(ID)取得
node = empNode.SelectSingleNode("FullName") ' /Team/Emp/FullName ノード検索
objEmp.FullName = node.InnerText ' /Team/Emp/ID 内のテキスト(FullName)取得
myTeam.Employees.Add(objEmp)
Next
' 復元したオブジェクトのデータ表示
Dim message As String
For Each emp As Employee In myTeam.Employees
message += String.Format("{0} / {1}", emp.EmployeeID, emp.FullName) + vbCrLf
Next
MessageBox.Show(message)
End Sub
ここでは、 XmlDocument 関連の処理として、大きく分けて XmlDocument の復元と XmlDocument の参照の 2つの処理を行っています。
【XmlDocument の復元】
Load メソッドを使用し XmlDocument.xml ファイルより XmlDocument を復元しています。
【XmlDocument の参照】
ノード(要素)を指定して XmlDocument を検索し、各テキストなどのデータを取得しています。
以上で、実装は完了です。では実際にビルドしてアプリケーションを動かしてみましょう。
アプリケーションにて各ボタンをクリックし、 Team オブジェクトをXML ドキュメントとして永続化および復元できることを確認します。
ま た、アプリケーションと同一フォルダ内に作成された XML ドキュメント ReadWriter.xml および XmlDocument.xml を Internet Explorer などで開き、 Team オブジェクトが XML ドキュメントとして永続化されていることを確認します。
まとめ
Xml 関連クラスを使用することにより、プログラミングによる永続化を行うことが可能です。
XmlSerializer クラスを使用したオブジェクトの永続化とは異なり、 XML の階層構造 / 要素 / テキスト(データ) などをプログラミングによる柔軟な制御を行うことが可能です。
今回ご紹介したプログラミング形式のそれぞれの特徴については下記の通りとなります。
形式
|
特徴
|
---|---|
XmlReader / XmlWriter |
|
XmlDocument |
|
上記の特徴を考慮し、単純にプログラミングによる永続化を行いたい場合は、 XmlReader / XmlWriter を使用し、 XmlDocument の特徴であるインメモリでの XML ドキュメント操作(ランダム アクセス / 柔軟なデータ編集)を行いたい場合のみ、 XmlDocument を使用するなど、用途に応じた使い分けを行うことが可能です。
このように .NET Framework では、 プログラミング形式によるデータの永続化を行うことが可能です。
参考資料
- .NET Framework 開発者ガイド / XML ドキュメント オブジェクト モデル (DOM)
- .NET Framework 開発者ガイド / XML シリアル化を制御する属性
- .NET Framework 開発者ガイド / 属性を使用した XML シリアル化の制御
ページのトップへ