C# 序列化对象到XML
2024-03-17 17:33:41

基本用法

C#中要将一个对象序列化到XML,或从XML反序列化需要用到 XmlSerializer 类。

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
48
49
50
51
52
53
54
55
56
57
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace WindowsFormsApp1
{
public enum MyEnum
{
Enum1,
Enum2
}

public class Cat
{
public int Color;
}

public class Student
{
private int _val1;
public int Val2;
public MyEnum MyEnum;
public int Val3 { get; } = 0;
public int Val4 { get; set; } = 0;
public int? Val5 = null;

public Cat MyCat = new();
public List<int> Arr1;
public static int StaticVal;
}

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
var obj = new Student()
{
Arr1 = new List<int>
{
10,
20
}
};

var serializer = new XmlSerializer(obj.GetType());
using var fs = new FileStream("obj.xml", FileMode.Create);
serializer.Serialize(fs, obj);
}
}
}

输出XML内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0"?>
<Student xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Val2>0</Val2>
<MyEnum>Enum1</MyEnum>
<Val5 xsi:nil="true" />
<MyCat>
<Color>0</Color>
</MyCat>
<Arr1>
<int>10</int>
<int>20</int>
</Arr1>
<Val4>0</Val4>
</Student>

可见类成员并没有完全被序列化,因为 XmlSerializer 默认不会序列化以下几种数据:

  1. 静态成员,因为静态成员属于类而不是实例。
  2. 只读成员,因为只读成员在反序列化时不能被初始化。
  3. 私有成员,因为私有成员不能从外部访问,因此无法序列化和反序列化。

必须有默认构造函数

当类没有提供无参数构造函数时,构造 XmlSerializer 时就会抛出InvalidOperationException异常

1
Student 无法序列化,因为它没有无参数的构造函数。

实现 IXmlSerializable 接口

在某些情况下,XmlSerializer类的默认行为可能无法满足需求,这时就需要实现 IXmlSerializable 接口来控制序列化和反序列化过程

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
public class Student: IXmlSerializable
{
private int _val1;
public int Val2;
public MyEnum MyEnum;
public int Val3
{
get;
} = 0;
public int Val4
{
get;
set;
} = 0;
public int ? Val5 = null;
public Cat MyCat = new();
public List < int > Arr1;
public static int StaticVal;

public XmlSchema GetSchema()
{
return null; // 没用,总是返回null
}

public void ReadXml(XmlReader reader)
{
Val2 = reader.ReadElementContentAsInt();
}

public void WriteXml(XmlWriter writer)
{
writer.WriteValue(Val2);
}
}

输出XML内容

1
2
<?xml version="1.0"?>
<Student>0</Student>

一些需要实现IXmlSerializable接口的情况:

  1. 控制值的输出格式。
  2. 需要序列化私有成员时。
  3. 当需要在序列化过程中执行一些自定义的操作时,例如在序列化之前或之后执行某些操作,或者在序列化期间处理异常时。

注解

使用注解(Attribute)来为XML序列化和反序列化提供更多的控制和灵活性。

XmlRoot

XmlRoot 用于指定XML文档根元素名称和命名空间的注解。它可以应用于类或结构体,并且可以在序列化和反序列化过程中提供更多的控制和灵活性。

1
2
3
4
5
6
[XmlRoot("Person", Namespace = "http://example.com")]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}

输出XML内容

1
2
3
4
<Person xmlns="http://example.com">
<Name>Alice</Name>
<Age>30</Age>
</Person>

XmlElement

XmlElement 用于将类的属性或字段序列化为XML元素的注解。它可以应用于公共字段或属性,并且可以指定XML元素的名称和命名空间。

1
2
3
4
5
6
7
8
public class Person
{
[XmlElement("FullName")]
public string Name { get; set; }

[XmlElement("Years")]
public int Age { get; set; }
}

输出内容

1
2
3
4
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Years>0</Years>
</Person>

在这个例子中,XmlElement 注解指定了节点元素的名称。更多用法参考 XmlElement

XmlAttribute

XmlAttribute 是用于将类的属性或字段序列化为XML属性的注解。它可以应用于公共字段或属性,并且可以指定XML属性的名称和命名空间。

1
2
3
4
5
6
7
public class Person
{
public string Name { get; set; }

[XmlAttribute("Years")]
public int Age { get; set; }
}

输出内容

1
2
3
<Person Years="30">
<Name>Alice</Name>
</Person>

在这个例子中,注解将Age属性序列化为XML属性,属性名为”Years”。更多用法参考 XmlAttributes

XmlArray

XmlArray 用于将数组或集合属性序列化为XML数组的注解。它可以应用于公共字段或属性,并且可以指定XML数组的名称、元素名称和命名空间。

1
2
3
4
5
6
7
8
public class Person
{
public string Name { get; set; }

[XmlArray("Interests")]
[XmlArrayItem("Interest")]
public string[] Interests { get; set; }
}

在这个例子中,注解指定了生成的XML数组的名称为”Interests”。同时,XmlArrayItem注解指定了生成的XML数组元素的名称为”Interest”。

1
2
3
4
5
6
7
8
<Person>
<Name>Alice</Name>
<Interests>
<Interest>Reading</Interest>
<Interest>Traveling</Interest>
<Interest>Hiking</Interest>
</Interests>
</Person>

XmlIgnore

XmlIgnore 用于公共字段或属性,并用于指示XmlSerializer忽略该字段或属性的序列化。

1
2
3
4
5
6
7
public class Person
{
public string Name { get; set; }

[XmlIgnore]
public int Age { get; set; }
}

其他注解

还有一些其他不常用的注解参考官方手册 用来控制 XML 序列化的属性

相关阅读

如何:序列化对象
XML 序列化注意事项

上一页
2024-03-17 17:33:41
下一页