[原] 自己实现简单的XML序列化和反序列化
功能比较简单,对自定义类型、List
其中包含了(反射创建数组、反射创建泛型、反射填充泛型内容、反射填充数组内容) 其实我写这段话就是为了让你来的。
public static class SerializeXmlHelper { /// /// 序列化一个对象(非列表为XML) /// /// /// /// public static XElement SerializeToXml( this object obj, string rootName = null ) { var t = obj.GetType(); XElement root; if (t.IsGenericType) { root = obj.SerializeListToXml(rootName); } else if (t.IsArray) { root = obj.SerializeArrayToXml(rootName); } else { root = new XElement(t.Name); var ps = t.GetProperties(); if (ps.Length == 0) { root.Value = obj.ToString(); } else { foreach ( var p in ps) { if (p.PropertyType.BaseType == typeof ( object )) { var node = new XElement(p.Name, p.GetValue(obj, null )); root.Add(node); } else root.Add(p.GetValue(obj, null ).SerializeToXml(p.Name)); } } } return root; } /// /// 序列化一个List为xml /// /// /// /// public static XElement SerializeListToXml( this object obj, string rootName) { var root = new XElement(rootName); var list = (IEnumerable)obj; foreach ( var x in list) { root.Add(x.SerializeToXml(rootName)); } return root; } /// /// 序列化一个数组为xml /// /// /// /// public static XElement SerializeArrayToXml( this object obj, string rootName) { var root = new XElement(rootName); foreach ( var o in (Array)obj) { root.Add(o.SerializeToXml(rootName)); } return root; } /// /// 反序列xml为一个对象 /// /// /// /// public static T DeserializeFromXml( this XElement element) { return (T)DeserializeFromXml(element, typeof (T)); } public static object DeserializeFromXml( this XElement element, Type t) { //如果是继承,则名字空间必须一致才行。 if (t.Name != element.Name) { t = Type.GetType(t.Namespace + "." + element.Name); if (t == null ) return null ; } var obj = Activator.CreateInstance(t); var ps = t.GetProperties(); foreach ( var p in ps) { var e = element.Element(p.Name); if (!e.HasElements) { p.SetValue(obj, e.Value, null ); } else { if (p.PropertyType.IsArray) { var tmp = DeserializeArrayFromXml(e, p.PropertyType); p.SetValue(obj, tmp, null ); } else if (p.PropertyType.IsGenericType) { p.SetValue(obj, DeserializeListFromXml(e, p.PropertyType), null ); } else { p.SetValue(obj, e.Value, null ); } } } return obj; } /// /// 反序列化xml为一个数组 /// /// /// public static T[] DeserializeArrayFromXml( this XContainer element) { return (T[])DeserializeArrayFromXml(element, typeof (T)); } public static Array DeserializeArrayFromXml( this XContainer element, Type t) { var elements = element.Elements(); //创建数组 var atype = Type.GetType(t.FullName.Replace( "[]" , "" )); var array = Array.CreateInstance(atype, elements.Count()); var i = 0; foreach ( var e in elements) { if (e.HasElements) { array.SetValue(DeserializeFromXml(e, atype), i); } else { array.SetValue(Convert.ChangeType(e.Value, atype), i); } i++; } return array; } /// /// 反序列化xml为一个泛型ListT /// /// /// public static T DeserializeListFromXml( this XContainer element) { return (T)DeserializeListFromXml(element, typeof (T)); } /// /// 反序列化xml为一个泛型ListT /// /// /// 泛型List的类型 /// public static IEnumerable DeserializeListFromXml( this XContainer element, Type t) { var elements = element.Elements(); t = Type.GetType(t.FullName.Replace( "IEnumerable" , "List" )); var list = (IEnumerable)Activator.CreateInstance(t); var argt = t.GetGenericArguments()[0]; var add = t.GetMethod( "Add" , new [] { argt }); foreach ( var e in elements) { //如果是自定义类型 if (e.HasElements) { add.Invoke(list, new [] { DeserializeFromXml(e, argt) }); } else add.Invoke(list, new [] { Convert.ChangeType(e.Value, argt) }); } return list; } } |
测试代码:
namespace ConsoleApplication2
{
public class A
{
public string Name { get; set; }
}
public class Test
{
public string Name { get; set; }
public int[] Arr { get; set; }
public A[] Arr1 { get; set; }
public IEnumerable<A> List { get; set; }
}
class Program
{
static void Main(string[] args)
{
var t = new Test
{
Name = "T1",
Arr = new[] { 1, 2, 3, 4 },
Arr1 = new [] { new A { Name = "A1" }, new A { Name = "A2" } },
List = new List<A> { new A { Name = "A1" }, new A { Name = "A2" } }
};
var xml = t.SerializeToXml();
Console.WriteLine(xml);
var obj = new Test();
obj.DeserializeFromXml(xml);
Console.WriteLine(obj.Arr[0]);
Console.Read();
}
public static string XmlSerializer<T>(T serialObject) where T : class
{
var ser = new XmlSerializer(serialObject.GetType());
var mem = new MemoryStream();
var writer = new XmlTextWriter(mem, Encoding.UTF8);
ser.Serialize(writer, serialObject);
writer.Close();
return Encoding.UTF8.GetString(mem.ToArray());
}
}
}
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?