深入理解:XML与对象的序列化与反序列化
2023-06-13 09:15:01 时间
这篇文章主要讲述XML与对象的序列化与反序列化。并且会附上一些简单的序列化与反序列化方法,供大家使用。
假设我们在一个Web项目中有这样两个类
publicclassMember
{
publicstringNum{get;set;}
publicstringName{get;set;}
}
publicclassTeam
{
public stringName;
public List<Member>Members{get;set;}
}
假设我们需要把Team类的一个实例POST到一个URL,
当然,使用Form隐藏域提交就可以完成该功能。
<!--使用Razor来演示-->
@modelTeam
<formid="submitForm"action="http://www.johnconnor.com/team"method="post">
<inputtype="hidden"name="TeamName"value="@Model.Name"/>
<inputtype="hidden"name="MemberNum1"value="@Model.Members[0].Num"/>
<inputtype="hidden"name="MemberName1"value="@Model.Members[0].Name"/>
...
<!--省略28X2个input标签-->
<inputtype="hidden"name="MemberNum30"value="@Model.Members[29].Num"/>
<inputtype="hidden"name="MemberName30"value="@Model.Members[29].Name"/>
</form>
<scripttype="text/javascript">
document.getElementById("submitForm").submit();
</script>
还敢想象一下如果Team再复杂一些,嵌套再多一些的情况么?
呃,即使你愿意这么传数据,对方看到一坨参数名就够头疼了。
我们都知道对象是不能在网络中直接传输的,不过还有补救的办法。
<?xmlversion="1.0"encoding="utf-8"?>
<Teamxmlns: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(在system.xml.dll中)
现在这里展示了一个提供序列化与反序列化方法的EncodeHelper类。
Deserialize方法将XML字符串转换为指定类型的对象;
Serialize方法则将对象转换为XML字符串。
///<summary>
///提供xml文档序列化反序列化
///</summary>
publicsealedclassEncodeHelper
{
///<summary>
///反序列化XML字符串为指定类型
///</summary>
publicstaticobjectDeserialize(stringXml,TypeThisType)
{
XmlSerializerxmlSerializer=newXmlSerializer(ThisType);
objectresult;
try
{
using(StringReaderstringReader=newStringReader(Xml))
{
result=xmlSerializer.Deserialize(stringReader);
}
}
catch(ExceptioninnerException)
{
boolflag=false;
if(Xml!=null)
{
if(Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble())))
{
flag=true;
}
}
thrownewApplicationException(string.Format("Couldn"tparseXML:"{0}";ContainsBOM:{1};Type:{2}.",
Xml,flag,ThisType.FullName),innerException);
}
returnresult;
}
///<summary>
///序列化object对象为XML字符串
///</summary>
publicstaticstringSerialize(objectObjectToSerialize)
{
stringresult=null;
try
{
XmlSerializerxmlSerializer=newXmlSerializer(ObjectToSerialize.GetType());
using(MemoryStreammemoryStream=newMemoryStream())
{
XmlTextWriterxmlTextWriter=newXmlTextWriter(memoryStream,newUTF8Encoding(false));
xmlTextWriter.Formatting=Formatting.Indented;
xmlSerializer.Serialize(xmlTextWriter,ObjectToSerialize);
xmlTextWriter.Flush();
xmlTextWriter.Close();
UTF8EncodinguTF8Encoding=newUTF8Encoding(false,true);
result=uTF8Encoding.GetString(memoryStream.ToArray());
}
}
catch(ExceptioninnerException)
{
thrownewApplicationException("Couldn"tSerializeObject:"+ObjectToSerialize.GetType().Name,innerException);
}
returnresult;
}
}
要使用这个类需要添加以下引用
usingSystem.Text;
usingSystem.IO;
usingSystem.Xml;
usingSystem.Xml.Serialization;
下面我们用一个控制台程序来演示一下这个类是如何工作的。这里是程序的Main函数。
staticvoidMain(string[]args)
{
List<Member>Members=newList<Member>();
Membermember1=newMember{Name="Marry",Num="001"};
Membermember2=newMember{Name="John",Num="002"};
Members.Add(member1);
Members.Add(member2);
Teamteam=newTeam{Name="Development",Members=Members};
varxml=EncodeHelper.Serialize(team);//序列化
Console.Write(xml);//打印序列化后的XML字符串
Console.ReadLine();
TeamnewTeam=EncodeHelper.Deserialize(xml,typeof(Team))asTeam;//反序列化时需要显式的进行类型转换
Console.WriteLine("TeamName:"+newTeam.Name);//显示反序列化后的newTeam对象
foreach(varmemberinnewTeam.Members)
{
Console.WriteLine("MemberNum:"+member.Num);
Console.WriteLine("MemberName:"+member.Name);
}
Console.ReadLine();
}
在执行完Console.Write(xml)这行代码后,就可以看到打印出来的XML文档了。
<?xmlversion="1.0"encoding="utf-8"?>
<Teamxmlns: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对象打印出来是这样的结果。
MemberNum:001
MemberName:Marry
MemberNum:002
MemberName:John
回到我们开头的Web通信的例子,
利用XML序列化与反序列化来进行对象传递,我们只需要把需要传递的对象序列化为XML字符串,使用一个隐藏域进行form提交就可以搞定咯!
接收方再将接收到的XML字符串反序列化成预设的对象即可。前提是双方必须约定序列化与反序列化的过程一致,且对象相同。
最后我们来看一下怎么利用一些特性来控制序列化与反序列化操作的过程。我们把开始的类改一下:
publicclassMember
{
[XmlElement("Member_Num")]
publicstringNum{get;set;}
publicstringName{get;set;}
}
[XmlRoot("Our_Team")]
publicclassTeam
{
[XmlIgnore]publicstringName;
publicList<Member>Members{get;set;}
}
然后我们再次执行刚才的控制台程序,序列化结果变成了这样:
<?xmlversion="1.0"encoding="utf-8"?>
<Our_Teamxmlns: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查看,就不多讲了。
有了这些知识,在网络中传递对象数据应该已经难不倒各位看官了把。^_^
相关文章
- JS 对象(Object)和字符串(String)互转[通俗易懂]
- asp中Session对象的清空[通俗易懂]
- React源码学习入门(四)深入探究React中的对象池
- 【说站】Python bs4的四种对象
- Spring MVC框架:第二章:视图解析器和@RequestMapping注解使用在类级别及获取原生Servlet API对象
- Mabatis 源码探究(2)Java 获取mybatis-config.xml的输入流 inputStream对象
- WordPress插件实现上传图片单独存到至腾讯云COS对象存储
- 【Android Protobuf 序列化】Protobuf 使用 ( Protobuf 源码分析 | 创建 Protobuf 对象 )
- XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax详解编程语言
- 数据MySQL:存储XML数据的有效方案(mysql存储xml)
- SMW0上传EXCEL模板时报错无分配给对象***的MIME类型详解编程语言
- MySQL实现存储对象数组的方法(mysql存储对象数组)
- 时间设置Redis中Java对象的过期时间(redisjava过期)
- Oracle删除对象:简单而快速!(oracle删除对象)
- Oracle 导出XML文件的技巧(oracle写xml文件)
- XML配置Redis让操作更高效(xml配置redis)
- MySQL数据库如何使用XML文件进行数据存储与交换(mysql xml文件)
- MySQL和XML如何处理小于符号(mysql xml小于)
- 使用MySQL将XML数据存储起来,轻松高效地管理和访问(mysql xml 存储)
- Oracle修改XML深入挖掘XML文件的变化(oracle修改xml)
- Oracle中高效处理XML的方法(oracle中处理xml)
- 深入了解MySQL XML数据库数据存储和管理的细节(mysql xml数据库)
- 优化Oracle XML伪列体验提升表现(oracle xml伪列)
- 籍Oracle XML编程实战指南(oracle xml 书)
- 在ASP中用“正则表达式对象”来校验数据的合法性
- php基础知识:类与对象(1)
- ruby对象的初始化方法
- js跨浏览器实现将字符串转化为xml对象的方法
- JavaScript获取当前页面上的指定对象示例代码
- JavaScript中的全局对象介绍