一、序列化概念
(微软定义)序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
二、学习这方面的知识需要那些基础
1,知道XML是什么,如何定义一个标准的XML文件
2,知道XML架构(Schema)是什么,如何定义一个标准的XML架构文件
3,知道XSD.exe的基本用法。
如果你对XML或Schema有什么不清楚的地方,请到这里来学习 中国XML论坛
三、案例学习
假如我们这这样一个xml文件,我们需要将它反序列化为对象
<?xml version="1.0" encoding="UTF-8"?>
<!--示例 XML 文件由 XMLSpy v2006 U 创建 (http://www.altova.com)-->
<Pages>
<FirstPage Url="Text">
<SecondPage Url="Text"/>
<SecondPage Url="Text"/>
</FirstPage>
<FirstPage Url="Text">
<SecondPage Url="Text"/>
<SecondPage Url="Text"/>
</FirstPage>
</Pages>
要将xml反序列化为对象,他们之间不能直接转换,需要一个中间人,就是Schema,Schema文件我们可以用工具生成,也可以自己手写,一般的做法就是先用工具生成,然后在其基础上修改,我这里用的生成工具是XMLSpy v2006,默认生成格式如下:<!--示例 XML 文件由 XMLSpy v2006 U 创建 (http://www.altova.com)-->
<Pages>
<FirstPage Url="Text">
<SecondPage Url="Text"/>
<SecondPage Url="Text"/>
</FirstPage>
<FirstPage Url="Text">
<SecondPage Url="Text"/>
<SecondPage Url="Text"/>
</FirstPage>
</Pages>
Code
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--W3C Schema 由 XMLSpy v2006 U 创建 (http://www.altova.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="FirstPage">
<xs:complexType>
<xs:sequence>
<xs:element ref="SecondPage" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Url" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Text"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Pages">
<xs:complexType>
<xs:sequence>
<xs:element ref="FirstPage" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SecondPage">
<xs:complexType>
<xs:attribute name="Url" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Text"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
其中的<xs:simpleType>节点我们不需要,修改成如下格式:<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--W3C Schema 由 XMLSpy v2006 U 创建 (http://www.altova.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="FirstPage">
<xs:complexType>
<xs:sequence>
<xs:element ref="SecondPage" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Url" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Text"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Pages">
<xs:complexType>
<xs:sequence>
<xs:element ref="FirstPage" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SecondPage">
<xs:complexType>
<xs:attribute name="Url" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Text"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
Code
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--W3C Schema 由 XMLSpy v2006 U 创建 (http://www.altova.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="FirstPage">
<xs:complexType>
<xs:sequence>
<xs:element ref="SecondPage" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Url" use="required">
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Pages">
<xs:complexType>
<xs:sequence>
<xs:element ref="FirstPage" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SecondPage">
<xs:complexType>
<xs:attribute name="Url" use="required">
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
用微软提供的工具xsd.exe也可以生成xml架构,网上有很多文章都做了介绍,这里就不列举了。<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--W3C Schema 由 XMLSpy v2006 U 创建 (http://www.altova.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="FirstPage">
<xs:complexType>
<xs:sequence>
<xs:element ref="SecondPage" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Url" use="required">
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Pages">
<xs:complexType>
<xs:sequence>
<xs:element ref="FirstPage" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SecondPage">
<xs:complexType>
<xs:attribute name="Url" use="required">
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
有了Schema文件,我们就可以用xsd.exe工具来生成和xml文件对应的类文件了。生成方法如下:
首先运行.NET FrameWork的SDK命令提示
在其中键入:xsd /c /l:CS xsd文件路径 /o:文件输出路径
切记"/o:文件输出路径"之间不要有空格
其中红色标识部分分别为文件所在的物理路径,生成的类文件如下:
Code
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行库版本:2.0.50727.832
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
//
// 此源代码由 xsd 自动生成, Version=2.0.50727.42。
//
namespace JianCaiWeb.BLL {
using System.Xml.Serialization;
/**//// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class Pages {
private FirstPage[] firstPageField;
/**//// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("FirstPage")]
public FirstPage[] FirstPage {
get {
return this.firstPageField;
}
set {
this.firstPageField = value;
}
}
}
/**//// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class FirstPage {
private SecondPage[] secondPageField;
private string urlField;
/**//// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SecondPage")]
public SecondPage[] SecondPage {
get {
return this.secondPageField;
}
set {
this.secondPageField = value;
}
}
/**//// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Url {
get {
return this.urlField;
}
set {
this.urlField = value;
}
}
}
/**//// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class SecondPage {
private string urlField;
/**//// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Url {
get {
return this.urlField;
}
set {
this.urlField = value;
}
}
}
}
正常情况下,我们需要对工具生成的类文件做一些修改,修改如下://------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行库版本:2.0.50727.832
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
//
// 此源代码由 xsd 自动生成, Version=2.0.50727.42。
//
namespace JianCaiWeb.BLL {
using System.Xml.Serialization;
/**//// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class Pages {
private FirstPage[] firstPageField;
/**//// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("FirstPage")]
public FirstPage[] FirstPage {
get {
return this.firstPageField;
}
set {
this.firstPageField = value;
}
}
}
/**//// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class FirstPage {
private SecondPage[] secondPageField;
private string urlField;
/**//// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SecondPage")]
public SecondPage[] SecondPage {
get {
return this.secondPageField;
}
set {
this.secondPageField = value;
}
}
/**//// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Url {
get {
return this.urlField;
}
set {
this.urlField = value;
}
}
}
/**//// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class SecondPage {
private string urlField;
/**//// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Url {
get {
return this.urlField;
}
set {
this.urlField = value;
}
}
}
}
Code
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行库版本:2.0.50727.832
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
//
// 此源代码由 xsd 自动生成, Version=2.0.50727.42。
//
using System.Xml.Serialization;
public partial class Pages {
private FirstPage[] firstPageField;
[XmlElementAttribute("FirstPage")]
public FirstPage[] FirstPage {
get {
return this.firstPageField;
}
set {
this.firstPageField = value;
}
}
}
public partial class FirstPage {
private SecondPage[] secondPageField;
private string urlField;
[XmlElementAttribute("SecondPage")]
public SecondPage[] SecondPage {
get {
return this.secondPageField;
}
set {
this.secondPageField = value;
}
}
[XmlAttributeAttribute()]
public string Url {
get {
return this.urlField;
}
set {
this.urlField = value;
}
}
}
public partial class SecondPage {
private string urlField;
[XmlAttributeAttribute()]
public string Url {
get {
return this.urlField;
}
set {
this.urlField = value;
}
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行库版本:2.0.50727.832
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
//
// 此源代码由 xsd 自动生成, Version=2.0.50727.42。
//
using System.Xml.Serialization;
public partial class Pages {
private FirstPage[] firstPageField;
[XmlElementAttribute("FirstPage")]
public FirstPage[] FirstPage {
get {
return this.firstPageField;
}
set {
this.firstPageField = value;
}
}
}
public partial class FirstPage {
private SecondPage[] secondPageField;
private string urlField;
[XmlElementAttribute("SecondPage")]
public SecondPage[] SecondPage {
get {
return this.secondPageField;
}
set {
this.secondPageField = value;
}
}
[XmlAttributeAttribute()]
public string Url {
get {
return this.urlField;
}
set {
this.urlField = value;
}
}
}
public partial class SecondPage {
private string urlField;
[XmlAttributeAttribute()]
public string Url {
get {
return this.urlField;
}
set {
this.urlField = value;
}
}
}
数组的基类(Array)实现了IEnumerable接口,可以使用foreach访问集合内的数据,下边修改的类同样支持foreach,应该是类的另一种写法(我原来以为数组不支持foreach,真是太大意了,以后尽量少犯这么低级的错误。)
修改后的类文件如下:
Code
using System.Xml.Serialization;
using System;
using System.Collections;
[Serializable()]
public partial class Pages
{
private FirstPageCollection firstPageField;
/**//// <remarks/>
[XmlElementAttribute("FirstPage")]
public FirstPageCollection FirstPage
{
get
{
return this.firstPageField;
}
set
{
this.firstPageField = value;
}
}
}
[Serializable()]
public partial class FirstPageCollection : ArrayList
{
public virtual void Add(FirstPage first)
{
base.Add(first);
}
/**//// <summary>
/// Gets or sets a RewriterRule at a specified ordinal index.
/// </summary>
public FirstPage this[int index]
{
get
{
return (FirstPage)base[index];
}
set
{
base[index] = value;
}
}
}
[Serializable()]
public partial class FirstPage
{
private SecondPageCollection secondPageField;
private string urlField;
/**//// <remarks/>
[XmlElementAttribute("SecondPage")]
public SecondPageCollection SecondPage
{
get
{
return this.secondPageField;
}
set
{
this.secondPageField = value;
}
}
[XmlAttributeAttribute()]
public string Url
{
get
{
return this.urlField;
}
set
{
this.urlField = value;
}
}
}
[Serializable()]
public partial class SecondPageCollection : ArrayList
{
public virtual void Add(SecondPage first)
{
base.Add(first);
}
/**//// <summary>
/// Gets or sets a RewriterRule at a specified ordinal index.
/// </summary>
public SecondPage this[int index]
{
get
{
return (SecondPage)base[index];
}
set
{
base[index] = value;
}
}
}
[Serializable()]
public partial class SecondPage
{
private string urlField;
[XmlAttributeAttribute()]
public string Url
{
get
{
return this.urlField;
}
set
{
this.urlField = value;
}
}
}
仔细看过之后,不难发现,比上一个类多了两个集合类,FirstPageCollection和SecondPageCollection这两个类,我们就是用他们来取代数组,这连个类都继承至ArrayList,当然你也可以继承自别的类,例如CollectionBase,当然你也可以手写,需要实现如下接口IEnumerable。这是一个网友写的实现什么接口的类实例可以被foreach 。using System.Xml.Serialization;
using System;
using System.Collections;
[Serializable()]
public partial class Pages
{
private FirstPageCollection firstPageField;
/**//// <remarks/>
[XmlElementAttribute("FirstPage")]
public FirstPageCollection FirstPage
{
get
{
return this.firstPageField;
}
set
{
this.firstPageField = value;
}
}
}
[Serializable()]
public partial class FirstPageCollection : ArrayList
{
public virtual void Add(FirstPage first)
{
base.Add(first);
}
/**//// <summary>
/// Gets or sets a RewriterRule at a specified ordinal index.
/// </summary>
public FirstPage this[int index]
{
get
{
return (FirstPage)base[index];
}
set
{
base[index] = value;
}
}
}
[Serializable()]
public partial class FirstPage
{
private SecondPageCollection secondPageField;
private string urlField;
/**//// <remarks/>
[XmlElementAttribute("SecondPage")]
public SecondPageCollection SecondPage
{
get
{
return this.secondPageField;
}
set
{
this.secondPageField = value;
}
}
[XmlAttributeAttribute()]
public string Url
{
get
{
return this.urlField;
}
set
{
this.urlField = value;
}
}
}
[Serializable()]
public partial class SecondPageCollection : ArrayList
{
public virtual void Add(SecondPage first)
{
base.Add(first);
}
/**//// <summary>
/// Gets or sets a RewriterRule at a specified ordinal index.
/// </summary>
public SecondPage this[int index]
{
get
{
return (SecondPage)base[index];
}
set
{
base[index] = value;
}
}
}
[Serializable()]
public partial class SecondPage
{
private string urlField;
[XmlAttributeAttribute()]
public string Url
{
get
{
return this.urlField;
}
set
{
this.urlField = value;
}
}
}
四、结束语
xml反序列化其实并不复杂,只是我们平时用的少,多用两次就没有什么了。 我们这里写了一个简单的demo,大家对比这看看会好理解一点,文件下载