这篇随笔对应的.Net命名空间是System.Xml.Serialization;文中的示例代码需要引用这个命名空间。
为什么要做序列化和反序列化?
.Net程序执行时,对象都驻留在内存中;内存中的对象如果需要传递给其他系统使用;或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化。
范围:本文只介绍xml序列化,其实序列化可以是二进制的序列化,也可以是其他格式的序列化。
看一段最简单的Xml序列化代码
1
2
3
4
5
6
7
8
9
10
11
12
class Program
{
    static void Main(string[] args)
    {
        int i = 10;
        //声明Xml序列化对象实例serializer
        XmlSerializer serializer = new XmlSerializer(typeof(int));
        //执行序列化并将序列化结果输出到控制台
        serializer.Serialize(Console.Out, i);
        Console.Read();
    }
}

上面代码对int i进行了序列化,并将序列化的结果输出到了控制台,输出结果如下

<?xml version="1.0" encoding="gb2312"?>
<int>10</int>

可以将上述序列化的xml进行反序列化,如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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));
        //反序列化,并将反序列化结果值赋给变量i
        int i = (int)serializer.Deserialize(rdr);
        //输出反序列化结果
        Console.WriteLine("i = " + i);
        Console.Read();
    }
}

以上代码用最简单的方式说明了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
namespace UseXmlSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            //声明一个猫咪对象
            var c = new Cat { Color = "White", Speed = 10, Saying = "White or black,  so long as the cat can catch mice,  it is a good cat" };
 
            //序列化这个对象
            XmlSerializer serializer = new XmlSerializer(typeof(Cat));
 
            //将对象序列化输出到控制台
            serializer.Serialize(Console.Out, c);
 
            Console.Read();
        }
    }
 
    [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; }
    }
}

可以使用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
/*玉开技术博客 http://www.cnblogs.com/yukaizhao */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
 
namespace UseXmlSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            //声明一个猫咪对象
            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));
 
            //将对象序列化输出到控制台
            serializer.Serialize(Console.Out, cc);
 
            Console.Read();
        }
    }
 
    [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; }
    }
}

以上代码将输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="gb2312"?>
w.w3.org/2001/XMLSchema">
  <items>
    <item color="White">
      <saying>White or black,  so long as the cat can catch mice,  it is a good
cat</saying>
    </item>
    <item color="Black">
      <saying>White or black,  so long as the cat can catch mice,  it is a good
cat</saying>
    </item>
  </items>
</cats>

XmlSerializer内存泄漏问题:

多谢chenlulouis,仔细看了下msdn,确实存在泄漏的情况,msdn说明如下:

动态生成的程序集

为了提高性能,XML 序列化基础结构将动态生成程序集,以序列化和反序列化指定类型。此基础结构将查找并重复使用这些程序集。此行为仅在使用以下构造函数时发生:

XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)

如果使用任何其他构造函数,则会生成同一程序集的多个版本,且绝不会被卸载,这将导致内存泄漏和性能降低。最简单的解决方案是使用先前提到的两个构造函数的其中一个。否则,必须在 Hashtable 中缓存程序集,如以下示例中所示。

也就是说我们在使用XmlSerializer序列化,初始化XmlSerializer对象时最好使用下面两个构造函数否则会引起内存泄漏。
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)

C#处理Xml的相关随笔:

