文档章节

XML序列化和反序列化

文文1
 文文1
发布于 2015/09/12 16:26
字数 1148
阅读 595
收藏 10

在谈XML序列化之前,我们先来说说序列化。


序列化名词解释:序列化是将对象状态转换为可保持或传输的格式的过程。


与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。这就是序列化的意义所在。

我们可以把对象序列化为不同的格式,比如说,Json序列化、XML序列化、二进制序列化、SOAP序列化等,以上这些不同的格式也都是为了适应具体的业务需求。

在本篇文章中,我们就来分析一下XML的序列化和反序列化。我们先来看一个XML文件:

<?xml version="1.0" encoding="utf-8" ?>
<BaseInfo>
  <Person>
    <Name>小明</Name>
    <Age>16</Age>
    <Books>
      <Book>
        <ISBN>123</ISBN>
        <Title>借的书1</Title>
      </Book>
    </Books>
  </Person>
  <Person>
    <Name>小红</Name>
    <Age>18</Age>
    <Books>
      <Book>
        <ISBN>456</ISBN>
        <Title>借的书2</Title>
      </Book>
      <Book>
        <ISBN>789</ISBN>
        <Title>借的书3</Title>
      </Book>
    </Books>
  </Person>
</BaseInfo>

在这个文件中BaseInfo为该XML的跟节点,它的里面由多个Person节点组成,在Person节点中又包括Name、Age、Books节点,Books节点中又由多个Book组成,在Book中又包括ISBN和Title。


下面首先我们要做的是创建与该XML相对应的对象,然后把对象转换为上述XML(序列化),或者把上述XML转换为对象(反序列化)。下面的例子中只是把XML存到本地,再从本地读取出来,如果需要在网络中传输,应该添加Serializable属性,我们先来创建对象。

using System.Xml.Serialization;
public class BaseInfo
{
   List<Person> perList = new List<Person>();
 
   [XmlElement(ElementName="Person")]
    public List<Person> PerList
    {
       get { return perList; }
       set { perList = value; }
    }
}

使用XML序列化需要引入命名空间System.Xml.Serialization。我们创建的类名称为BaseInfo,这里与XML的跟节点需要对应,当然我们也可以指定该类转换为XML时映射成的名称,这里可以使用XmlRoot中的ElementName来指定它的名称,就像该类中的属性PerList那样应用,当然你也可以使用比较省事的方法,类的名称和XML节点的名称相同即可,就像该例子中一样。在BaseInfo类中,我们维护了一个PerList它是一个Person对象的集合,当然这个属性的名称并不与XML文件中的对应,所以要更改它的名称为Person。


好,接下来我们看看Person类:

using System.Xml.Serialization;
public class Person
{
     string name;
     int age;
     List<Books> bookList=new List<Books>();
 
     /// <summary>
     /// 必须有默认的构造函数
     /// </summary>
     public Person()
     { }
 
     public Person(string name, int age)
     {
         this.name = name;
         this.age = age;
     }
 
     public string Name
     {
         get { return name; }
         set { name = value; }
     }
 
     public int Age
     {
         get { return age; }
         set { age = value; }
     }
 
     [XmlElement(ElementName = "Books")]
     public List<Books> BookList
     {
         get { return bookList; }
         set { bookList = value; }
     }
 }

在该类中有Name和Age,还有维护了一个Books对象。


我们再来看看Books:

using System.Xml.Serialization;
public class Books
{
    List<Book> bookList = new List<Book>();
 
    [XmlElement(ElementName = "Book")]
    public List<Book> BookList
    {
        get { return bookList; }
        set { bookList = value; }
    }
}

Books的作用就像是一个过渡的类,只为了与XML中的节点Books对应,在该类中维护了Book类的对象集合。


那么,最后我们来看Book类:

using System.Xml.Serialization;
public class Book
{
    string isbn;
    string title;
 
    public Book() { }
 
    public Book(string isbn, string title)
    {
        this.isbn = isbn;
        this.title = title;
    }
 
    public string ISBN
    {
        get { return isbn; }
        set { isbn = value; }
    }
  
    public string Title
    {
        get { return title; }
        set { title = value; }
    }   
}

好了,这样我们需要的类也就都创建完了,虽说创建类的过程有些繁杂,但是有了这些类,我们也就不用一个一个处理XML的节点了。我们创建一个简单的控制台程序,在里面添加两个处理方法,第一个是序列化方法:

