C#でXmlSerializerを使ったコード例10選!初心者もすぐにマスター

C#のXmlSerializerクラスを使った具体的なサンプルコード集C#
この記事は約22分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミングでは、データのやり取りが日常茶飯事です。

特に、C#言語を使ってアプリケーションを開発する際、データを効率的に扱うことが重要となります。

ここで役立つのが、C#におけるXmlSerializerクラスです。

この記事では、XmlSerializerクラスの基本から応用までを、初心者にも理解しやすいように丁寧に解説します。

サンプルコードを交えながら、実際にどのようにデータをXML形式で保存し、また読み込むかを学んでいきましょう。

●XmlSerializerクラスとは

C#言語におけるXmlSerializerクラスは、オブジェクトをXML形式に変換し、またその逆の変換を行うための強力なツールです。

XMLは「eXtensible Markup Language」の略で、データを構造化して保存するための汎用的なフォーマットです。

XmlSerializerクラスを使用することで、C#のオブジェクトをXML形式で簡単に保存し、後からそのデータを再構築することが可能になります。

これはデータの永続化や、異なるシステム間でのデータのやり取りに非常に役立ちます。

○XmlSerializerクラスの基本概要

XmlSerializerクラスの基本的な使い方は、オブジェクトをXMLに変換(シリアライズ)、およびXMLをオブジェクトに変換(デシリアライズ)することです。

シリアライズはオブジェクトの状態を保存するプロセスで、デシリアライズは保存された状態からオブジェクトを再構築するプロセスです。

C#においては、このプロセスを非常に簡単に行うことができ、複雑なコードを書く必要がありません。

○XmlSerializerの利点と使い方

XmlSerializerクラスを使用する最大の利点は、その柔軟性と汎用性にあります。

XMLはテキストベースのフォーマットであるため、人間にも読みやすく、さまざまなシステムやプラットフォーム間で容易にデータを共有することができます。

また、XmlSerializerはカスタムクラスに対しても使用でき、プロパティやフィールドをXML要素や属性にマッピングすることが可能です。

これにより、複雑なデータ構造も簡単にXML形式で表現することができます。

●XmlSerializerの基本的な使い方

C#におけるXmlSerializerの使用は、オブジェクトのXMLへのシリアライズと、XMLからオブジェクトへのデシリアライズの二つのプロセスに分けられます。

シリアライズはオブジェクトの状態をXML形式でファイルやストリームに保存することを指し、デシリアライズはその逆のプロセス、つまりXML形式のデータからオブジェクトを再構築することを指します。

これらのプロセスは、データの永続化や異なるシステム間でのデータ交換において重要な役割を果たします。

○サンプルコード1:オブジェクトのシリアライズ

まずは、単純なオブジェクトをXML形式にシリアライズする基本的な方法を見てみましょう。

下記のサンプルコードでは、Personクラスのインスタンスを作成し、それをXMLファイルにシリアライズしています。

using System;
using System.IO;
using System.Xml.Serialization;

// サンプルのPersonクラス
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        Person person = new Person() { Name = "山田太郎", Age = 30 };

        XmlSerializer serializer = new XmlSerializer(typeof(Person));
        using (StreamWriter writer = new StreamWriter("person.xml"))
        {
            serializer.Serialize(writer, person);
        }

        Console.WriteLine("オブジェクトをXMLにシリアライズしました。");
    }
}

このコードでは、Personクラスのインスタンスを作成し、XmlSerializerを使用してStreamWriterを通じてファイルに書き込んでいます。

結果として、person.xmlファイルにはPersonオブジェクトのXML表現が保存されます。

○サンプルコード2:XMLファイルのデシリアライズ

次に、XMLファイルからオブジェクトをデシリアライズする方法を見てみましょう。

下記のサンプルコードでは、先ほどシリアライズしたperson.xmlファイルからPersonオブジェクトを再構築しています。

using System;
using System.IO;
using System.Xml.Serialization;

// サンプルのPersonクラス
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Person));
        using (StreamReader reader = new StreamReader("person.xml"))
        {
            Person person = (Person)serializer.Deserialize(reader);
            Console.WriteLine($"読み込んだオブジェクト: 名前={person.Name}, 年齢={person.Age}");
        }
    }
}

