UD2SL3——lXmlSerialzable接口

本章代码关键字

1
2
3
4
5
6
7
8
9
10
11
12
13
IXmlSerializable                    //若要使自定义类有自己的自定义序列化规则,则需要继承该接口,并实现该接口的方法
GetSchema() { } //返回框架,一般返回null即可
WriteXml(XmlWriter writer) { } //对该类对象序列化时会自动调用的方法
writer.WriteAttributeString(,) //写属性
writer.WriteElementString() //写元素节点
writer.WriteStartElement() //写头节点
writer.WriteEndElement() //写尾节点
ReadXml(XmlReader reader) { } //对该类反序列化时会自动调用的方法
reader[] //读取当前节点属性
reader.Read() //读取下一个节点
reader.Value //读取当前节点的内容
reader.ReadStartElement() //读当前节点下的头节点
reader.ReadEndElement() //读当前节点的的尾节点

lXmlSerialzable接口

C# 的 XmlSerializer​ 提供了可拓展内容
可以让一些不能被序列化和反序列化的特殊类能被处理
让特殊类继承 IXmlSerializable​ 接口 实现其中的方法即可

自定义类实践

序列化回顾

1
2
3
4
5
6
7
8
9
10
11
12
13
14
TestLesson3 t = new TestLesson3();
t.test2 = "123";
using (StreamWriter writer = new StreamWriter(Application.persistentDataPath + "/TestLesson3.xml"))
{
XmlSerializer s = new XmlSerializer(typeof(TestLesson3));
s.Serialize(writer, t);
}

using (StreamReader reader = new StreamReader(Application.persistentDataPath + "/TestLesson3.xml"))
{
XmlSerializer s = new XmlSerializer(typeof(TestLesson3));
t = s.Deserialize(reader) as TestLesson3;
}

自定义类的自定义序列化

若要自定义自己的序列化规则,需要继承IXmlSerializable​接口
这样XML序列化对象 在序列化 该类的对象 时 会调用该接口的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class TestLesson3 : IXmlSerializable
{
public int test1;
public string test2;
//返回结构
public XmlSchema GetSchema()
{
return null; //一般用不到,直接返回空
}
//反序列化时 会自动调用的方法
public void ReadXml(XmlReader reader)
{
//在里面可以 自定义反序列化的规则
}
//序列化时 会自动调用的方法
public void WriteXml(XmlWriter writer)
{
//在里面可以 自定义序列化的规则
//如果要自定义 序列化的规则 一定会用到 XmlWriter中的一些方法 来进行序列化
}
}

序列化时会自动调用的方法

在该方法里一定会使用参数writer​的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void WriteXml(XmlWriter writer)
{
//在里面可以 自定义序列化的规则
//如果要自定义 序列化的规则 一定会用到 XmlWriter中的一些方法 来进行序列化
//1.写属性
writer.WriteAttributeString("test1", test1.ToString());
writer.WriteAttributeString("test2", test2);

//2.写节点
writer.WriteElementString("test1", test1.ToString());
writer.WriteElementString("test2", test2);

//3.写包裹节点
XmlSerializer s = new XmlSerializer(typeof(int)); //实例化一个int类型的xml序列化对象
writer.WriteStartElement("test1"); //写头节点
s.Serialize(writer, test1); //写包裹节点
writer.WriteEndElement(); //写尾节点,不需要写参数,自动根据上句写好的头节点补齐

XmlSerializer s2 = new XmlSerializer(typeof(string)); //实例化一个string类型的xml序列化对象
writer.WriteStartElement("test2"); //写头节点
s2.Serialize(writer, test2); //写包裹节点
writer.WriteEndElement(); //写尾节点,不需要写参数,自动根据上句写好的头节点补齐
}

反序列化时会自动调用的方法

在该方法里一定会使用参数reader​的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public void ReadXml(XmlReader reader)
{
//在里面可以 自定义反序列化的规则
//1.读属性
test1 = int.Parse(reader["test1"]);
test2 = reader["test2"];

//2.读节点
//方式一:一个部分一个部分的读
reader.Read(); //这时读到的是test1节点
reader.Read(); //这时读到的是test1包裹的内容
test1 = int.Parse(reader.Value); //得到当前内容的值
reader.Read(); //这时读到的是尾部包裹节点
reader.Read(); //这时读到的是test2节点
reader.Read(); //这时读到的是test2包裹的内容
test2 = reader.Value;
//方法二:
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element) //在这里只要判断是元素开始节点就读取
{
switch (reader.Name) //根据名字来读取内容
{
case "test1":
reader.Read();
test1 = int.Parse(reader.Value);
break;
case "test2":
reader.Read();
test2 = reader.Value;
break;
}
}
}

//3.读包裹节点
XmlSerializer s = new XmlSerializer(typeof(int)); //实例化一个int类型的xml序列化对象
XmlSerializer s2 = new XmlSerializer(typeof(string)); //实例化一个string类型的xml序列化对象
reader.Read(); //跳过根节点
reader.ReadStartElement("test1"); //读头节点
test1 = (int)s.Deserialize(reader); //读包裹节点
reader.ReadEndElement(); //读尾节点

reader.ReadStartElement("test2"); //读头节点
test2 = s2.Deserialize(reader).ToString(); //读包裹节点
reader.ReadEndElement(); //读尾节点
}

返回框架

一般用不到,直接返回空

1
2
3
4
public XmlSchema GetSchema()
{
return null; //一般用不到,直接返回空
}