public static void xmlSerialize()
{
    Book b1 = new Book("111","书1");
    Book b2 = new Book("222","书2");
    Book b3 = new Book("333","书3");
    Books bs1 = new Books();
    Books bs2 = new Books();
    bs1.BookList.Add(b1);
    bs1.BookList.Add(b2);
    bs2.BookList.Add(b3);
    Person p1 = new Person("张三", 11);
    Person p2 = new Person("李四", 22);
    p1.BookList.Add(bs1);
    p2.BookList.Add(bs2);
    BaseInfo baseInfo = new BaseInfo();
    baseInfo.PerList.Add(p1);
    baseInfo.PerList.Add(p2);
 
    StringWriter sw = new StringWriter();
    //创建XML命名空间
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("","");
    XmlSerializer serializer = new XmlSerializer(typeof(BaseInfo));
    serializer.Serialize(sw, baseInfo, ns);
    sw.Close();
 
    Console.Write(sw.ToString());
}

调用该方法运行效果:

1


第二个是反序列化方法:

public static void xmlDeserialize()
{
    //xml来源可能是外部文件,也可能是从其他系统获得
    FileStream file = new FileStream(@"http://www.cnblogs.com/info.xml", FileMode.Open, FileAccess.Read);
    XmlSerializer xmlSearializer = new XmlSerializer(typeof(BaseInfo));
    BaseInfo info = (BaseInfo)xmlSearializer.Deserialize(file);
    file.Close();
    foreach (Person per in info.PerList)
    {
        Console.WriteLine("人员:");
        Console.WriteLine(" 姓名:" + per.Name);
        Console.WriteLine(" 年龄:" + per.Age);
        foreach (Books b1 in per.BookList)
        {
            foreach (Book b in b1.BookList)
            {
                Console.WriteLine(" 书:");
                Console.WriteLine("     ISBN:" + b.ISBN);
                Console.WriteLine("     书名:" + b.Title);
            }
        }
    }
}

 

调用该方法运行效果:

2

本文转载自:

文文1
粉丝 25
博文 454
码字总数 143313
作品 0
长沙
程序员
私信 提问
加载中

评论(2)

文文1
文文1 博主

引用来自“老张大哥”的评论

c#不错

13
老张大哥
老张大哥
c#不错
C# xml和对象的序列化与反序列化

为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中;内存中的对象如果需要传递给其他系统使用;或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化。...

KavenSu
2014/02/21
652
0
WCF技术剖析之十六:数据契约的等效性和版本控制

数据契约是对用于交换的数据结构的描述,是数据序列化和反序列化的依据。在一个WCF应用中,客户端和服务端必须通过等效的数据契约方能进行有效的数据交换。随着时间的推移,不可避免地,我们...

长平狐
2012/09/04
72
0
XmlSerializer 对象的Xml序列化和反序列化

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

长平狐
2012/06/08
227
0
.NET 中的序列化 & 反序列化

序列化:将对象的状态信息及类型信息,转换为一种易于传输或存储形式(流,即字节序列)的过程。 下图为序列化过程图示,图片来自微软官方文档: 反序列化:与序列化相反,将流转换为对象的过...

雪飞鸿
01/28
0
0
.NET高级代码审计(第六课) DataContractSerializer反序列化漏洞

原文来自安全客,作者:Ivan1ee@360云影实验室 原文链接:https://www.anquanke.com/post/id/175796 相关阅读: 《.NET 高级代码审计(第一课)XmlSerializer 反序列化漏洞》 《.NET 高级代码...

安全客
04/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

记一次项目启动报java.lang.StackOverflowError

项目是spring boot,之前没有问题,突然有一次debug方式启动的时候报这个错误。 因为其他同事没有问题,线上也没有问题,所以先排除了是代码问题。 开始以为电脑开的软件太多,然后给jvm的内存...

chro008
1分钟前
3
0
idea 2019.2免费激活码

亲测有效到2020.6 812LFWMRSH-eyJsaWNlbnNlSWQiOiI4MTJMRldNUlNIIiwibGljZW5zZWVOYW1lIjoi5q2j54mIIOaOiOadgyIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb......

Iverson58
9分钟前
3
0
移动APP开发中的重要注意事项

您的移动app在变化吗?如果没有,请确保遵循这些提示进行移动app开发。大多数行业的IT领导者都优先考虑劳动力和消费者的移动性。实现成功的移动app开发具有挑战性,涉及在app功能开发的基础上...

a429011717
16分钟前
4
0
Qt编写自定义控件69-代码行数统计

一、前言 代码行数统计主要用来统计项目中的所有文件的代码行数,其中包括空行、注释行、代码行,可以指定过滤拓展名,比如只想统计.cpp的文件,也可以指定文件或者指定目录进行统计。写完这...

飞扬青云
34分钟前
9
0
驰骋工作流引擎-ccflow关于 “ 是否自动计算未来的处理人”的功能变更

关键字:流程未来节点处理人 工作流快速开发平台 工作流流设计 业务流程管理 asp.net 开源工作流 业务背景:一个流程在启动起来后,是可以对一些节点计算出来处理人是谁,流程的走向。对于另...

孟娟
50分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部