ステップ 7 ハンズオン : XML を利用したオブジェクトの永続化

マイクロソフト株式会社 デベロッパーマーケティング本部
デベロッパーエバンジェリスト 辻郷 隆史

目標 XML を利用したオブジェクトの永続化
使用技術
  • System.Xml.Serialization
  • Visual Basic .NET / Windows フォーム
取り上げるトピックス
  • オブジェクトの永続化および復元方法
  • 属性を使用した XML シリアル化の制御方法
前提知識
関連記事

 

オブジェクト データの永続化

System.Xml.Serialization 名前空間内の XmlSerializer クラスを使用することにより、XML を利用したオブジェクトの永続化を行うことが可能です。
今回のサンプル アプリケーションでは、下記の 2 種類のオブジェクトの永続化と復元の実装を行います。

図 1. サンプル アプリケーション

  1. 単純なデータ型のメンバーを持つオブジェクトの永続化と復元
  2. ArrayList メンバーを持つオブジェクトの永続化と復元

Visual Studio .NET 2003 を起動して、以下の設定で新規にプロジェクトを作成します。

プロジェクトの種類
プロジェクトテンプレート
プロジェクト名
[Visual Basic プロジェクト] [Windows アプリケーション] ObjectToXmlApp

ツールボックスから、 Button コントロールを 4 つ、フォーム上に配置し以下のようにプロパティを設定します。

図 2. アプリケーションのデザイン

 

コントロール ID
プロパティ名
設定値
Button1 Text オブジェクト永続化
Button2 Text オブジェクト復元
Button3 Text オブジェクト永続化(ArrayList)
Button4 Text オブジェクト復元(ArrayList)

単純なデータ型のメンバーを持つクラスを作成します。
プロジェクトへクラスを追加( Employee.vb )し、クラスを下記の通り実装します。

Public Class Employee
    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

フォーム( Form1.vb )のコードを表示し、先頭に名前空間のインポートを追加します。

Imports System.IO
Imports System.Xml.Serialization

Public Class Form1
    Inherits System.Windows.Forms.Form
…

Button1 / Click イベント ハンドラへオブジェクトを永続化する処理を実装します。

ここでは、 XmlSerializer の Serialize メソッドを使用し、 Employee.xml へ XML ドキュメントを永続化しています。

Button2 / Click イベント ハンドラへオブジェクトを復元する処理を実装します。

Private Sub Button1_Click(…) Handles Button1.Click
    ' 永続化するオブジェクト
    Dim emp As New Employee(1, "舞黒 太郎", New DateTime(1970, 1, 1))

    ' XmlSerializer 作成(Employee)
    Dim mySerializer As New XmlSerializer(GetType(Employee))

    ' ファイルへ永続化するための StreamWriter 作成
    Dim myWriter As New StreamWriter("Employee.xml")

    ' Employee オブジェクトのシリアライズ
    mySerializer.Serialize(myWriter, emp)

    ' StreamWriter ストリームのクローズ
    myWriter.Close()
End Sub

ここでは、 XmlSerializer の Deserialize メソッドを使用し、 Employee.xml から XML ドキュメントを復元しています。

 

以上で、実装は完了です。では実際にビルドしてアプリケーションを動かしてみましょう。

アプリケーションにて 「 オブジェクト永続化 」 ボタンをクリックし、 Employee オブジェクトをXML ドキュメントとして永続化します。
アプリケーションと同一フォルダ内に作成された XML ドキュメント Employee.xml を Internet Explorer などで開き、 Employee オブジェクトが XML ドキュメントとして永続化されていることを確認します。

図 3. 永続化された XML ドキュメント

※XmlSerializer では、オブジェクトのパブリック プロパティとパブリック フィールドのシリアライズを行うため、 Employee クラスの mFullName / mBirthDate などのプライベート フィールドおよびメソッドなどはシリアライズされません。

「 オブジェクト復元 」 ボタンをクリックし、 XML ドキュメントが Employee オブジェクトへ復元され、メッセージ ボックスに Employee オブジェクトのデータが表示されることを確認します。

 

永続化を行う際の、要素名などについては、クラス名やメンバー名などがデフォルトで使用されます。
任意の要素名などを指定したい場合は、属性を使用することにより名前空間や要素名などを指定することが可能となります。

Employee クラス( Employee.vb ) のコードを表示後、下記の通り先頭へ名前空間のインポートを追加し、クラスやフィールドに対して属性を追加します。

Imports System.Xml.Serialization

