浅谈XML与对象的序列化与反序列化

开发
今天我们将谈到XML与对象的序列化与反序列化。并且会附上一些简单的序列化与反序列化方法,供大家使用。

这篇文章主要讲述XML与对象的序列化与反序列化。并且会附上一些简单的序列化与反序列化方法,供大家使用。

假设我们在一个Web项目中有这样两个类

  1. public class Member   
  2. {  
  3.   public string Num { getset; }  
  4.   public string Name { getset; }  
  5. }  
  6. public class Team  
  7. {  
  8.    public  string Name;  
  9.    public  List<Member> Members { getset; }  

假设我们需要把Team类的一个实例POST到一个URL,

  当然,使用Form隐藏域提交就可以完成该功能。

  如果该Team包括30条数据呢?

  为了区分每个Member,我们得给参数的名字加上后缀。这就要一大串的隐藏域来完成:

  1. <!--使用Razor来演示-->@model Team  
  2. <form id="submitForm" action="http://www.johnconnor.com/team" method="post"> 
  3. <input type="hidden" name="TeamName" value="@Model.Name" /> 
  4. <input type="hidden" name="MemberNum1" value="@Model.Members[0].Num" /> 
  5. <input type="hidden" name="MemberName1" value="@Model.Members[0].Name" /> 
  6. ...<!--省略28X2个input标签--> 
  7. <input type="hidden" name="MemberNum30" value="@Model.Members[29].Num" /> 
  8. <input type="hidden" name="MemberName30" value="@Model.Members[29].Name" /> 
  9. </form> 
  10. <script type="text/javascript"> 
  11.     document.getElementById("submitForm").submit();  
  12. </script> 

  还敢想象一下如果Team再复杂一些,嵌套再多一些的情况么?

  呃,即使你愿意这么传数据,对方看到一坨参数名就够头疼了。

  我们都知道对象是不能在网络中直接传输的,不过还有补救的办法。

  XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储数据,任何一个对象都可以用XML来描述。以Team类为例:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  3.   <Name>Development</Name> 
  4.   <Members> 
  5.     <Member> 
  6.       <Num>001</Num> 
  7.       <Name>Marry</Name> 
  8.     </Member> 
  9.     <Member> 
  10.       <Num>002</Num> 
  11.       <Name>John</Name> 
  12.     </Member> 
  13.   </Members> 
  14. </Team> 

   这样一个XML文档就表示了Team一个实例。

  聪明的看官应该已经想到,XML是可以作为对象信息的载体在网络中传输,因为它是文本形式的。

  怎么进行XML文档与对象的相互转换呢?

  XmlSerializer类就是干这个活的。

      命名空间:System.Xml.Serialization

      程序集:System.Xml(在 system.xml.dll 中)

  现在这里展示了一个提供序列化与反序列化方法的EncodeHelper类。

  Deserialize方法将XML字符串转换为指定类型的对象;

  Serialize方法则将对象转换为XML字符串。

  1. /// <summary>  
  2.  /// 提供xml文档序列化 反序列化  
  3.  /// </summary>  
  4.  public sealed class EncodeHelper  
  5.  {  
  6.      /// <summary>  
  7.      /// 反序列化XML字符串为指定类型  
  8.      /// </summary>  
  9.      public static object Deserialize(string Xml, Type ThisType)  
  10.      {  
  11.          XmlSerializer xmlSerializer = new XmlSerializer(ThisType);  
  12.          object result;  
  13.          try 
  14.          {  
  15.              using (StringReader stringReader = new StringReader(Xml))  
  16.              {  
  17.                  result = xmlSerializer.Deserialize(stringReader);  
  18.              }  
  19.          }  
  20.          catch (Exception innerException)  
  21.          {  
  22.              bool flag = false;  
  23.              if (Xml != null)  
  24.              {  
  25.                  if (Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble())))  
  26.                  {  
  27.                      flag = true;  
  28.                  }  
  29.              }  
  30.              throw new ApplicationException(string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}; Type: {2}.",                 Xml, flag, ThisType.FullName), innerException);  
  31.          }  
  32.          return result;  
  33.      }  
  34.  
  35.      /// <summary>  
  36.      /// 序列化object对象为XML字符串  
  37.      /// </summary>  
  38.      public static string Serialize(object ObjectToSerialize)  
  39.      {  
  40.          string result = null ;  
  41.          try 
  42.          {  
  43.          XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType());  
  44.            
  45.          using (MemoryStream memoryStream = new MemoryStream())  
  46.          {  
  47.              XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false));  
  48.              xmlTextWriter.Formatting = Formatting.Indented;  
  49.              xmlSerializer.Serialize(xmlTextWriter, ObjectToSerialize);  
  50.              xmlTextWriter.Flush();  
  51.              xmlTextWriter.Close();  
  52.              UTF8Encoding uTF8Encoding = new UTF8Encoding(falsetrue);  
  53.              result= uTF8Encoding.GetString(memoryStream.ToArray());  
  54.          }  
  55.          }  
  56.          catch (Exception innerException)  
  57.          {  
  58.              throw new ApplicationException("Couldn't Serialize Object:" + ObjectToSerialize.GetType().Name, innerException);  
  59.          }  
  60.          return result;  
  61.      }  
  62.  } 

  要使用这个类需要添加以下引用

 

  1.   using System;  
  2.   using System.Text;  
  3.   using System.IO;  
  4.   using System.Xml;  
  5.   using System.Xml.Serialization; 

 

  下面我们用一个控制台程序来演示一下这个类是如何工作的。这里是程序的Main函数。

  1. static void Main(string[] args)  
  2.         {  
  3.             List<Member> Members = new List<Member>();  
  4.             Member member1 = new Member { Name = "Marry"Num = "001" };  
  5.             Member member2 = new Member { Name = "John"Num = "002" };  
  6.             Members.Add(member1);  
  7.             Members.Add(member2);  
  8.             Team team = new Team { Name = "Development"MembersMembers = Members };  
  9.             var xml =EncodeHelper.Serialize(team);//序列化  
  10.             Console.Write(xml);//打印序列化后的XML字符串  
  11.             Console.ReadLine();  
  12.             Team newTeam = EncodeHelper.Deserialize(xml, typeof(Team)) as Team;//反序列化时需要显式的进行类型转换  
  13.             Console.WriteLine("Team Name:"+newTeam.Name);//显示反序列化后的newTeam对象  
  14.             foreach (var member in newTeam.Members)  
  15.             {  
  16.                 Console.WriteLine("Member Num:" + member.Num);  
  17.                 Console.WriteLine("Member Name:" + member.Name);  
  18.             }  
  19.             Console.ReadLine();  
  20.         } 

  在执行完Console.Write(xml)这行代码后,就可以看到打印出来的XML文档了。

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  3.   <Name>Development</Name> 
  4.   <Members> 
  5.     <Member> 
  6.       <Num>001</Num> 
  7.       <Name>Marry</Name> 
  8.     </Member> 
  9.     <Member> 
  10.       <Num>002</Num> 
  11.       <Name>John</Name> 
  12.     </Member> 
  13.   </Members> 
  14. </Team> 

  与我在文章开头给出的例子是一模一样的。

  最终反序列化出来的newTeam对象打印出来是这样的结果。

  Team Name:Development

  Member Num:001

  Member Name:Marry

  Member Num:002

  Member Name:John

  回到我们开头的Web通信的例子,

  利用XML序列化与反序列化来进行对象传递,我们只需要把需要传递的对象序列化为XML字符串,使用一个隐藏域进行form提交就可以搞定咯!

  接收方再将接收到的XML字符串反序列化成预设的对象即可。前提是双方必须约定序列化与反序列化的过程一致,且对象相同。

  最后我们来看一下怎么利用一些特性来控制序列化与反序列化操作的过程。我们把开始的类改一下:

  1. public class Member  
  2.     {  
  3.         [XmlElement("Member_Num")]  
  4.         public string Num { get; set; }  
  5.         public string Name { get; set; }  
  6.     }  
  7.     [XmlRoot("Our_Team")]  
  8.     public class Team  
  9.     {  
  10.         [NonSerialized]public string Name;修正于2012-4-13        
  11. [XmlIgnore]public string Name;  
  12.         public List<Member> Members { get; set; }  
  13.     }  
  14.    
  15.  
  16. public class Member  
  17.     {  
  18.         [XmlElement("Member_Num")]  
  19.         public string Num { get; set; }  
  20.         public string Name { get; set; }  
  21.     }  
  22.     [XmlRoot("Our_Team")]  
  23.     public class Team  
  24.     {  
  25.         [NonSerialized]public string Name;修正于2012-4-13        
  26. [XmlIgnore]public string Name;  
  27.         public List<Member> Members { get; set; }  
  28.     } 

  然后我们再次执行刚才的控制台程序,序列化结果变成了这样:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <Our_Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  3.   <Name>Development</Name>修正于2012-4-13  
  4.   <Members> 
  5.     <Member> 
  6.       <Member_Num>001</Member_Num> 
  7.       <Name>Marry</Name> 
  8.     </Member> 
  9.     <Member> 
  10.       <Member_Num>002</Member_Num> 
  11.       <Name>John</Name> 
  12.     </Member> 
  13.   </Members> 
  14. </Our_Team> 

  本来的根节点Team变成了Our_Team,Member的子节点Num变成了Member_Num,并且Team的Name子节点被忽略了。

  可见特性XmlRoot可以控制根节点的显示和操作过程,XmlElement则针对子节点。如果某些成员被标记XmlIgnore NonSerialized修正于2012-4-13特性,则在序列化与反序列化过程中会被忽略

