http://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html

这篇随笔对应的.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 { getset; }
 
        //要求不序列化Speed属性
        [XmlIgnore]
        public int Speed { getset; }
 
        //设置Saying属性序列化为Xml子元素
        [XmlElement("saying")]
        public string Saying { getset; }
    }
}

可以使用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 { getset; }
    }
 
    [XmlRoot("cat")]
    public class Cat
    {
        //定义Color属性的序列化为cat节点的属性
        [XmlAttribute("color")]
        public string Color { getset; }
 
        //要求不序列化Speed属性
        [XmlIgnore]
        public int Speed { getset; }
 
        //设置Saying属性序列化为Xml子元素
        [XmlElement("saying")]
        public string Saying { getset; }
    }
}

以上代码将输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="gb2312"?>
<cats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://ww
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)

 

XmlSerializer 对象的Xml序列化和反序列化的更多相关文章

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

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

  2. C#操作Xml:XmlSerializer 对象的Xml序列化和反序列化

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

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

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

  4. .NET中XML序列化和反序列化常用类和用来控制XML序列化的属性总结(XmlSerializer,XmlTypeAttribute,XmlElementAttribute,XmlAttributeAttribute,XmlArrayAttribute...)

    序列化和反序列化是指什么? 序列化(seriallization): 将对象转化为便于传输的数据格式, 常见的序列化格式:二进制格式,字节数组,json字符串,xml字符串.反序列化(deserial ...

  5. 将对象xml序列化和反序列化

    //将一个对象按XML序列化的方式写入到一个文件,使用的默认的UTF8编码格式 //o为要序列化的对象 //path保存文件的路径 public static object  _lockObj=new ...

  6. XML序列化和反序列化

    上篇总结了下JSON的序列化和反序列化,博园中大牛给了很多牛叉的评论,学习了不少. 不过在上篇中忘了把json序列化和反序列化的另外一种方式写上去了,这里做个简单的补充: Json篇:http://w ...

  7. XML 序列化与反序列化

    XML序列化与反序列化 1.将一个类转化为XML文件 /// <summary> /// 对象序列化成XML文件 /// </summary> /// <param na ...

  8. XML序列化与反序列化

    public static class XmlHelper { private static void XmlSerializeInternal(Stream stream, object o, En ...

  9. c# XML序列化与反序列化

    c# XML序列化与反序列化 原先一直用BinaryFormatter来序列化挺好,可是最近发现在WinCE下是没有办法进行BinaryFormatter操作,很不爽,只能改成了BinaryWrite ...

随机推荐

  1. Write on ……… failed: 112(failed to retrieve text for this error. Reason: 15105)

    早上检查数据库的备份邮件时,发现一台Microsoft SQL Server 2008 R2 (SP2)数据库的Maintenance Report有错误 在SSMS里面执行Exec YourSQLD ...

  2. sp_configure错误:不支持对系统目录进行即席更新。

    今天在一台数据库服务器上(Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64)     Standard Edition (64-bit))使 ...

  3. PHP中require和include路径问题总结

    1 绝对路径.相对路径和未确定路径 相对路径 相对路径指以.开头的路径,例如 ./a/a.php (相对当前目录) ../common.inc.php (相对上级目录), 绝对路径 绝对路径是以 / ...

  4. SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 邮件作为一种非常便利的预警实现方式,在及时性和易用性 ...

  5. Shelve Instance 操作详解 - 每天5分钟玩转 OpenStack(38)

    Instance 被 Suspend 后虽然处于 Shut Down 状态,但 Hypervisor 依然在宿主机上为其预留了资源,以便在以后能够成功 Resume. 如果希望释放这些预留资源,可以使 ...

  6. jQuery 3.0 的 setter/getter 模式

    jQuery 的 setter/getter 共用一个函数,通过是否传参来表明它是何种意义.简单说传参它是 setter,不传它是 getter. 一个函数具有多种意义在编程语言中并不罕见,比如函数重 ...

  7. awk-实践

    实际中遇到的问题 字符串截取函数 substr #!/usr/bin/awk #author:zhaoyingnan #filename:substr.awk #substr 函数 #|awk -f ...

  8. 每天一个linux命令(2):cd命令

    1. 命令格式: cd [目录名] 2. 命令功能: 切换当前目录至dirName 3. 常用范例 3.1 例一:进入系统根目录 命令: cd / 输出: [root@localhost ~]# cd ...

  9. css 使容器宽度适应内容宽

    p{ width:intrinsic; width: -moz-max-content; width: -webkit-max-content; float:right; width:auto; /* ...

  10. 使用Struts框架,实现用户登陆功能

    前言:本篇文章是本人这周学习的一个小结,在自我总结的同时,希望也能够给其他同学带来一点帮助.本文主要知识是参照书本上的知识点以及网上其他博客文章,在上机操练后的所得,具体源码主要来自http://bl ...