このコードでは、XmlSerializerを使用してStreamReaderからXMLデータを読み込み、それをPerson型のオブジェクトに変換しています。

このプロセスにより、XMLデータからオブジェクトの状態を復元することができます。

●XmlSerializerを使った応用例

C#のXmlSerializerクラスは基本的なシリアライズやデシリアライズの他に、より複雑なデータ構造や様々なシナリオにも対応可能です。

リストや配列の扱い、カスタムクラスのシリアライズ、さらには継承を使ったシリアライズなど、さまざまな応用が考えられます。

これにより、C#でのデータ処理の幅が大きく広がります。

○サンプルコード3:リストのシリアライズ

リストのシリアライズは、複数のオブジェクトを一つのXMLファイルに保存する際に有用です。

下記のサンプルコードでは、PersonオブジェクトのリストをXMLファイルにシリアライズしています。

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

// サンプルのPersonクラス
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        List<Person> people = new List<Person>
        {
            new Person() { Name = "山田太郎", Age = 30 },
            new Person() { Name = "佐藤花子", Age = 25 }
        };

        XmlSerializer serializer = new XmlSerializer(typeof(List<Person>));
        using (StreamWriter writer = new StreamWriter("people.xml"))
        {
            serializer.Serialize(writer, people);
        }

        Console.WriteLine("リストをXMLにシリアライズしました。");
    }
}

このコードでは、List<Person>型のオブジェクトを作成し、それをXmlSerializerを使ってXMLにシリアライズしています。

これにより、複数のPersonオブジェクトが一つのXMLファイルにまとめて保存されます。

○サンプルコード4:複雑なオブジェクトのシリアライズ

複雑なオブジェクト構造を持つクラスのシリアライズも、XmlSerializerで可能です。

下記のサンプルコードでは、異なる型のプロパティを持つEmployeeクラスをシリアライズしています。

using System;
using System.IO;
using System.Xml.Serialization;

// サンプルのAddressクラス
public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

// サンプルのEmployeeクラス
public class Employee
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Address Address { get; set; }
}

class Program
{
    static void Main()
    {
        Employee employee = new Employee()
        {
            Name = "鈴木一郎",
            Age = 40,
            Address = new Address() { Street = "桜通り1-2-3", City = "東京" }
        };

        XmlSerializer serializer = new XmlSerializer(typeof(Employee));
        using (StreamWriter writer = new StreamWriter("employee.xml"))
        {
            serializer.Serialize(writer, employee);
        }

        Console.WriteLine("複雑なオブジェクトをXMLにシリアライズしました。");
    }
}

この例では、EmployeeクラスにAddress型のプロパティが含まれています。

XmlSerializerはこのような複雑なオブジェクト構造も適切に扱い、それをXML形式で表現することができます。

この機能を利用することで、より複雑なデータ構造も効率的に扱うことが可能になります。

○サンプルコード5:カスタム属性を使用したシリアライズ

XmlSerializerを使用する際、特定の属性を使ってシリアライズの挙動をカスタマイズすることができます。

例えば、特定のプロパティをXMLに含めないようにする、またはXMLの要素名を変更するなどのカスタマイズが可能です。

下記のサンプルコードでは、XmlIgnore属性とXmlElement属性を使用しています。

using System;
using System.IO;
using System.Xml.Serialization;

public class Book
{
    [XmlElement("Title")]
    public string Name { get; set; }

    [XmlIgnore]
    public int PageCount { get; set; }

    public string Author { get; set; }
}

class Program
{
    static void Main()
    {
        Book book = new Book()
        {
            Name = "プログラミング入門",
            PageCount = 300,
            Author = "山田太郎"
        };

        XmlSerializer serializer = new XmlSerializer(typeof(Book));
        using (StreamWriter writer = new StreamWriter("book.xml"))
        {
            serializer.Serialize(writer, book);
        }

        Console.WriteLine("カスタム属性を使用したシリアライズが完了しました。");
    }
}

