[原] 自己实现简单的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());
}
}
}
运行结果: