DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

Object配列やArrayListをXMLシリアル化する

注意:ここではXmlSerializerクラスを使った方法を紹介します。DataContractSerializerクラスを使った方法は、「DataContractSerializerを使って、Object配列やArrayListをXMLシリアル化する」で説明しています。

オブジェクトの内容をファイルに保存、復元する」で説明した方法でObject型の配列やArrayListオブジェクトなどをシリアル化すると、例外InvalidOperationException(XML ドキュメントを生成中にエラーが発生しました)がスローされる場合があります。例えば、次のようなケースです。

VB.NET
コードを隠すコードを選択
Public Class SampleItem
    Public Number As Integer
    Public Message As String

    Public Sub New()
        Number = 0
        Message = ""
    End Sub

    Public Sub New(ByVal num As Integer, ByVal msg As String)
        Number = num
        Message = msg
    End Sub
End Class

Public Class MainClass
    'エントリポイント
    Public Shared Sub Main()
        'XMLシリアル化するArrayList
        Dim al As New System.Collections.ArrayList()
        al.Add(New SampleItem(12, "こんにちは"))

        'XMLファイルに保存する
        Dim serializer As New System.Xml.Serialization.XmlSerializer( _
            GetType(System.Collections.ArrayList))
        Dim fs As New System.IO.FileStream("C:\test\sample.xml", _
                                           System.IO.FileMode.Create)
        'エラーが発生する
        serializer.Serialize(fs, al)
        '閉じる
        fs.Close()
    End Sub
End Class
C#
コードを隠すコードを選択
public class SampleItem
{
    public int Number;
    public string Message;

    public SampleItem()
    {
        Number = 0;
        Message = "";
    }
    public SampleItem(int num, string msg)
    {
        Number = num;
        Message = msg;
    }
}

public class MainClass
{
    //エントリポイント
    public static void Main()
    {
        //XMLシリアル化するArrayList
        System.Collections.ArrayList al = new System.Collections.ArrayList();
        al.Add(new SampleItem(12, "こんにちは"));

        //XMLファイルに保存する
        System.Xml.Serialization.XmlSerializer serializer =
            new System.Xml.Serialization.XmlSerializer(
                typeof(System.Collections.ArrayList));
        System.IO.FileStream fs =
            new System.IO.FileStream(@"C:\test\sample.xml",
                System.IO.FileMode.Create);
        //エラーが発生する
        serializer.Serialize(fs, al);
        //閉じる
        fs.Close();
    }
}

ここでは、これを解決する方法を幾つか紹介します。

XmlSerializerコンストラクタに型を指定する方法

まずは、XmlSerializerのコンストラクタでArrayListに追加される可能性のあるすべてのオブジェクトの型を通知する方法を紹介します。例えば上記の例では、SampleItemクラス型を通知します。復元する時も同様に型を通知する必要があります。

この方法を使って上記の例を修正すると次のようになります。(SampleItemクラスは前と同じですので、省略します。)

VB.NET
コードを隠すコードを選択
Public Class MainClass
    'エントリポイント
    Public Shared Sub Main()
        'XMLシリアル化するArrayList
        Dim al As New System.Collections.ArrayList()
        al.Add(New SampleItem(12, "こんにちは"))

        'ArrayListに追加されているオブジェクトの型の配列を作成
        Dim et As Type() = New Type() {GetType(SampleItem)}

        'ArrayListに追加されているオブジェクトを指定してXMLファイルに保存する
        Dim serializer As New System.Xml.Serialization.XmlSerializer( _
            GetType(System.Collections.ArrayList), et)
        Dim fs As New System.IO.FileStream("C:\test\sample.xml", _
                                           System.IO.FileMode.Create)
        serializer.Serialize(fs, al)
        '閉じる
        fs.Close()
    End Sub
End Class
C#
コードを隠すコードを選択
public class MainClass
{
    //エントリポイント
    public static void Main()
    {
        //XMLシリアル化するArrayList
        System.Collections.ArrayList al = new System.Collections.ArrayList();
        al.Add(new SampleItem(12, "こんにちは"));

        //ArrayListに追加されているオブジェクトの型の配列を作成
        Type[] et = new Type[] { typeof(SampleItem) };

        //ArrayListに追加されているオブジェクトを指定してXMLファイルに保存する
        System.Xml.Serialization.XmlSerializer serializer =
            new System.Xml.Serialization.XmlSerializer(
                typeof(System.Collections.ArrayList), et);
        System.IO.FileStream fs =
            new System.IO.FileStream(@"C:\test\sample.xml",
                System.IO.FileMode.Create);
        serializer.Serialize(fs, al);
        //閉じる
        fs.Close();
    }
}

書き込まれたXMLファイルの内容は次のようになります。

XmlArrayItemAttributeを使用する方法

Object型の配列やArrayListがクラスのメンバで、そのクラスのインスタンスをシリアル化する場合は、そのメンバにXmlArrayItemAttribute属性を適用する方法があります。この方法はシリアル化するクラスに手を加えるだけで、あとは「オブジェクトの内容をファイルに保存、復元する」方法とまったく同じやり方でシリアル化できます。

以下に、ArrayListをメンバに持つSampleClassクラスのインスタンスをシリアル化する例を示します。

VB.NET
コードを隠すコードを選択
Public Class SampleItem
    Public Number As Integer
    Public Message As String

    Public Sub New()
        Number = 0
        Message = ""
    End Sub
    Public Sub New(ByVal num As Integer, ByVal msg As String)
        Number = num
        Message = msg
    End Sub
End Class

'シリアル化するクラス
Public Class SampleClass
    'ArrayListに追加される型を指定する
    <System.Xml.Serialization.XmlArrayItem(GetType(SampleItem))> _
    Public Items As System.Collections.ArrayList

    Public Sub New()
        Items = New System.Collections.ArrayList()
        Items.Add(New SampleItem(12, "こんにちは"))
    End Sub
End Class

Public Class MainClass
    'エントリポイント
    Public Shared Sub Main()
        'XMLシリアル化するオブジェクト
        Dim obj As New SampleClass()

        'ArrayListに追加されているオブジェクトを指定してXMLファイルに保存する
        Dim serializer As New System.Xml.Serialization.XmlSerializer( _
            GetType(SampleClass))
        Dim fs As New System.IO.FileStream("C:\test\sample.xml", _
                                           System.IO.FileMode.Create)
        serializer.Serialize(fs, obj)
        fs.Close()
    End Sub
End Class
C#
コードを隠すコードを選択
public class SampleItem
{
    public int Number;
    public string Message;

    public SampleItem()
    {
        Number = 0;
        Message = "";
    }
    public SampleItem(int num, string msg)
    {
        Number = num;
        Message = msg;
    }
}

//シリアル化するクラス
public class SampleClass
{
    //ArrayListに追加される型を指定する
    [System.Xml.Serialization.XmlArrayItem(typeof(SampleItem))]
    public System.Collections.ArrayList Items;

    public SampleClass()
    {
        Items = new System.Collections.ArrayList();
        Items.Add(new SampleItem(12, "こんにちは"));
    }
}

public class MainClass
{
    //エントリポイント
    public static void Main()
    {
        //XMLシリアル化するオブジェクト
        SampleClass obj = new SampleClass();

        //ArrayListに追加されているオブジェクトを指定してXMLファイルに保存する
        System.Xml.Serialization.XmlSerializer serializer =
            new System.Xml.Serialization.XmlSerializer(typeof(SampleClass));
        System.IO.FileStream fs =
            new System.IO.FileStream(@"C:\test\sample.xml",
                System.IO.FileMode.Create);
        serializer.Serialize(fs, obj);
        fs.Close();
    }
}

このコードによって書き込まれたXMLファイルの内容は次のようになります。

  • 履歴:
  • 2012/3/2 サンプルを分かりやすいように書き直すなど。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。