[原] 自己实现简单的XML序列化和反序列化

功能比较简单,对自定义类型、List、Array实现了序列化

其中包含了(反射创建数组、反射创建泛型、反射填充泛型内容、反射填充数组内容) 其实我写这段话就是为了让你来的。

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());
}
}
}
复制代码

 

 

 

运行结果:

 

posted @   君之蘭  阅读(891)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示