[C#]属性とテキストで構成されるXMLタグをデシリアライズする為のクラス設計

C#でXMLデータを扱う場合、XMLSerializerが便利です
XMLのレイアウトに合わせてクラスを設計しておければ、XMLデータをクラスにデシリアライズしてくれるからです

デシリアライズの方法については、
[.NET][C#]XMLをクラスに変換する/クラスをXMLに変換する | ごった煮 – tips about programming and building a server
に詳しく書いておりますのでこちらを参照していただくとして、
本ページでは、属性とテキストで構成されるXMLをデシリアライズする為のクラスの設計方法について記載します

読み込み対象となるXML

例として、以下の様なXMLを用意しました

<?xml version="1.0" encoding="utf-8"?>
<person>
  <name>山田太郎</name>
  <birthday>1980/01/01</birthday>
  <job start="2002/4/1" end="2004/3/31">○○株式会社</job>
  <job start="2004/4/1" end="2008/3/31">□□株式会社</job>
  <job start="2009/4/1" >△△株式会社</job>
</person>

XMLタグ”job”に、属性”start” “end”があり、テキストとして”○○株式会社”等があります
また、XMLタグ “job” は複数あります

このようなXMLデータをデシリアライズする為のクラスをこれより設計していきます

クラスやプロパティに与える属性の種類

XMLデータをデシリアライズする場合、作成するクラスやプロパティに、XMLのタグやXML属性を対応付けしなければなりません
具体的には、クラスやプロパティに”属性”を与えることになります
与えられる属性としては、代表的なものとして以下があります

System.Xml.Serialization.XmlRoot XMLルートエレメント(タグ)名
System.Xml.Serialization.XmlElement XMLエレメント(タグ)名
System.Xml.Serialization.XmlAttribute XMLエレメント(タグ)の属性(Attribute)
System.Xml.Serialization.XmlText XMLエレメントの内容(テキスト)

クラス設計

XML “person” の構造は以下の様になっています

  • ルートタグは “person”
  • “job”タグに属性 “start”,”end”がある
  • “job”タグは複数ある

このことから、デシリアライズする為のクラスの構造は以下の様になると思います

PERSON
  +-- NAME
  +-- BIRTHDAY
  +-- JOB  ※複数ある為、List 
       +-- START 
       +-- END
       +-- 会社名

クラスの作成

では、実際にクラスを作成してみます
作るクラスは個人情報クラス(Person)と職歴クラス(Job)の2クラスです

個人情報クラス(Person)

using System;
using System.Collections.Generic;

namespace Sample.Model
{
    /// <summary>
    /// 個人情報
    /// </summary>
    [System.Xml.Serialization.XmlRoot("person")]
    public class Person
    {
        /// <summary>
        /// 名前
        /// </summary>
        [System.Xml.Serialization.XmlElement("name")]
        public string Name {get; set;}
        /// <summary>
        /// 誕生日
        /// </summary>
        [System.Xml.Serialization.XmlElement("birthday")]
        public string Birthday { get; set; }
        /// <summary>
        /// 職歴
        /// </summary>
        [System.Xml.Serialization.XmlElement("job")]
        public List<Sample.Model.Job> Jobs { get; set; }
    
    }
}

職歴は複数ある為、List<Sample.Model.Job> としてプロパティ定義しています

職歴クラス(Job)

using System;

namespace Sample.Model
{
    /// <summary>
    /// 職歴
    /// </summary>
    public class Job
    {
        /// <summary>
        /// 入社日
        /// </summary>
        [System.Xml.Serialization.XmlAttribute("start")]
        public string StartDay {get; set;}
        /// <summary>
        /// 退社日
        /// </summary>
        [System.Xml.Serialization.XmlAttribute("end")]
        public string EndDay { get; set; }
        /// <summary>
        /// 会社名
        /// </summary>
        [System.Xml.Serialization.XmlText()]
        public string CompanyName { get; set; }
    }
}

入社日及び退社日のプロパティには属性の為、プロパティに”XmlAttribute”の属性を与えています

また、会社名のプロパティにには”XmlText”の属性を与えています

実際に読み込んでみる

クラスの作成が終わりましたので、実際に読み込むコードを作成して実行してみましょう

using System;
using System.Diagnostics;

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {

            System.IO.FileStream fs = new System.IO.FileStream(@"C:\TEMP\PERSON.XML", System.IO.FileMode.Open);

            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Sample.Model.Person));

            Sample.Model.Person personModel = (Sample.Model.Person)serializer.Deserialize(fs);

            Debug.WriteLine(String.Format("NAME={0}, Birthday={1}", personModel.Name, personModel.Birthday));

            foreach (Sample.Model.Job jobModel in personModel.Jobs)
            {
jobModel.EndDay));
                Debug.WriteLine(String.Format("COMAPNY={0}, START={1}, END={2}", jobModel.CompanyName, jobModel.StartDay, jobModel.EndDay));
            }
            fs.Close();
        }
    }
}

冒頭で記載したXMLデータをC:\TEMP\PERSON.XMLとして配置し、VisualStudio上で実行します
すると、デバックコンソールに以下の様にプリントされました

   :    :
   :    :
NAME=山田太郎, Birthday=1980/01/01
COMAPNY=○○株式会社, START=2002/4/1, END=2004/3/31
COMAPNY=□□株式会社, START=2004/4/1, END=2008/3/31
COMAPNY=△△株式会社, START=2009/4/1, END=
   :    :
   :    :

うん。うまく読み込めた様です

XMLSerializerを使ったより詳しいTIPSは姉妹サイトごった煮 – tips about programming and building a serverの個別記事
[.NET][C#]XMLをクラスに変換する/クラスをXMLに変換する
を参照してください