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($"测试序列化结果:\r\n{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($"测试序列化结果:\r\n{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($"测试序列化结果:\r\n{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>
运行结果中的Residence标记就是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方法中添加Neighbor
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($"测试序列化结果:\r\n{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($"测试序列化结果:\r\n{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($"测试序列化结果:\r\n{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
}