この例では、BookクラスのNameプロパティがXMLのTitle要素としてシリアライズされ、PageCountプロパティはXMLに含まれません。

このように属性を使用することで、シリアライズのプロセスを細かく制御することが可能です。

○サンプルコード6:エラーハンドリングの実装

シリアライズやデシリアライズのプロセス中にエラーが発生する可能性もあります。

例えば、不正なXML形式のデータを読み込もうとした場合などです。

このようなエラーを適切にハンドリングすることが重要です。

下記のサンプルコードでは、エラーハンドリングの実装方法を表しています。

using System;
using System.IO;
using System.Xml.Serialization;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Person));
            using (StreamReader reader = new StreamReader("invalid.xml"))
            {
                Person person = (Person)serializer.Deserialize(reader);
            }
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine("デシリアライズ中にエラーが発生しました。");
            Console.WriteLine(ex.Message);
        }
    }
}

このコードでは、無効なXMLデータを読み込むことで意図的に例外を発生させ、catchブロックでそれを捕捉しています。

エラーメッセージを表示することで、何が原因でエラーが発生したのかをユーザーに通知することができます。

このように例外処理を適切に行うことで、プログラムの安定性を高めることができます。

●XmlSerializerの高度なカスタマイズ

XmlSerializerを使ったシリアライズでは、さまざまな高度なカスタマイズが可能です。

これには、名前空間の定義やフォーマットの変更などが含まれ、より複雑なXMLドキュメントの生成が可能となります。

これらのカスタマイズを行うことで、XMLの構造をより細かく制御し、特定の要件に合わせたデータ表現を実現できます。

○サンプルコード7:名前空間のカスタマイズ

XMLにおいて名前空間は、要素や属性の名前の衝突を避けるために使用されます。

XmlSerializerを使ってXMLを生成する際にも、名前空間をカスタマイズすることができます。

下記のサンプルコードでは、カスタム名前空間を指定しています。

using System;
using System.IO;
using System.Xml.Serialization;

public class Report
{
    public string Title { get; set; }
    public string Content { get; set; }
}

class Program
{
    static void Main()
    {
        Report report = new Report()
        {
            Title = "月次報告",
            Content = "内容の概要"
        };

        XmlSerializer serializer = new XmlSerializer(typeof(Report));
        XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
        namespaces.Add("ns", "http://www.example.com/report");

        using (StreamWriter writer = new StreamWriter("report.xml"))
        {
            serializer.Serialize(writer, report, namespaces);
        }

        Console.WriteLine("カスタム名前空間を使用したシリアライズが完了しました。");
    }
}

このコードでは、XmlSerializerNamespacesを用いて名前空間を定義し、Serializeメソッドの引数として渡しています。

この結果、生成されるXMLファイルには指定した名前空間が適用されます。

○サンプルコード8:フォーマットのカスタマイズ

XmlSerializerを使用する際には、XMLのフォーマットもカスタマイズすることができます。

例えば、インデントの有無や改行のスタイルなどを変更することが可能です。

下記のサンプルコードでは、XMLのフォーマットを整える方法を表しています。

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

public class Product
{
    public string Name { get; set; }
    public double Price { get; set; }
}

class Program
{
    static void Main()
    {
        Product product = new Product()
        {
            Name = "コーヒーマグ",
            Price = 1200
        };

        XmlSerializer serializer = new XmlSerializer(typeof(Product));
        XmlWriterSettings settings = new XmlWriterSettings
        {
            Indent = true,
            NewLineOnAttributes = true,
            Encoding = Encoding.UTF8
        };

        using (XmlWriter writer = XmlWriter.Create("product.xml", settings))
        {
            serializer.Serialize(writer, product);
        }

        Console.WriteLine("フォーマットをカスタマイズしたシリアライズが完了しました。");
    }
}

このコードでは、XmlWriterSettingsを用いてXMLのフォーマットを指定し、XmlWriterを通じてシリアライズしています。

この方法を用いることで、読みやすい整形されたXMLファイルを生成することが可能です。

○サンプルコード9:パフォーマンスの最適化