<XmlRoot(ElementName:="Emp")> _
Public Class Employee
    <XmlElement(ElementName:="ID")> _
    Public EmployeeID As Integer
    Private mFullName As String
    …

ここでは、 XmlRoot 属性および XmlElement 属性を使用し、要素名を指定しています。

修正完了後、ビルドし実行します。

再度、アプリケーションにて 「 オブジェクト永続化 」 ボタンをクリックし、 Employee オブジェクトをXML ドキュメントとして永続化します。
XML ドキュメント Employee.xml を Internet Explorer などで開き、 属性にて指定した要素名が反映されていることを確認します。

図 4. 属性を指定した XML ドキュメント

 

ArrayList のメンバーを持つオブジェクトを作成します。
プロジェクトへクラスを追加( Team.vb )し、クラスを下記の通り実装します。

Imports System.Xml.Serialization

Public Class Team
    <XmlElement(ElementName:="Emp")> _
    Public Employees As New ArrayList
End Class

フォーム( Form1.vb )の Button3 / Click イベント ハンドラへオブジェクトを永続化する処理を実装します。

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

    ' XmlSerializer 作成(Team)
    Dim mySerializer As New XmlSerializer(GetType(Team))

    ' ファイルへ永続化するための StreamWriter 作成
    Dim myWriter As New StreamWriter("Team.xml")

    ' Team オブジェクトのシリアライズ
    mySerializer.Serialize(myWriter, myTeam)

    ' StreamWriter ストリームのクローズ
    myWriter.Close()
End Sub

Button4 / Click イベント ハンドラへオブジェクトを復元する処理を実装します。

Private Sub Button4_Click(…) Handles Button4.Click
    Dim myTeam As Team              ' 復元するオブジェクト

    ' XmlSerializer 作成(Team)
    Dim mySerializer As New XmlSerializer(GetType(Team))

    ' ファイルから復元するための StreamReader 作成
    Dim myReader As New StreamReader("Team.xml")

    ' Team オブジェクトの逆シリアライズ
    myTeam = CType(mySerializer.Deserialize(myReader), Team)

    ' StreamReader ストリームのクローズ
    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

 

アプリケーションを実行後、 「 オブジェクト永続化(ArrayList) 」 ボタンをクリックすると、下記のようなエラーダイアログが表示されます。

図 5. XML ドキュメント シリアライズ エラー

ArrayList をメンバーとしているクラスなどを XmlSerializer クラスを使用してシリアライズする場合は、属性を使用しオブジェクトの型を XmlSerializer に通知する必要があります。
オブジェクトの型を通知していない場合は、今回のようにエラーが発生します。

次のステップで属性を使用しオブジェクトの型を XmlSerializer に通知することにします。

 

Team クラス( Team.vb ) をコード エディタで表示後、下記の通り属性を追加します。

Imports System.Xml.Serialization

Public Class Team
    <XmlElement(ElementName:="Emp", Type:=GetType(Employee))> _
    Public Employees As New ArrayList
End Class

ここでは、 XmlElement 属性の Type プロパティへ Employee オブジェクトの型を設定することにより、 XmlSerializer にオブジェクトの型を通知しています。

修正完了後、ビルドし実行します。

再度、アプリケーションにて 「 オブジェクト永続化(ArrayList) 」 ボタンをクリックし、 Team オブジェクトをXML ドキュメントとして永続化できることを確認します。

【XmlSerializer 利用側でのオブジェクト型の通知】

XmlSerializer を利用している側で、オブジェクト型の通知を行うことも可能です。その場合は、下記の通り XmlSerializer 生成時のパラメータとしてオブジェクト型を指定します。

' XmlSerializer 作成(Team)
    Dim subType(0) As Type
    subType(0) = GetType(Employee)
    Dim mySerializer As New XmlSerializer(GetType(Team), subType)

 

まとめ

XmlSerializer クラスを使用することにより、オブジェクトの永続化を行うことが可能です。
また、 要素名などを指定する必要がある場合、およびオブジェクトへ型の通知を行う場合は、属性を使用しシリアル化の制御を行うことが可能です。

このように .NET Framework では、 XML を利用したオブジェクトデータの永続化を効率良く行うことが可能です。

参考資料

  • .NET Framework 開発者ガイド / XML シリアル化の概要
  • .NET Framework 開発者ガイド / XML シリアル化を制御する属性
  • .NET Framework 開発者ガイド / 属性を使用した XML シリアル化の制御

ページのトップへ