読者です 読者をやめる 読者になる 読者になる

謎言語使いの徒然

適当に気になった技術や言語を流すブログ。

XmlSerializer 試してみる。

勉強 .NET Tips

実行対象のデータクラス(持ち越し)。

namespace UsingXmlSerializer
{
    [Serializable]
    public class Hardwere
    {
        public uint Price;
        public String Name { get; set; }
        public String Maker;

        public override string ToString()
        {
            return string.Format(
                "Name:{0}, Price:{1}({2})",
                Name, Price, Maker);
        }
    }

    [Serializable]
    public class Game : IDeserializationCallback
    {
        public Hardwere[] Hard { get; set; }
        public String Title { get; set; }
        public String Genre { get; set; }
        public uint Price { get; set; }
        public String CERO = "A";
        public int Age;

        public override string ToString()
        {
            return string.Format(
                "Title:{0}, CERO:{4}({5}), Genre:{1}, Price:{2} {3}",
                Title, Genre, Price, HardList(Hard), CERO, Age);
        }

        private static string HardList(Hardwere[] list)
        {
            StringBuilder builder = new StringBuilder();
            foreach (Hardwere data in list)
            {
                builder.Append('(');
                builder.Append(data);
                builder.Append(')');
            }

            return builder.ToString();
        }

        void IDeserializationCallback.OnDeserialization(object sender)
        {
            switch (this.CERO)
            {
                case "A":
                    this.Age = 0;
                    break;
                case "B":
                    this.Age = 12;
                    break;
                case "C":
                    this.Age = 15;
                    break;
                case "D":
                    this.Age = 17;
                    break;
                case "Z":
                    this.Age = 18;
                    break;
                default:
                    this.Age = 0;
                    break;
            }
        }
    }

    [Serializable]
    public enum HardwereType
    {
        PS3, XBox360, PSP, Wii, DS
    }
}

このクラスの出力が以下のとおり。

<?xml version="1.0" encoding="utf-8"?>
<Game xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <CERO>D</CERO>
  <Age>0</Age>
  <Hard>
    <Hardwere>
      <Price>29800</Price>
      <Maker>Microsoft</Maker>
      <Name>Xbox 360 4GB + Kinect</Name>
    </Hardwere>
    <Hardwere>
      <Price>34980</Price>
      <Maker>SONY</Maker>
      <Name>PlayStationR3 クラシック・ホワイト 320GB</Name>
    </Hardwere>
  </Hard>
  <Title>VANQUISH</Title>
  <Genre>FPS</Genre>
  <Price>7980</Price>
</Game>
XmlArray
[XmlArray(ElementName="Hardweres")]
public Hardwere[] Hard { get; set; }
<Hardweres>
  <Hardwere>
    <Price>29800</Price>
    <Maker>Microsoft</Maker>
    <Name>Xbox 360 4GB + Kinect</Name>
  </Hardwere>
  <Hardwere>
    <Price>34980</Price>
    <Maker>SONY</Maker>
    <Name>PlayStationR3 クラシック・ホワイト 320GB</Name>
  </Hardwere>
</Hardweres>
XmlArrayItem
[XmlArrayItem("Platform")]
public Hardwere[] Hard { get; set; }
  <Hard>
    <Platform>
      <Price>29800</Price>
      <Maker>Microsoft</Maker>
      <Name>Xbox 360 4GB + Kinect</Name>
    </Platform>
    <Platform>
      <Price>34980</Price>
      <Maker>SONY</Maker>
      <Name>PlayStationR3 クラシック・ホワイト 320GB</Name>
    </Platform>
  </Hard>
XmlAttribute
[XmlAttribute]
public String Name { get; set; }
<Platform Name="Xbox 360 4GB + Kinect">
  <!-- 略 -->
</Platform>
XmlRoot
[XmlRoot(ElementName="GameSoft")]
public class Game : IDeserializationCallback
<?xml version="1.0" encoding="utf-8"?>
<GameSoft xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <!-- 略 -->
</GameSoft>
XmlAttribute
public class Hardwere
{
    public uint Price;

    [XmlAttribute]
    public String Name { get; set; }
    public String Maker;

    public override string ToString()
    {
        return string.Format(
            "Name:{0}, Price:{1}({2})",
            Name, Price, Maker);
    }
}
<Platform Name="Xbox 360 4GB + Kinect">
  <Price>29800</Price>
  <Maker>Microsoft</Maker>
</Platform>
XmlChoiceIdentifier

使い方が凄く特殊。
XMLSchema 上、以下の状態(XML要素選択)のモノをマップする際に使う。

<choice>
  <element name="A" />
  <element name="B" />
  <element name="C" />
  <element name="D" />
  <element name="Z" />
</choice>
[XmlElement("A", typeof(String))]
[XmlElement("B", typeof(String))]
[XmlElement("C", typeof(String))]
[XmlElement("D", typeof(String))]
[XmlElement("Z", typeof(String))]
[XmlChoiceIdentifier("cero")]
public String CERO = "A";

[XmlIgnore]
public CEROTypes cero;

/* 中略 */

[XmlType(IncludeInSchema = false)]
public enum CEROTypes
{
    A,B,C,D,Z
}

と書いて、

<?xml version="1.0" encoding="utf-8"?>
<GameSoft xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <A>D</A>

多分、解析時に「A」が入ってるからタグが「A」になってるのかも?

XmlEnum
[XmlRoot(ElementName="GameSoft")]
public class Game : IDeserializationCallback
{
    public CEROTypes innerCero = CEROTypes.A;
    /* 略 */
}

public enum CEROTypes
{
    [XmlEnum(Name="前年齢")]
    A,
    [XmlEnum(Name = "12歳以上")]
    B,
    [XmlEnum(Name = "15歳以上")]
    C,
    [XmlEnum(Name = "17歳以上")]
    D,
    [XmlEnum(Name = "18歳以上")]
    Z
}
<?xml version="1.0" encoding="utf-8"?>
<GameSoft xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" mlns:xsd="http://www.w3.org/2001/XMLSchema">
  <innerCero>前年齢</innerCero>
XmlIgnore

XMLシリアライズされなくなります。以上。

XmlText

XML 直下文字列になる。

class Sample{
    [XmlText]
    public string TextMessage = "HAHAHA";
}
<?xml version="1.0" encoding="utf-8"?>
<Sample>HAHAHA</Sample>
XmlType

XML 定義型を割り当てる

[XmlType(TypeName="Platform")]
public class Hardwere
{
    public uint Price;

    [XmlAttribute]
    public String Name { get; set; }
    public String Maker;

    public override string ToString()
    {
        return string.Format(
            "Name:{0}, Price:{1}({2})",
            Name, Price, Maker);
    }
}
<Platform Name="Xbox 360 4GB + Kinect">
  <Price>29800</Price>
  <Maker>Microsoft</Maker>
</Platform>