1. 序列化和反序列化的作用
使用XML序列化能够方便XML的存储或传输,能够把一个对象的公共域和属性保存为一种序列格式的过程;反序列化则是使用序列化的状态信息将对象从序列XML状态还原为初始状态的过程。
2. 如何进行序列化与反序列操作
.NETFramework提供了System.Runtime.Serialization和
System.Xml.Serialization以提供序列化功能。而System.Xml.Serialization提供了一个XmlSerializer类,该类可以将一个对象序列化和反序列化为XML格式。XmlSerializer类虽然能够执行序列化和反序列化,但是序列化和反序列化有一个最大的区别,就是序列化调用Serialize方法,而反序列化调用Deserialize方法。
3. 序列化和反序化的应用(应用见程序部分)
1Common和Decommon以上代码用最简单的方式说明了xml序列化
和反序列化的过程。
2MyDe中有一个自定义类Cat,Cat类有三个属性分别为Color,Saying,
Speed。
可以使用XmlElement指定属性序列化为子节点(默认情况会序列化
为子节点);或者使用XmlAttribute特性制定属性序列化为Xml节点
的属性;还可以通过XmlIgnore特性修饰要求序列化程序不序列化修
饰属性。
3XmlArray数组的Xml序列化需要使用XmlArrayAttribute和
XmlArrayItemAttribute;XmlArrayAttribute指定数组元素的Xml节点名,XmlArrayItemAttribute指定数组元素的Xml节点名
4. 序列化和反序列化时应该注意的问题
(1)需序列化的字段必须是公共的(public)
(2)需要序列化的类都必须有一个无参的构造函数
(3)枚举变量可序列化为字符串,无需用[XmlInclude]
(4)导出非基本类型对象,都必须用[XmlInclude]事先声明。该 规则递归作用到子元素
如导出ArrayList对象,若其成员是自定义的,需预包含处理:
using System.Xml.Serialization;
[XmlInclude(typeof(自定义类))]
(5)Attribute中的IsNullable参数若等于false,表示若元素为null则不显示该元素。
也就是说:针对值类型(如结构体)该功能是实效的
若数组包含了100个空间,填充了10个类对象,则序列化后只显示10个节点
若数组包含了100个空间,填充了10个结构体对象,则序列化后会显示100个节点
(6)真正无法XML序列化的情况
某些类就是无法XML序列化的(即使使用了[XmlInclude])
IDictionary(如HashTable)
System.Drawing.Color
System.Drawing.Font
SecurityAttribute声明
父类对象赋予子类对象值的情况
对象间循环引用
(7)对于无法XML序列化的对象,可考虑
使用自定义xml序列化(实现IXmlSerializable接口)
实现IDictionary的类,可考虑:
1用其它集合类替代;
2用类封装之,并提供Add和this函数
某些类型需要先经过转换,然后才能序列化为 XML。如XML序列化System.Drawing.Color,可先用ToArgb()将其转换为整数
过于复杂的对象用xml序列化不便的话,可考虑用二进制序列
(8)对XML序列化还包括以下属性
1XmlRoot:用来识别作为XML文件根元素或结构,可以用此标记把一个元素的名称设置为根元素。
2XmlElement:共有的属性或字段可以作为一个元素被序列化到XML结构中。
3XmlAttribute:共有的属性或字段可以作为一个属性被序列化到XML结构中。
4XmlIgnore: 共有的属性或字段不包括在序列化的XML结构中。
5XmlArray: 共有的属性或字段可以作为一个元素数组被序列化到XML结构中。
6XmlArrayItem:用来识别可以放到一个序列化数组中的类型。
[XmlRoot("Block")]
public class Block
{
[XmlAttribute("id")]
public int id { get; set; }
[XmlElement("name")]
public string name { get; set; }
[XmlElement("Nub")]
public int Nub { get; set; }
private Line lline = new Line();
public Line Lline
{
get { return lline; }
set { lline = value; }
}
private List<Line> lines = new List<Line>();
public List<Line> Lines
{
get { return lines; }
set { lines = value; }
}
}
static void ChooseActive()
{
Console.WriteLine("******************************");
Console.WriteLine("请选择将要执行的动作:");
Console.WriteLine("1.序列化");
Console.WriteLine("2.反序列化");
XmlSerializer myxm = new XmlSerializer(typeof(Block));
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "myFileName.xml");
string input = Console.ReadLine();
switch (input)
{
case "1":
Console.WriteLine("1.序列化正在进行...");
#region 实体定义
Block myBlock = new Block { id = 12344, name = "ad", Nub = 1111 };
myBlock.Lline.Content = "guojing";
myBlock.Lline.Len = 123;
myBlock.Lline.lineNo = 456;
Line mline = new Line();
mline.lineNo = 7742;
mline.Content = "hsd";
mline.Len = 2356;
myBlock.Lines.Add(mline);
Line line1 = new Line();
line1.Content = "uwer";
line1.lineNo = 247;
line1.Len = 8347;
myBlock.Lines.Add(line1);
Line L = new Line();
L.Len = 6;
myBlock.Lines.Add(L);
#endregion
StreamWriter myWrite = new StreamWriter(path);
myxm.Serialize(myWrite, myBlock);
myxm.Serialize(Console.Out, myBlock);
myWrite.Close();
Console.WriteLine("序列化完毕");
break;
case "2":
Console.WriteLine("2.反序列化正在进行...");
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(path);
StreamReader st = new StreamReader(path);
object de = myxm.Deserialize(st);
Block bl = de as Block;
Console.WriteLine("bl.Lline.Content:" + bl.Lline.Content.ToString());
st.Close();
Console.WriteLine("反序列化完毕");
break;
default:
break;
}
ChooseActive();
}