XmlSerializerの使用において、パフォーマンスは重要な考慮事項です。

特に大量のデータを頻繁にシリアライズする場合、効率的なコーディングが求められます。

下記のサンプルコードでは、パフォーマンスを考慮したシリアライズの方法を表しています。

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

public class Employee
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        List<Employee> employees = new List<Employee>();
        for (int i = 0; i < 1000; i++)
        {
            employees.Add(new Employee() { Name = "従業員" + i, Age = 30 + i % 50 });
        }

        XmlSerializer serializer = new XmlSerializer(typeof(List<Employee>));
        using (StreamWriter writer = new StreamWriter("employees.xml"))
        {
            serializer.Serialize(writer, employees);
        }

        Console.WriteLine("大量データのシリアライズが完了しました。");
    }
}

このコードでは、大量のEmployeeオブジェクトをリストに格納し、一括でシリアライズしています。

このように、大量データを扱う際には、一度にシリアライズすることでパフォーマンスの向上が期待できます。

○サンプルコード10:セキュリティの考慮事項

XmlSerializerを使用する際には、セキュリティも重要な要素です。

特に、外部からのデータをデシリアライズする場合、不正なデータによる攻撃や脆弱性の問題が発生する可能性があります。

下記のサンプルコードでは、セキュリティを考慮したデシリアライズの方法を表しています。

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

public class Product
{
    public string Name { get; set; }
    public double Price { get; set; }
}

class Program
{
    static void Main()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Product));

        // セキュリティを考慮したデシリアライズ
        using (FileStream stream = new FileStream("product.xml", FileMode.Open))
        using (XmlReader reader = XmlReader.Create(stream))
        {
            Product product = (Product)serializer.Deserialize(reader);
            Console.WriteLine($"製品名: {product.Name}, 価格: {product.Price}");
        }
    }
}

この例では、XmlReaderを使用してデシリアライズを行っています。

XmlReaderは、XMLデータの検証や安全な読み込みをサポートしており、セキュリティリスクを低減できます。

特に外部ソースからのXMLデータを扱う場合、このような手法が推奨されます。

●注意点と対処法

XmlSerializerを使用する際には、いくつかの注意点があります。

これらを理解し、適切に対処することで、より安全で効率的なシリアライズプロセスを実現することができます。

○データ型の互換性に関する注意

XmlSerializerは、シリアライズおよびデシリアライズする際に、データ型の互換性を保つ必要があります。

特に、デシリアライズする際には、XMLデータが元のクラスの構造と一致している必要があります。

互換性がない場合、実行時エラーが発生する可能性があります。

この問題を回避するためには、シリアライズとデシリアライズで同じクラス構造を使用することが重要です。

○シリアライズプロセス中のエラー処理

シリアライズプロセス中には様々なエラーが発生する可能性があります。

これには、不正なデータ型、不完全なXML構造、ファイル書き込み時のエラーなどが含まれます。

これらのエラーを適切にハンドリングすることで、プログラムの安定性を高めることができます。

例外処理を適切に実装することで、これらの問題に対処できます。

○セキュリティ上の注意点

XmlSerializerの使用においては、セキュリティも重要な考慮事項です。

特に外部ソースからのXMLデータをデシリアライズする場合、XML注入攻撃などのセキュリティリスクに対処する必要があります。

安全なデシリアライズを行うためには、信頼できるソースからのデータのみを処理し、可能であればXMLデータを事前に検証することが推奨されます。

まとめ

この記事を通じて、C#におけるXmlSerializerクラスの使用方法とその応用例を詳細に解説してきました。

初心者から上級者まで、C#プログラミングにおいてXmlSerializerの使い方を理解することは非常に重要です。

この記事が示した多岐にわたるサンプルコードと詳細な説明は、実際のプログラム開発において役立つことでしょう。

特に、セキュリティやパフォーマンスの観点は、現代のソフトウェア開発において欠かせない要素です。

XmlSerializerを適切に使用することで、C#におけるデータのシリアライズとデシリアライズを効率的かつ安全に行うことができます。

この知識を活用し、より洗練されたプログラムの開発に取り組んでいただければ幸いです。