原文链接:http://www.cnblogs.com/John-Connor/archive/2012/04/12/2440352.html

【编辑推荐】

  1. XML之父解读未来互联网"游戏化"的三个真谛
  2. Ajax和Web服务数据格式:XML SOAP HTML
  3. 超强解析XML——简单直接的来
  4. 解析PHP中的XML数据
  5. 大话HTML DOM与XML DOM的区别与联系 
责任编辑:彭凡 来源: 博客园
相关推荐

2018-03-19 10:20:23

Java序列化反序列化

2011-06-01 15:05:02

序列化反序列化

2023-12-13 13:49:52

Python序列化模块

2009-09-09 15:47:27

XML序列化和反序列化

2009-09-09 14:45:41

XML序列化和反序列化

2011-05-18 15:20:13

XML

2022-08-06 08:41:18

序列化反序列化Hessian

2009-06-14 22:01:27

Java对象序列化反序列化

2009-08-24 17:14:08

C#序列化

2023-11-20 08:44:18

数据序列化反序列化

2009-08-06 11:16:25

C#序列化和反序列化

2019-11-20 10:07:23

web安全PHP序列化反序列化

2009-08-25 14:24:36

C#序列化和反序列化

2011-06-01 14:50:48

2013-03-11 13:55:03

JavaJSON

2021-11-18 07:39:41

Json 序列化Vue

2009-09-09 16:10:11

.NET序列化和反序列

2009-08-25 14:43:26

C#序列化和反序列化

2010-03-19 15:54:21

Java Socket

2009-07-29 13:39:02

JSON序列化和反序列ASP.NET AJA
点赞
收藏

51CTO技术栈公众号