代码之家  ›  专栏  ›  技术社区  ›  Gqqnbig

序列化多态列表但不能更改类型定义

  •  0
  • Gqqnbig  · 技术社区  · 7 年前

    我正在使用另一方的dll,它定义了动物、猫、鱼类。

    //Begin another party's DLL
    public class animals
    {
    }
    
    public class cat : animals
    {
        public string size { get; set; }
        public string furColor { get; set; }
    }
    
    public class fish : animals
    {
        public string size { get; set; }
        public string scaleColor { get; set; }
    }
    //End another party's DLL
    
    static void Main(string[] args)
    {
    
        using (var xmlWriter = XmlWriter.Create("a.xml", new XmlWriterSettings { Indent = true }))
        {
            var eventArgsList = new List<animals>();
            eventArgsList.Add(new cat { size = "10", furColor = "red" });
            eventArgsList.Add(new fish { size = "20", scaleColor = "blue" });
    
            new XmlSerializer(eventArgsList.GetType(),new[] { typeof(cat), typeof(fish) }).Serialize(xmlWriter, eventArgsList);
        }
    }
    

    以上代码正确输出

    <?xml version="1.0" encoding="utf-8"?>
    <ArrayOfAnimals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <animals xsi:type="cat">
        <size>10</size>
        <furColor>red</furColor>
      </animals>
      <animals xsi:type="fish">
        <size>20</size>
        <scaleColor>blue</scaleColor>
      </animals>
    </ArrayOfAnimals>
    

    但是,我希望它看起来像

    <?xml version="1.0" encoding="utf-8"?>
    <Animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <cat>
        <size>10</size>
        <furColor>red</furColor>
      </cat>
      <fish>
        <size>20</size>
        <scaleColor>blue</scaleColor>
      </fish>
    </Animals>
    

    顺便说一下,它和 Serialize a polymorphic List with the same type name ,但我无法更改类型定义。我想我得用 XmlAttributeOverrides ,有人能告诉我怎么做吗?

    2 回复  |  直到 7 年前
        1
  •  1
  •   CodingYoshi    7 年前

    为了在XML中使用该结构而不编写自定义序列化程序,您需要在C语言类中具有相同的结构。但这很容易,因为visual studio会为您做到这一点。

    复制所需的XML并 create classes for that XML structure . 它将创建以下类。你需要做一个调整和设置 AnonymousType = false 正如我在下面所做的。

    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public partial class Animals
    {
    
        private AnimalsCat[] catField;
    
        private AnimalsFish[] fishField;
    
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("cat")]
        public AnimalsCat[] cat
        {
            get
            {
                return this.catField;
            }
            set
            {
                this.catField = value;
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("fish")]
        public AnimalsFish[] fish
        {
            get
            {
                return this.fishField;
            }
            set
            {
                this.fishField = value;
            }
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
    public partial class AnimalsCat
    {
    
        private byte sizeField;
    
        private string furColorField;
    
        /// <remarks/>
        public byte size
        {
            get
            {
                return this.sizeField;
            }
            set
            {
                this.sizeField = value;
            }
        }
    
        /// <remarks/>
        public string furColor
        {
            get
            {
                return this.furColorField;
            }
            set
            {
                this.furColorField = value;
            }
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
    public partial class AnimalsFish
    {
    
        private byte sizeField;
    
        private string scaleColorField;
    
        /// <remarks/>
        public byte size
        {
            get
            {
                return this.sizeField;
            }
            set
            {
                this.sizeField = value;
            }
        }
    
        /// <remarks/>
        public string scaleColor
        {
            get
            {
                return this.scaleColorField;
            }
            set
            {
                this.scaleColorField = value;
            }
        }
    }
    

    用法

    using (var xmlWriter = XmlWriter.Create("a.xml", new XmlWriterSettings { Indent = true }))
    {
        var eventArgsList = new Animals();
        eventArgsList.cat = new AnimalsCat[1]; // set this based on the number 
        eventArgsList.fish = new AnimalsFish[2]; // set this based on the number 
    
        // Do this using a loop but I just hard coded it
        eventArgsList.cat[0] = new AnimalsCat { size = 10, furColor = "red" };
        eventArgsList.fish[0] = new AnimalsFish { size = 20, scaleColor = "blue" };
        eventArgsList.fish[1] = new AnimalsFish { size = 30, scaleColor = "orange" };
    
        new XmlSerializer(eventArgsList.GetType(), new[] { typeof(AnimalsCat), typeof(AnimalsFish) }).Serialize(xmlWriter, eventArgsList);
    }
    

    输出

    <?xml version="1.0" encoding="utf-8"?>
    <Animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <cat>
        <size>10</size>
        <furColor>red</furColor>
      </cat>
      <fish>
        <size>20</size>
        <scaleColor>blue</scaleColor>
      </fish>
      <fish>
        <size>30</size>
        <scaleColor>orange</scaleColor>
      </fish>
    </Animals>
    
        2
  •  0
  •   Gqqnbig    7 年前

    受codingyoshi创新方法的启发,我发现下面的helper类可以缩短100行。

    [XmlRoot("Animals")]
    public class AnimalsHelper
    {
        [XmlElement("Cat", typeof(cat))]
        [XmlElement("Fish", typeof(fish))]
        public List<animals> Animals { get; set; } = new List<animals>();
    }
    
    static void Main(string[] args)
    {
    
        using (var xmlWriter = XmlWriter.Create("a.xml", new XmlWriterSettings { Indent = true }))
        {
            var animalsHelper= new AnimalsHelper();
            animalsHelper.Animals.Add(new cat { size = "10", furColor = "red" });
            animalsHelper.Animals.Add(new fish { size = "20", scaleColor = "blue" });
    
            new XmlSerializer(animalsHelper.GetType(),new[] { typeof(cat), typeof(fish) }).Serialize(xmlWriter, animalsHelper);
        }
    
        using (var xmlReader = XmlReader.Create("a.xml", new XmlReaderSettings { IgnoreWhitespace = true }))
        {
            var obj = (AnimalsHelper)new XmlSerializer(animalsHelper.GetType(), new[] { typeof(cat), typeof(fish) }).Deserialize(xmlReader);
    
        }
    }
    

    我仍然渴望一个不使用helper类的解决方案。

    推荐文章