XML的序列化和反序列化 详细介绍
为什么要做序列化和反序列化?
一个回答:
我们都知道对象是不能在网络中直接传输的,不过还有补救的办法。XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储数据,任何一个对象都可以用XML来描述。XML是可以作为对象信息的载体在网络中传输,因为它是文本形式的。
怎么进行XML文档与对象的相互转换呢?
XmlSerializer类就是干这个活的。
命名空间:System.Xml.Serialization
程序集:System.Xml(在 system.xml.dll 中)
现在这里展示了一个提供序列化与反序列化方法的EncodeHelper类(在文章最后,并且会讲解如何使用)。
Deserialize方法将XML字符串转换为指定类型的对象;(反序列化)
Serialize方法则将对象转换为XML字符串。(序列化)
另一个回答:
class Program {static void Main(string[] args){int i = 10;//声明Xml序列化对象实例serializerXmlSerializer serializer = new XmlSerializer(typeof(int));//执行序列化并将序列化结果输出到控制台 serializer.Serialize(Console.Out, i);Console.Read();} }
上面代码对int i进行了序列化,并将序列化的结果输出到了控制台,输出结果如下:
<?xml version="1.0" encoding="gb2312"?> <int>10</int>
可以将上述序列化的xml进行反序列化,如下代码:
static void Main(string[] args) {using (StringReader rdr = new StringReader(@"<?xml version=""1.0"" encoding=""gb2312""?> <int>10</int>")){//声明序列化对象实例serializer XmlSerializer serializer = new XmlSerializer(typeof(int));//反序列化,并将反序列化结果值赋给变量iint i = (int)serializer.Deserialize(rdr);//输出反序列化结果Console.WriteLine("i = " + i);Console.Read();} }
以上代码用最简单的方式说明了xml序列化和反序列化的过程,.Net系统类库为我们做了大量的工作,序列化和反序列化都非常简单。但是在现实中业务需求往往比较复杂,不可能只简单的序列化一个int变量,显示中我们需要对复杂类型进行可控制的序列化。
[XmlRoot(
"cat"
)]
//要求不序列化Speed属性
[XmlIgnore]
[XmlAttribute
]
[XmlElement
]
可以使用XmlElement指定属性序列化为子节点(默认情况会序列化为子节点);或者使用XmlAttribute特性制定属性序列化为Xml节点的属性;还可以通过XmlIgnore特性修饰要求序列化程序不序列化修饰属性。
一、序列化对象
首先我们先定义实体类:
public class People{//XmlAttribute:指定XmlSerializer将该类成员序列化为XML属性
[XmlAttribute]public string Name { get; set; }[XmlAttribute]public int Age { get; set; }}[XmlRoot]public class Student : People{//定义SClass属性的序列化为Student节点的属性
[XmlElement]public string SClass { get; set; }[XmlElement]public int Number { get; set; }}
第一步:将实体类序列化为XML文档,代码如下:
Student stu = new Student() { Age = 12, Number = 23, Name = "张三", SClass = "高一(2)班" };XmlSerializer ser = new XmlSerializer(typeof(Student));StringWriter writer = new StringWriter();ser.Serialize(writer,stu);MessageBox.Show(writer.ToString());
在弹出框,出现的结果是:
这样,我们就序列化成功了啊。。
第二步:现在我们来进行反序列化测试:
//将Xml反序列为Student对象StringReader reader = new StringReader(writer.ToString()); //Deserialize反序列化指定TextReader包含的Xml文档,当然,不仅仅可以是TextReader,还可以是Stream等等,具体看起构造函数参数即可知道Student stu2= (Student)ser.Deserialize(reader);
我们用上面得到XML数据进行反序列化测试。查看运行结果,ok的啦!
二、序列化列表
和上面一样,序列化学生列表(People类和Student类和上面代码一样)
List<Student> stuList = new List<Student>();stuList.Add(new Student() { Age = 10, Number = 1, Name = "Tom", SClass = "Class One" });stuList.Add(new Student() { Age = 11, Number = 2, Name = "Jay", SClass = "Class Two" });stuList.Add(new Student() { Age = 12, Number = 3, Name = "Pet", SClass = "Class One" });stuList.Add(new Student() { Age = 13, Number = 4, Name = "May", SClass = "Class Three" });stuList.Add(new Student() { Age = 14, Number = 5, Name = "Soy", SClass = "Class Two" });//序列化XmlSerializer ser = new XmlSerializer(typeof(List<Student>));StringWriter writer = new StringWriter(); //将学生列表序列化为Xml数据 ser.Serialize(writer, stuList); //反序列化 //要先将构造StringReader,作为Deserialize()的初始化参数StringReader reader = new StringReader(writer.ToString());//别忘了从Object到List<Student>,否则会报错。。List<Student> stuList2 = (List<Student>)ser.Deserialize(reader);
运行结果是(注意:根是ArrayOfStudent不是Student了):
三、序列化字典(键/值对)
在XmlSerializer中,不支持Dirctionary<>类型的对象,所以在序列化这种最常见类型的时候,只能按照它的格式先创建一个可以序列化的类型,然后,将数据存储在该可序列化的类型中,然后再进行序列化即可。
Dictionary<string, int> dic = new Dictionary<string, int>();dic.Add("第一",1);dic.Add("第二", 2);dic.Add("第三", 3);dic.Add("第四", 4);List<DictionaryList> dicList = new List<DictionaryList>(); foreach (var a in dic){DictionaryList dicl = new DictionaryList() { Name=a.Key, Value=a.Value};dicList.Add(dicl);} //序列化XmlSerializer ser = new XmlSerializer(typeof(List<DictionaryList>));StringWriter writer = new StringWriter(); //序列化为Xml数据 ser.Serialize(writer, dicList);MessageBox.Show(writer.ToString()); //反序列化StringReader reader = new StringReader(writer.ToString()); List<DictionaryList> stuList2 = (List<DictionaryList>)ser.Deserialize(reader);
运行结果是:
四、序列化图片
补充:XmlArray和XmlArrayItem的使用,用在数组中
先构造实体类:
[XmlRoot("cats")]public class CatCollection{[XmlArray("items"), XmlArrayItem("item")]public Cat[] Cats { get; set; }}//[XmlRoot("cat")] 加不加都无所谓的。public class Cat{//定义Color属性的序列化为cat节点的属性[XmlAttribute("color")]public string Color { get; set; }//要求不序列化Speed属性 [XmlIgnore]public int Speed { get; set; }//设置Saying属性序列化为Xml子元素[XmlElement("saying")]public string Saying { get; set; }}
现在,进行序列化:
//声明一个猫咪对象 var cWhite = new Cat { Color = "White", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" }; var cBlack = new Cat { Color = "Black", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite, cBlack } }; //序列化这个对象XmlSerializer serializer = new XmlSerializer(typeof(CatCollection));StringWriter writer = new StringWriter();serializer.Serialize(writer,cc);MessageBox.Show(writer.ToString());
运行结果是:
XmlSerializer内存泄漏问题:
多谢chenlulouis,仔细看了下msdn,确实存在泄漏的情况,msdn说明如下:
动态生成的程序集
为了提高性能,XML 序列化基础结构将动态生成程序集,以序列化和反序列化指定类型。此基础结构将查找并重复使用这些程序集。此行为仅在使用以下构造函数时发生:
XmlSerializer(Type) XmlSerializer.XmlSerializer(Type, String)
如果使用任何其他构造函数,则会生成同一程序集的多个版本,且绝不会被卸载,这将导致内存泄漏和性能降低。最简单的解决方案是使用先前提到的两个构造函数的其中一个。否则,必须在 Hashtable 中缓存程序集,如以下示例中所示。
也就是说我们在使用XmlSerializer序列化,初始化XmlSerializer对象时最好使用下面两个构造函数否则会引起内存泄漏。
XmlSerializer(Type) XmlSerializer.XmlSerializer(Type, String)
C#处理Xml的相关随笔:
/// <summary>/// 提供xml文档序列化 反序列化/// </summary>public sealed class EncodeHelper{/// <summary>/// 反序列化XML字符串为指定类型/// </summary>public static object Deserialize(string Xml, Type ThisType){XmlSerializer xmlSerializer = new XmlSerializer(ThisType);object result;try{using (StringReader stringReader = new StringReader(Xml)){result = xmlSerializer.Deserialize(stringReader);}}catch (Exception innerException){bool flag = false;if (Xml != null){if (Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()))){flag = true;}}throw new ApplicationException(string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}; Type: {2}.", Xml, flag, ThisType.FullName), innerException);}return result;}/// <summary>/// 序列化object对象为XML字符串/// </summary>public static string Serialize(object ObjectToSerialize){string result = null ;try{XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType());using (MemoryStream memoryStream = new MemoryStream()){XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false));xmlTextWriter.Formatting = Formatting.Indented;xmlSerializer.Serialize(xmlTextWriter, ObjectToSerialize);xmlTextWriter.Flush();xmlTextWriter.Close();UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true);result= uTF8Encoding.GetString(memoryStream.ToArray());}}catch (Exception innerException){throw new ApplicationException("Couldn't Serialize Object:" + ObjectToSerialize.GetType().Name, innerException);}return result;}}
参考博客:http://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html
http://hi.baidu.com/jackeyrain/item/79ad923564fa94f1e6bb7a11
http://www.cnblogs.com/John-Connor/archive/2012/04/12/2440352.html
转载于:https://www.cnblogs.com/itjeff/p/4262547.html
XML的序列化和反序列化 详细介绍相关推荐
- C#实现对象的Xml格式序列化及反序列化
要序列化的对象的类: [Serializable] public class Person { private string name; public string Name { get { retu ...
- jackson (json、xml的序列化与反序列化)
jackson用于java对象到json的序列化与反序列化.还支持xml格式. jackson用于实现json与java对象的序列与反序列化.web service要实现跨机器传送对象那么就需要有一种 ...
- C# XML的序列化与反序列化
主要2种方式1.BinaryFormatter 2.XmlSerializer 创建对象 [Serializable] //如果要想保存某个class中的字段,必须在class前面加个这样attri ...
- java对象的序列化和反序列化详细解释
java对象的序列化和反序列化是什么意思 1.序列化是干啥用的? 序列化的原本意图是希望对一个Java对象作一下"变换",变成字节序列,这样一来方便持久化存储到磁盘,避免程序运行结 ...
- python之序列化与反序列化用法介绍json、pickle
1.什么是序列化和反序列化 序列化就是将内存中的数据结构转换成一种中间格式存储到硬盘或者基于网络传输 反序列化就是硬盘中或者网络传来的一种数据格式转换成内存中数据结构 2.为啥有呢? 1.可以保存 ...
- 通过XmlSerializer 实现XML的序列化与反序列化
通过XmlSerializer 我们可以十分简单的将Model与XML进行转换 官文在点这里 帮助类 1 using System; 2 using System.Text; 3 using Syst ...
- Java XML解析: 序列化 反序列化
Java解析XML的类库很多,本文记录用XStream库对XML的处理 背景 实际开发中,应用报文的格式一般都是JSON和XML:JSON大家都很熟悉(优秀类库:GSON/FastJson/Jacks ...
- 序列化和反序列化(转)
转载:http://kb.cnblogs.com/page/515982/ 摘要 序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出 ...
- 序列化和反序列化--转
http://www.infoq.com/cn/articles/serialization-and-deserialization 简介 文章作者服务于美团推荐与个性化组,该组致力于为美团用户提供每 ...
最新文章
- 批处理 bat 提取项目war包
- Why product sales area is not replicated to CRM
- 对某机构为“转移内部矛盾”而嫁祸于我们的事件之真相大起底
- CVPR2020 | 华为GhostNet超越谷歌MobileNetV3
- c++中wstring 和 string的转换
- eclipse安装Freemaker IDE插件
- (办公)eclipse连接github cannot open git-upload-pack(git-receive-pack)
- 威马EX6 Plus探险之旅!房山郊区竟藏着个1万平超大废弃矿洞?
- 移动端点击链接元素出现蓝色边框或者出现半透明蓝色背景
- 理解Twisted与非阻塞编程
- python自动化面试提问_Python自动化测试笔试面试题精选
- LayaAir Geolocation 获取地理位置
- 用canvas画圆形图片
- 电机或编码器相关的 CW 与 CCW
- HTML学习日记-第二篇
- 数商云:补齐数字化短板,农林牧渔供应链升级执行“三步走”
- 袋鼠云数栈UI5.0体验升级背后的故事:可用性原则与交互升级
- 计算机女学霸,邹楚杭:计算机学院走出来的才女学霸
- 远程删除用户手机照片?拼多多回应
- 捷达vs7测试_捷达vs7碰撞测试成绩
热门文章
- 【LeetCode】617. 合并二叉树
- ExcelBDD-Java开源组件发布了!
- 云专网和云专线的区别_云专线的优势及应用场景
- springboot整合hibernate_峰哥说技术系列-17 .Spring Boot 整合 Spring Data JPA
- 【参会指南】神策 2020 数据驱动用户大会,10 月 13 日将重磅开幕!
- 【重磅】神策分析 1.13 版本上线 ,持续深耕打造场景化数据分析
- 吴恩达的 AI 战略强调了什么?
- css深入理解之overflow
- mybatis表关联彻底理解
- php pdo预处理语句与存储过程