C#操作Xml:XmlSerializer 对象的Xml序列化和反序列化的更多相关文章

  1. C#中XML与对象之间的序列化、反序列化

    直接上代码: using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serializ ...

  2. XPatchLib 对象增量数据序列化及反序列化器 For .Net

    在日常的软件开发和使用过程中,我们发现同一套系统的同一配置项在不同的客户环境中是存在各种各样的差异的.在差异较为分散时,如何较好的管理这些差异,使得维护过程能够更加安全和快速,一直在这样那样的困扰着开 ...

  3. 序列化对象C++对象的JSON序列化与反序列化探索

    新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正 一:背景 作为一名C++开发人员,我始终很期待能够像C#与JAVA那样,可以省力的进行对象的序列化与反序列化,但到现在为止,还没有找 ...

  4. C++对象的JSON序列化与反序列化探索完结-列表的序列化与反序列化

    在前两篇文章中,我们已经完成对普通对象以及复杂对象嵌套的序列化与反序列化,见如下地址: C++对象的JSON序列化与反序列化探索 C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化 ...

  5. C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化

    本文是基本上一篇博文进行改进而成,上一篇请见: C++对象的JSON序列化与反序列化探索 此处就不多说了,直接上代码. 1. 序列化基类 #pragma once #include <strin ...

  6. C++对象的JSON序列化与反序列化探索

    一:背景 作为一名C++开发人员,我一直很期待能够像C#与JAVA那样,可以轻松的进行对象的序列化与反序列化,但到目前为止,尚未找到相对完美的解决方案. 本文旨在抛砖引玉,期待有更好的解决方案:同时向 ...

  7. XmlSerializer 对象的Xml序列化和反序列化

    http://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html 这篇随笔对应的.Net命名空间是System.Xm ...

  8. XmlSerializer 对象的Xml序列化和反序列化,XMLROOT别名设置

    这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间.   为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中 ...

  9. 用C#实现XML和实体类之间序列化和反序列化相互转换

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

随机推荐

  1. OTN&互换amp; P-OTN有效降低100G 网络成本 (两)

    OTN互换& P-OTN有效降低100G 网络成本 (两) 在全球范围内.网流量的增长速度是空前的,导致此现象的缘由包含云服务的增长.移动宽带和基于互联网的视频点播服务的增长. Cisco估计 ...

  2. Appium0.18.x迁移到Appium1.x须知事项(灰常实用,解答了本人几个疑问)

    英文原版:https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/migrating-to-1-0.md Migr ...

  3. ajax jsonp跨域

    js跨域问题是指:js不同域进行数据传输或通信之间,让我们用ajax到不同的域请求数据.或js获得在不同领域的框架页(iframe)数据.只有到协议.域名.port无论是有不同的.它们被认为是不同的域 ...

  4. linux于test 订购具体解释

    測试标志 代表意义 文件名称.文件类型 -e 该文件名称是否存在 -f 该文件名称是否存在且为file -d 该文件名称是否存在且为文件夹 -b 该文件名称是否存在且为一个block -c 该文件名称 ...

  5. xml在此生活

    小编尾随学习的步伐.今天小编简要概述xml在此生活,xml她的百度百科这一解释:可扩展标记语言 (ExtensibleMarkup Language, XML).用于标记电子文件使其具有结构性的标记语 ...

  6. nodeJs基础

    Node.js 是一个基于Chrome JavaScript 执行时建立的一个平台, 用来方便地搭建高速的 易于扩展的网络应用· Node.js 借助事件驱动, 非堵塞I/O 模型变得轻量和高效, 很 ...

  7. StackExchange.Redis 使用-同步 异步 即发即弃 (三)

    访问单个服务器 有时候需要为单个服务器指定特定的命令 . IServer server = redis.GetServer("localhost", 6379); GetServe ...

  8. 【高德地图API】从头德国高中生JS API(三)覆盖物——大喊|折线|多边形|信息表|聚合marker|点蚀图|照片覆盖

    覆盖物,是一张地图的灵魂.有覆盖物的地图.才是完整的地图.在一张地图上,除了底层的底图(瓦片图,矢量图),控件(有功能可操作的工具).最重要最必不可少的就是覆盖物了.覆盖物有多种.包含.标注.折线.多 ...

  9. ASP.NET 异步编程

    ASP.NET 异步编程 相关博文: 异步编程 In .NET(回味无穷!!!) ASP.NET sync over async(异步中同步,什么鬼?) 本来这篇博文想探讨下异步中的异常操作,但自己在 ...

  10. mfc 链接时错误 文件函数重复定义

    我在HeaderFile里新建了一个函数,然后在程序里调用,一直出现这个错误,说这个函数重复定义, 发现是VS自动加到External dependencies里面了.把HeaderFile里的函数文 ...