热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

功能比较简单,对自定义类型、List、Array实现了序列化其中包含了(反射创建数组、反射创建泛型、反射填充泛型内容、反射填充数组内容)其实我写这段话就是为了让你来的。

功能比较简单,对自定义类型、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());
}
}
}

 

 

 

运行结果:

 


推荐阅读
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 集合的遍历方式及其局限性
    本文介绍了Java中集合的遍历方式,重点介绍了for-each语句的用法和优势。同时指出了for-each语句无法引用数组或集合的索引的局限性。通过示例代码展示了for-each语句的使用方法,并提供了改写为for语句版本的方法。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
author-avatar
悟哩兰荷_982
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有