深入理解:XML与对象的序列化与反序列化
2015-01-24信息快讯网
本篇文章是对XML与对象的序列化与反序列化进行了详细的分析介绍,需要的朋友参考下
这篇文章主要讲述XML与对象的序列化与反序列化。并且会附上一些简单的序列化与反序列化方法,供大家使用。
假设我们在一个Web项目中有这样两个类
public class Member { public string Num { get; set; } public string Name { get; set; } } public class Team { public string Name; public List<Member> Members { get; set; } }
假设我们需要把Team类的一个实例POST到一个URL,
当然,使用Form隐藏域提交就可以完成该功能。
如果该Team包括30条数据呢?
为了区分每个Member,我们得给参数的名字加上后缀。这就要一大串的隐藏域来完成:
<!--使用Razor来演示--> @model Team <form id="submitForm" action="http://www.johnconnor.com/team" method="post"> <input type="hidden" name="TeamName" value="@Model.Name" /> <input type="hidden" name="MemberNum1" value="@Model.Members[0].Num" /> <input type="hidden" name="MemberName1" value="@Model.Members[0].Name" /> ... <!--省略28X2个input标签--> <input type="hidden" name="MemberNum30" value="@Model.Members[29].Num" /> <input type="hidden" name="MemberName30" value="@Model.Members[29].Name" /> </form> <script type="text/javascript"> document.getElementById("submitForm").submit(); </script>
还敢想象一下如果Team再复杂一些,嵌套再多一些的情况么?
呃,即使你愿意这么传数据,对方看到一坨参数名就够头疼了。
我们都知道对象是不能在网络中直接传输的,不过还有补救的办法。
XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储数据,任何一个对象都可以用XML来描述。以Team类为例:
<?xml version="1.0" encoding="utf-8"?> <Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Name>Development</Name> <Members> <Member> <Num>001</Num> <Name>Marry</Name> </Member> <Member> <Num>002</Num> <Name>John</Name> </Member> </Members> </Team>
这样一个XML文档就表示了Team一个实例。
聪明的看官应该已经想到,XML是可以作为对象信息的载体在网络中传输,因为它是文本形式的。
怎么进行XML文档与对象的相互转换呢?
XmlSerializer类就是干这个活的。
命名空间:System.Xml.Serialization
程序集:System.Xml(在 system.xml.dll 中)
现在这里展示了一个提供序列化与反序列化方法的EncodeHelper类。
Deserialize方法将XML字符串转换为指定类型的对象;
Serialize方法则将对象转换为XML字符串。
/// <summary> /// 提供xml文档序列化 反序列化 /// </summary> public sealed class EncodeHelper { /// <summary> /// 反序列化XML字符串为指定类型 /// </summary> public static object Deserialize(string Xml, Type ThisType) { XmlSerializer xmlSerializer = new XmlSerializer(ThisType); object result; try { using (StringReader stringReader = new StringReader(Xml)) { result = xmlSerializer.Deserialize(stringReader); } } catch (Exception innerException) { bool flag = false; if (Xml != null) { if (Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()))) { flag = true; } } throw new ApplicationException(string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}; Type: {2}.", Xml, flag, ThisType.FullName), innerException); } return result; } /// <summary> /// 序列化object对象为XML字符串 /// </summary> public static string Serialize(object ObjectToSerialize) { string result = null ; try { XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType()); using (MemoryStream memoryStream = new MemoryStream()) { XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false)); xmlTextWriter.Formatting = Formatting.Indented; xmlSerializer.Serialize(xmlTextWriter, ObjectToSerialize); xmlTextWriter.Flush(); xmlTextWriter.Close(); UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true); result= uTF8Encoding.GetString(memoryStream.ToArray()); } } catch (Exception innerException) { throw new ApplicationException("Couldn't Serialize Object:" + ObjectToSerialize.GetType().Name, innerException); } return result; } }
要使用这个类需要添加以下引用
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
下面我们用一个控制台程序来演示一下这个类是如何工作的。这里是程序的Main函数。
static void Main(string[] args) { List<Member> Members = new List<Member>(); Member member1 = new Member { Name = "Marry", Num = "001" }; Member member2 = new Member { Name = "John", Num = "002" }; Members.Add(member1); Members.Add(member2); Team team = new Team { Name = "Development", Members = Members }; var xml =EncodeHelper.Serialize(team);//序列化 Console.Write(xml);//打印序列化后的XML字符串 Console.ReadLine(); Team newTeam = EncodeHelper.Deserialize(xml, typeof(Team)) as Team;//反序列化时需要显式的进行类型转换 Console.WriteLine("Team Name:"+newTeam.Name);//显示反序列化后的newTeam对象 foreach (var member in newTeam.Members) { Console.WriteLine("Member Num:" + member.Num); Console.WriteLine("Member Name:" + member.Name); } Console.ReadLine(); }
在执行完Console.Write(xml)这行代码后,就可以看到打印出来的XML文档了。
<?xml version="1.0" encoding="utf-8"?> <Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Name>Development</Name> <Members> <Member> <Num>001</Num> <Name>Marry</Name> </Member> <Member> <Num>002</Num> <Name>John</Name> </Member> </Members> </Team>
与我在文章开头给出的例子是一模一样的。
最终反序列化出来的newTeam对象打印出来是这样的结果。
Team Name:Development
Member Num:001
Member Name:Marry
Member Num:002
Member Name:John
回到我们开头的Web通信的例子,
利用XML序列化与反序列化来进行对象传递,我们只需要把需要传递的对象序列化为XML字符串,使用一个隐藏域进行form提交就可以搞定咯!
接收方再将接收到的XML字符串反序列化成预设的对象即可。前提是双方必须约定序列化与反序列化的过程一致,且对象相同。
最后我们来看一下怎么利用一些特性来控制序列化与反序列化操作的过程。我们把开始的类改一下:
public class Member { [XmlElement("Member_Num")] public string Num { get; set; } public string Name { get; set; } } [XmlRoot("Our_Team")] public class Team { [XmlIgnore]public string Name; public List<Member> Members { get; set; } }
然后我们再次执行刚才的控制台程序,序列化结果变成了这样:
<?xml version="1.0" encoding="utf-8"?> <Our_Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Members> <Member> <Member_Num>001</Member_Num> <Name>Marry</Name> </Member> <Member> <Member_Num>002</Member_Num> <Name>John</Name> </Member> </Members> </Our_Team>
本来的根节点Team变成了Our_Team,Member的子节点Num变成了Member_Num,并且Team的Name子节点被忽略了。
可见特性XmlRoot可以控制根节点的显示和操作过程,XmlElement则针对子节点。如果某些成员被标记XmlIgnore,则在序列化与反序列化过程中会被忽略。
这些特性的具体内容可以在MSDN查看,就不多讲了。
有了这些知识,在网络中传递对象数据应该已经难不倒各位看官了把。^_^
php解析xml提示Invalid byte 1 of 1-byte UTF-8 sequence错误的处理方法
PHP将XML转数组过程详解
PHP生成sitemap.xml地图函数
php json与xml序列化/反序列化
php操作xml
php中如何使对象可以像数组一样进行foreach循环
php多层数组与对象的转换实例代码
浅析php面向对象public private protected 访问修饰符
解析PHP将对象转换成数组的方法(兼容多维数组类型)
PHP在不同页面间传递Json数据示例代码
探讨:使用XMLSerialize 序列化与反序列化
探讨如何使用SimpleXML函数来加载和解析XML文档
php之XML转数组函数的详解
基于PHP对XML的操作详解
php xml常用函数的集合(比较详细)
解析PHP多种序列化与反序列化的方法
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
深入分析php之面向对象
PHP笔记之:基于面向对象设计的详解
基于PHP 面向对象之成员方法详解
php中serialize序列化与json性能测试的示例分析
php学习笔记之面向对象编程
php中显示数组与对象的实现代码