• C# 序列化与反序列化之xml对属性或者字段的子类化的子对象进行序列化的解决方案


    C# 序列化与反序列化之xml对属性或者字段的子类化的子对象进行序列化的解决方案

    xml序列化涉及到XmlRoot,XmlInclude,XmlElement,XmlAttribute,XmlType(用于继承的子类),XmlArray,XmlArrayItem(集合和集合项)等

    新建控制台console项目,添加类XmlPerson以及XmlPerson的子类XmlStudent,XmlTeacher,添加Address类以及Address的的子类USAddress,AUAddress

    1、运行的主方法代码如下:

    using log4net;
    using System;
    using System.Data;
    using System.Data.SQLite;
    using System.Diagnostics;
    using System.IO;
    using System.IO.Compression;
    using System.IO.MemoryMappedFiles;
    using System.IO.Pipes;
    using System.Linq;
    using System.Net;
    using System.Security.AccessControl;
    using System.Security.Principal;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Reflection;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Runtime.Serialization;
     
    namespace SupremeConsole
    {
        class Program
        {
           
            static void Main(string[] args)
            {
                
                TestSeri();
                Console.ReadLine();
            }
     
           
            public static void TestSeri()
            {
                //Team team = new Team { TName="123",PlayerList = { new Person { Name="1",Age=1},new Person { Name = "2", Age = 2 } } };
                #region BinarySerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.BinarySerialize<Team>(team);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:
    {s}");
     
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.bin");//序列化
                //SerializeManager.Instance.BinarySerialize<Team>(team, path);
     
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.bin");
                //Team test = SerializeManager.Instance.BinaryDeserialize<Team>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
                #endregion
     
                #region SoapSerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.SoapSerialize<Team>(team);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:
    {s}");
     
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Soap序列化.xml");//序列化
                //SerializeManager.Instance.SoapSerialize<Team>(team, path);
     
     
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Soap序列化.xml");
                //Team test = SerializeManager.Instance.SoapDeserialize<Team>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
                #endregion
     
                #region XmlSerialize 要序列化的对象可以不添加SerializableAttribute属性,[Serializable]
                //XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12,Address="住址。。。。" };
    XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, HomeAddress = new Address { Street = "默默大街三号", PostCode = "233664" } };
                //XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, HomeAddress = new USAddress { Street = "默默大街三号", PostCode = "233664", Neighbor="邻居666" } };
                string s = SerializeManager.Instance.XmlSerialize<XmlPerson>(xmlPerson);//序列化
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("测试序列化成功。。。");
                Console.WriteLine($"测试序列化结果:
    {s}");
     
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化.txt");//序列化
                //SerializeManager.Instance.XmlSerialize<TestClass>(testClass, path);
     
                //备用
                //string json = "{"Address":"中国南京","Age":10,"Id":1,"Name":"张三","Sex":"男"}";
                //TestClass test = SerializeManager.Instance.DataContractJsonDeserializeJson<TestClass>(json);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
     
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化.txt");
                //TestClass test = SerializeManager.Instance.XmlDeserialize<TestClass>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //} 
                #endregion
            }
        }
    }

    2、xml对属性或者字段的子类化的子对象进行序列化,首先添加类XmlPerson以及XmlPerson的子类XmlStudent,XmlTeacher,添加Address类以及Address的的子类USAddress,AUAddress

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Serialization;
    
    namespace SupremeConsole
    {
        #region 继承XmlPerson以及继承的子类 
        /// <summary>
        /// xml序列化测试类
        /// </summary>
        //继承XmlPerson的子类XmlStudent,XmlTeacher的序列化
        //[XmlInclude(typeof(继承的子类1))]//XmlInclude指明了,继承子类的序列化的类型,如 XmlInclude(typeof(XmlStudent)),或者再序列化的时候添加子类类型XmlSerializer xs = new XmlSerializer (typeof (XmlPerson),new Type[] { typeof (继承的子类1), typeof (继承的子类2)} );,如:new Type[] { typeof (XmlStudent), typeof (XmlTeacher)};
        [XmlRoot("haha")]
        //[XmlInclude(typeof(XmlStudent))]
        //[XmlInclude(typeof(XmlTeacher))]
        public class XmlPerson
        {
            /// <summary>
            /// 姓名
            /// </summary>       
            [XmlElement("MyName", Order = 2)]
            public string Name { get; set; }
    
            /// <summary>
            /// 年龄
            /// </summary>       
            [XmlAttribute("MyAge")]
            public int Age { get; set; }
    
            ///// <summary>
            ///// 住址
            ///// </summary>
            //[XmlElement("Residence", Order = 1)]
            //public string Address { get; set; }
    
            /// <summary>
            /// 住址
            /// </summary>
            [XmlElement("Residence", Order = 1)]
            public Address HomeAddress = new Address();//常规序列化        
        }
    
        [XmlType("SubXmlPersonIsXmlStudent")]//XmlStudent序列化后的名称
        public class XmlStudent : XmlPerson
        {
            /// <summary>
            /// 学号
            /// </summary>
            public string StuNumber { get; set; }
        }
    
        [XmlType("SubXmlPersonIsXmlTeacher")]//XmlTeacher序列化后的名称
        public class XmlTeacher : XmlPerson
        {
            /// <summary>
            /// 工号
            /// </summary>
            public string TeachNumber { get; set; }
    
        }
        #endregion
    
        #region Address以及继承的子类
    
        public class Address  //常规序列化
        {
            public string Street, PostCode;
        }
    
        [XmlType("USAddressISSubAddress")]
        public class USAddress : Address   //子类的序列化
        {
            public string Neighbor; //邻居
        }
    
        [XmlType("AUAddressISSubAddress")]
        public class AUAddress : Address //子类的序列化
        {
            public string OldNeighbor; //邻居
        }
        #endregion
    }

    运行效果:

    测试序列化成功。。。
    测试序列化结果:
    <?xml version="1.0"?>
    <haha xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" MyAge="12">
      <Residence>
        <Street>默默大街三号</Street>
        <PostCode>233664</PostCode>
      </Residence>
      <MyName>1111</MyName>
    </haha>
    

    运行结果中的红色标记就是XmlPerson中的HomeAddress 设置的别名Residence

    /// <summary>
    /// 住址
    /// </summary>
    [XmlElement("Residence", Order = 1)]
    public Address HomeAddress = new Address();//常规序列化

    修改XmlPerson中的 

    [XmlElement("Residence", Order = 1)]
    public Address HomeAddress = new Address();//常规序列化

    改成

    [XmlElement("Residence", Order = 1)]
    public Address HomeAddress = new USAddress();//子类的序列化

    同时修改 Address,在Address类上添加特性[XmlInclude(typeof(USAddress))],[XmlInclude(typeof(AUAddress))]

    [XmlInclude(typeof(USAddress))]
    [XmlInclude(typeof(AUAddress))]
    public class Address //常规序列化
    {
    public string Street, PostCode;
    }

    把TestSeri法中的

     XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, HomeAddress = new Address { Street = "默默大街三号", PostCode = "233664" } };

    改成

    XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, HomeAddress = new USAddress { Street = "默默大街三号", PostCode = "233664", Neighbor="邻居666" } };

    运行结果:

    测试序列化成功。。。
    测试序列化结果:
    <?xml version="1.0"?>
    <haha xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" MyAge="12">
      <Residence xsi:type="USAddressISSubAddress">
        <Street>默默大街三号</Street>
        <PostCode>233664</PostCode>
        <Neighbor>邻居666</Neighbor>
      </Residence>
      <MyName>1111</MyName>
    </haha>
    

     

      

    运行的结果来看出现了 Residence xsi:type="USAddressISSubAddress",出现的原因是在Address类上添加特性[XmlInclude(typeof(USAddress))],这就是xml对属性或者字段的子类化的子对象进行序列化的结果

    要想出现下面的效果

    修改

    [XmlElement("Residence", Order = 1)]
    //public Address HomeAddress = new USAddress();//子类的序列化

    改为

    [XmlElement("Residence", typeof(Address), Order = 1)]
    [XmlElement("USAddressISSubAddressResidence", typeof(USAddress), Order = 1)]
    [XmlElement("AUAddressISSubAddressResidence", typeof(AUAddress), Order = 1)]
    public Address HomeAddress = new USAddress();//子类的序列化

    这时候就可以达到上述效果,但是Address类上添加特性[XmlInclude(typeof(USAddress))]对结果没有影响,可以去掉。

      

    3、xml对属性或者字段是泛型集合的序列化处理方式如下

    首先把XmlPerson类中的

    public Address HomeAddress = new USAddress();//子类的序列化

    改成 

    [XmlArray("集合列表的名称", Order = 1)]//默认序列化以后的名称是Addresses ,现在通过XmlArray来修改为指定的名称,如:[XmlArray("集合列表的名称", Order = 1)]
    [XmlArrayItem("集合列表中的项的名称")]//默认序列化以后的名称是Address,现在通过XmlArrayItem来修改为指定的名称,如:[XmlArrayItem("集合列表中的项的名称")]
    public List<Address> Addresses = new List<Address>(); 

    注意:XmlElement、XmlText 和 XmlAnyElement 不能与 XmlAttribute、XmlAnyAttribute、XmlArray 或 XmlArrayItem 一起使用,否则会报错。 

    把TestSeri方法中的

    XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, HomeAddress = new USAddress { Street = "默默大街三号", PostCode = "233664", Neighbor="邻居666" } };

    改成

    XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, Addresses = new List<Address> { new Address { Street = "大街三三号", PostCode = "123"}, new USAddress { Street = "大街六六号", PostCode = "456", Neighbor = "邻居666" } } };

    运行效果

    把   public List<Address> Addresses = new List<Address>();上的特性改成

    [XmlElement("Address", typeof(Address), Order = 1)]
    [XmlElement("AUAddress", typeof(AUAddress))]
    [XmlElement("USAddress", typeof(USAddress))]
    public List<Address> Addresses = new List<Address>();

    把TestSeri方法中的

    XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, Addresses = new List<Address> { new Address { Street = "大街三三号", PostCode = "123"}, new USAddress { Street = "大街六六号", PostCode = "456", Neighbor = "邻居666" } } };

    改成

    XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, Addresses = new List<Address> { new Address { Street = "大街三三号", PostCode = "123"}, new USAddress { Street = "大街六六号", PostCode = "456", Neighbor = "邻居666" }, new AUAddress { Street = "大街八八号", PostCode = "789", OldNeighbor = "旧朋友邻居8888" } } };

    运行效果

     把

    [XmlElement("Address", typeof(Address), Order = 1)]
    [XmlElement("AUAddress", typeof(AUAddress))]
    [XmlElement("USAddress", typeof(USAddress))]
    public List<Address> Addresses = new List<Address>();

    上的特性

    改成

    [XmlArray(Order = 1)]
    [XmlArrayItem("Address", typeof(Address))]
    [XmlArrayItem("AUAddress", typeof(AUAddress))]
    [XmlArrayItem("USAddress", typeof(USAddress))]
    public List<Address> Addresses = new List<Address>();

    运行效果

    上述测试的全部代码如下:

    Main主方法代码:

    using log4net;
    using System;
    using System.Data;
    using System.Data.SQLite;
    using System.Diagnostics;
    using System.IO;
    using System.IO.Compression;
    using System.IO.MemoryMappedFiles;
    using System.IO.Pipes;
    using System.Linq;
    using System.Net;
    using System.Security.AccessControl;
    using System.Security.Principal;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Reflection;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Runtime.Serialization;
    using System.Collections.Generic;
    
    namespace SupremeConsole
    {
        class Program
        {       
            static void Main(string[] args)
            {
                TestSeri();
                Console.ReadLine();
            }
    
            public static void TestSeri()
            {
                //Team team = new Team { TName="123",PlayerList = { new Person { Name="1",Age=1},new Person { Name = "2", Age = 2 } } };
                #region BinarySerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.BinarySerialize<Team>(team);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:
    {s}");
    
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.bin");//序列化
                //SerializeManager.Instance.BinarySerialize<Team>(team, path);
    
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "序列化11111.bin");
                //Team test = SerializeManager.Instance.BinaryDeserialize<Team>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
                #endregion
    
                #region SoapSerialize 必须添可序列化属性,即要序列化的对象必须添加SerializableAttribute属性,[Serializable]
                //string s = SerializeManager.Instance.SoapSerialize<Team>(team);//序列化
                //Console.ForegroundColor = ConsoleColor.Green;
                //Console.WriteLine("测试序列化成功。。。");
                //Console.WriteLine($"测试序列化结果:
    {s}");
    
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Soap序列化.xml");//序列化
                //SerializeManager.Instance.SoapSerialize<Team>(team, path);
    
    
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Soap序列化.xml");
                //Team test = SerializeManager.Instance.SoapDeserialize<Team>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
                #endregion
    
                #region XmlSerialize 要序列化的对象可以不添加SerializableAttribute属性,[Serializable]
                //XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12,Address="住址。。。。" };
                //XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, HomeAddress = new Address { Street = "默默大街三号", PostCode = "233664" } };
                //XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, HomeAddress = new USAddress { Street = "默默大街三号", PostCode = "233664", Neighbor="邻居666" } };
                XmlPerson xmlPerson = new XmlPerson { Name = "1111", Age = 12, Addresses = new List<Address> { new Address { Street = "大街三三号", PostCode = "123"}, new USAddress { Street = "大街六六号", PostCode = "456", Neighbor = "邻居666" }, new AUAddress { Street = "大街八八号", PostCode = "789", OldNeighbor = "旧朋友邻居8888" } } };
                string s = SerializeManager.Instance.XmlSerialize<XmlPerson>(xmlPerson);//序列化
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("测试序列化成功。。。");
                Console.WriteLine($"测试序列化结果:
    {s}");
    
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Addresses序列化.txt");//序列化
                //SerializeManager.Instance.XmlSerialize<XmlPerson>(xmlPerson, path);
    
                //string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Addresses序列化.txt");
                //XmlPerson test = SerializeManager.Instance.XmlDeserialize<XmlPerson>(path);//反序列化
                //if (test != null)
                //{
                //    Console.WriteLine($"测试序列化结果:{test.ToString()}");
                //}
                #endregion
            }
      }
    }

    xmlPerson类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Serialization;
    
    namespace SupremeConsole
    {
        #region 继承XmlPerson以及继承的子类 
        /// <summary>
        /// xml序列化测试类
        /// </summary>
        //继承XmlPerson的子类XmlStudent,XmlTeacher的序列化
        //[XmlInclude(typeof(继承的子类1))]//XmlInclude指明了,继承子类的序列化的类型,如 XmlInclude(typeof(XmlStudent)),或者再序列化的时候添加子类类型XmlSerializer xs = new XmlSerializer (typeof (XmlPerson),new Type[] { typeof (继承的子类1), typeof (继承的子类2)} );,如:new Type[] { typeof (XmlStudent), typeof (XmlTeacher)};
        [XmlRoot("haha")]
        //[XmlInclude(typeof(XmlStudent))]
        //[XmlInclude(typeof(XmlTeacher))]
        public class XmlPerson
        {
            /// <summary>
            /// 姓名
            /// </summary>       
            [XmlElement("MyName", Order = 2)]
            public string Name { get; set; }
    
            /// <summary>
            /// 年龄
            /// </summary>       
            [XmlAttribute("MyAge")]
            public int Age { get; set; }
    
            ///// <summary>
            ///// 住址
            ///// </summary>
            //[XmlElement("Residence", Order = 1)]
            //public string Address { get; set; }
    
            ///// <summary>
            ///// 住址
            ///// </summary>
            //[XmlElement("Residence", Order = 1)]
            //public Address HomeAddress = new Address();//常规序列化
    
            ///// <summary>
            ///// 住址
            ///// </summary>
            //[XmlElement("Residence", Order = 1)]
            //public Address HomeAddress = new USAddress();//子类的序列化
    
            ///// <summary>
            ///// 住址
            ///// </summary>
            //[XmlElement("Residence", typeof(Address), Order = 1)]
            //[XmlElement("USAddressISSubAddressResidence", typeof(USAddress), Order = 1)]
            //[XmlElement("AUAddressISSubAddressResidence", typeof(AUAddress), Order = 1)]
            //public Address HomeAddress = new USAddress();//子类的序列化
    
            ///// <summary>
            ///// 地址集合
            ///// </summary>
            //[XmlArray("集合列表的名称", Order = 1)]
            //[XmlArrayItem("集合列表中的项的名称")]
            //public List<Address> Addresses = new List<Address>();
            [XmlArray(Order = 1)]
            [XmlArrayItem("Address", typeof(Address))]
            [XmlArrayItem("AUAddress", typeof(AUAddress))]
            [XmlArrayItem("USAddress", typeof(USAddress))]
            public List<Address> Addresses = new List<Address>();
    
            //[XmlElement("Address", typeof(Address), Order = 1)]
            //[XmlElement("AUAddress", typeof(AUAddress))]
            //[XmlElement("USAddress", typeof(USAddress))]
            //public List<Address> Addresses = new List<Address>();
        }
    
        [XmlType("SubXmlPersonIsXmlStudent")]//XmlStudent序列化后的名称
        public class XmlStudent : XmlPerson
        {
            /// <summary>
            /// 学号
            /// </summary>
            public string StuNumber { get; set; }
        }
    
        [XmlType("SubXmlPersonIsXmlTeacher")]//XmlTeacher序列化后的名称
        public class XmlTeacher : XmlPerson
        {
            /// <summary>
            /// 工号
            /// </summary>
            public string TeachNumber { get; set; }
    
        }
        #endregion
    
        #region Address以及继承的子类
    
        [XmlInclude(typeof(USAddress))]
        [XmlInclude(typeof(AUAddress))]
        public class Address  //常规序列化
        {
            public string Street, PostCode;
        }
    
        [XmlType("USAddressISSubAddress")]
        public class USAddress : Address   //子类的序列化
        {
            public string Neighbor; //邻居
        }
    
        [XmlType("AUAddressISSubAddress")]
        public class AUAddress : Address //子类的序列化
        {
            public string OldNeighbor; //邻居
        }
        #endregion
    }
  • 相关阅读:
    python中的os
    文件系统的简单操作
    文件与目录管理
    用户与用户组管理
    基础命令的操作
    linux开机流程
    ansible源码安装、普通用户实现批量控制
    python3中得数据类型
    判断一个字符串中得大写字母,小写字母,数字出现得次数
    Elasticsearch 如何安全加固
  • 原文地址:https://www.cnblogs.com/1175429393wljblog/p/12036026.html
Copyright © 2020-2023  润新知