转载自: https://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html
名称 | 描述 |
XmlAttribute | 表示一个特性对象的集合,这些对象控制XmlSerializer如何序列化和反序列化对象 |
XmlArrayAttribute | 指定XmlSerializer应将特定的类成员序列化为XML元素数组 |
XmlArrayItemAttribute | 指定XmlSerializer可以放置在序列化数组中的派生类型 |
XmlArrayItemAttributes | 表示XmlArrayItemAttribute对象的集合 |
XmlAttributeAttribute | 指定XmlSerializer应将类成员作为XML特性序列化 |
XmlChoiceIdentifierAttribute | 指定可以通过使用枚举来进一步消除成员的歧义 |
XmlElementAttribute | 在XmlSerializer序列化或反序列化包含对象时,指示公共字段或属性表示XML元素 |
XmlElementAttributes | 表示XmlElementAttribute的集合,XmlSerializer将其用于它重写序列化类的默认方式 |
XmlEnumAttribute | 控制XmlSerializer如何序列化枚举成员 |
XmlIgnoreAttribute | 指示XmlSerializer方法不序列化公共字段或公共读/写属性值 |
XmlIncludeAttribute | 允许XmlSerializer在它序列化或反序列化对象时识别类型 |
XmlRootAttribute | 控制视为XML根元素的属性目标的XML序列化 |
XmlTextAttribute | 当序列化或反序列化时,想XmlSerializer指示应将此成员作为XML文本处理 |
XmlTypeAttribute | 控制当属性目标由XmlSerializer序列化时生成的XML结构 |
XmlAnyAttributeAttribute | 指定成员(返回XmlAttribute对象的数组的字段)可以包含XML属性 |
XmlAnyElementAttribute | 指定成员可以包含对象,该对象表示在序列化或反序列化的对象中没有相应成员的所有XML元素 |
XmlAnyElementAttributes | 表示XmlAnyElementAttribute对象的集合 |
XmlAttributeEventArgs | 为UnKnowAttribute提供数据 |
XmlAttributeOverrides | 允许你在使用XmlSerializer序列化或反序列化时重写属性、字段和类特性 |
XmlElementEventArgs | 为UnknownElement事件提供数据 |
XmlNamespaceDeclarationsAttribute | 指定目标属性、参数、返回值或类成员包含与XML文档中所用命名空间关联的前缀 |
XmlNodeEventArgs | 为UnknownNode时间提供数据 |
XmlSerializer | 将对象序列化到XML文档中和从XML文档中反序列化对象,XmlSerializer使你得以控制如何将对象编码到XML中 |
XmlSerializerNamespaces | 包含XmlSerializer用于在XML文档实例中生成限定名的XML命名空间和前缀 |
XmlTypeMapping | 包含从一种类型到另一种类型的映射 |
这篇随笔对应的.Net命名空间是System.Xml.Serialization;文中的示例代码需要引用这个命名空间。
为什么要做序列化和反序列化?
.Net程序执行时,对象都驻留在内存中;内存中的对象如果需要传递给其他系统使用;或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化。
范围:本文只介绍xml序列化,其实序列化可以是二进制的序列化,也可以是其他格式的序列化。
看一段最简单的Xml序列化代码
1 2 3 4 5 6 7 8 9 10 11 12 |
|
上面代码对int i进行了序列化,并将序列化的结果输出到了控制台,输出结果如下
|
可以将上述序列化的xml进行反序列化,如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
以上代码用最简单的方式说明了xml序列化和反序列化的过程,.Net系统类库为我们做了大量的工作,序列化和反序列化都非常简单。但是在现实中业务需求往往比较复杂,不可能只简单的序列化一个int变量,显示中我们需要对复杂类型进行可控制的序列化。
自定义对象的Xml序列化:
System.Xml.Serialization命名空间中有一系列的特性类,用来控制复杂类型序列化的控制。例如XmlElementAttribute、XmlAttributeAttribute、XmlArrayAttribute、XmlArrayItemAttribute、XmlRootAttribute等等。
看一个小例子,有一个自定义类Cat,Cat类有三个属性分别为Color,Saying,Speed。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
可以使用XmlElement指定属性序列化为子节点(默认情况会序列化为子节点);或者使用XmlAttribute特性制定属性序列化为Xml节点的属性;还可以通过XmlIgnore特性修饰要求序列化程序不序列化修饰属性。
对象数组的Xml序列化:
数组的Xml序列化需要使用XmlArrayAttribute和XmlArrayItemAttribute;XmlArrayAttribute指定数组元素的Xml节点名,XmlArrayItemAttribute指定数组元素的Xml节点名。
如下代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
|
以上代码将输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
XmlSerializer内存泄漏问题:
多谢chenlulouis,仔细看了下msdn,确实存在泄漏的情况,msdn说明如下:
动态生成的程序集
为了提高性能,XML 序列化基础结构将动态生成程序集,以序列化和反序列化指定类型。此基础结构将查找并重复使用这些程序集。此行为仅在使用以下构造函数时发生:
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
如果使用任何其他构造函数,则会生成同一程序集的多个版本,且绝不会被卸载,这将导致内存泄漏和性能降低。最简单的解决方案是使用先前提到的两个构造函数的其中一个。否则,必须在 Hashtable 中缓存程序集,如以下示例中所示。
也就是说我们在使用XmlSerializer序列化,初始化XmlSerializer对象时最好使用下面两个构造函数否则会引起内存泄漏。
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)