一、XML 基础概念
XML(eXtensible Markup Language,可扩展标记语言)是一种用于存储和传输数据的标记语言,由 W3C 制定,具有以下特点:
-
可扩展性 :允许自定义标记(如
<Student>
、<StuName>
),而非固定标签集; -
跨平台:独立于编程语言和操作系统,适合不同系统间的数据交换;
-
用途:主要用于数据存储和传输(如配置文件、WebService 数据交互),与 HTML(用于数据展示)形成互补。
二、XML 文档格式与语法要求
XML 有严格的格式规范,不符合规范的文档会被视为无效:
1. 格式要求
-
唯一根元素:整个文档必须有且仅有一个根元素(所有其他元素都嵌套在其内部);
-
标签匹配 :每个开始标签(如
<Student>
)必须有对应的结束标签(</Student>
); -
正确嵌套 :元素不能交叉嵌套(如
<a><b></a></b>
是错误的); -
属性规范:属性值必须用引号(单引号或双引号)括起,且同一元素中属性不能重复。
2. 核心语法
-
处理指令
:声明 XML 版本和编码(通常位于文档开头),如:
<?xml version="1.0" encoding="utf-8" ?>
-
元素
:由开始标签、内容、结束标签组成,如:
<StuName>高启强</StuName> <!-- 内容为文本 -->
-
属性
:元素的附加信息,格式为属性名="值",如:
<Version versionNum="2.1" pTime="2023-03-28">数据版本信息</Version>
-
注释
:以<!--开头,-->结尾,如:
<!-- 这是一个学生信息的XML文档 -->
三、XML 序列化与反序列化
XML 序列化是将对象转换为 XML 格式的过程,反序列化则是将 XML 还原为对象的过程,主要通过XmlSerializer
类实现。
1. 核心工具
XmlSerializer
:位于System.Xml.Serialization
命名空间,负责对象与 XML 的相互转换。
2. 序列化步骤
-
定义实体类:需序列化的类(无需特殊特性标记);
-
创建文件流 :通过
FileStream
指定 XML 文件路径和模式(如FileMode.Create
创建文件); -
实例化序列化器 :
XmlSerializer
需指定对象类型(如typeof(People)
); -
执行序列化 :调用
Serialize()
方法,将对象写入 XML 文件; -
释放资源:关闭文件流和写入器。
3. 反序列化步骤
-
创建文件流 :通过
FileStream
打开已有的 XML 文件; -
实例化序列化器:与序列化时的类型一致;
-
执行反序列化 :调用
Deserialize()
方法,将 XML 内容转换为对象; -
释放资源:关闭文件流和读取器。
4. 示例代码
using System.IO;
using System.Xml.Serialization;
// 1. 定义实体类
public class People
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public string Birth { get; set; }
}
// 2. 序列化:对象 → XML
public void XmlSerialize()
{
People people = new People()
{
Name = "吴亦凡",
Age = 18,
Sex = "男",
Birth = "2005-01-01"
};
// 创建文件流和写入器
using (FileStream fs = new FileStream("people.xml", FileMode.Create))
using (StreamWriter sw = new StreamWriter(fs))
{
XmlSerializer serializer = new XmlSerializer(typeof(People));
serializer.Serialize(sw, people); // 序列化并写入XML
}
}
// 3. 反序列化:XML → 对象
public void XmlDeserialize()
{
// 创建文件流和读取器
using (FileStream fs = new FileStream("people.xml", FileMode.Open))
using (StreamReader sr = new StreamReader(fs))
{
XmlSerializer serializer = new XmlSerializer(typeof(People));
People people = serializer.Deserialize(sr) as People; // 反序列化为对象
Console.WriteLine($"姓名:{people.Name},年龄:{people.Age}");
}
}
生成的people.xml
内容示例:
<?xml version="1.0" encoding="utf-8"?>
<People xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>吴亦凡</Name>
<Age>18</Age>
<Sex>男</Sex>
<Birth>2005-01-01</Birth>
</People>
四、XML 文件的生成与读取
除了通过序列化生成 XML,还可手动创建 XML 文件,或通过XmlDocument
类读取已有 XML。
1. 手动生成 XML 文件
通过文本编辑器直接编写,需遵循 XML 格式规范。例如学生信息 XML(XMLFile1.xml
):
<?xml version="1.0" encoding="utf-8" ?>
<Students> <!-- 根元素 -->
<Student> <!-- 子元素 -->
<StuName>高启强</StuName>
<StuAge>48</StuAge>
<StuGender>男</StuGender>
<StuClass>C#一班</StuClass>
</Student>
<Student>
<StuName>孟钰</StuName>
<StuAge>16</StuAge>
<StuGender>女</StuGender>
<StuClass>C#一班</StuClass>
</Student>
<DataInfo> <!-- 其他子元素 -->
<Version versionNum="2.1" pTime="2023-03-28">数据版本信息</Version>
</DataInfo>
</Students>
2. 读取 XML 文件(使用 XmlDocument
)
XmlDocument
是用于操作 XML 文档的核心类,可加载 XML 并遍历节点获取数据。
常用对象与方法
对象 | 属性 / 方法 | 说明 |
---|---|---|
XmlDocument |
Load(string path) |
加载指定路径的 XML 文件 |
DocumentElement |
获取 XML 的根节点 | |
XmlNode |
Name |
获取节点名称(如 "Student") |
InnerText |
获取节点的文本内容 | |
ChildNodes |
获取当前节点的所有子节点 |
读取示例代码
using System.Xml;
using System.Collections.Generic;
// 定义学生类
public class Student
{
public string StuName { get; set; }
public int StuAge { get; set; }
public string StuGender { get; set; }
public string StuClass { get; set; }
}
// 读取XML并转换为学生列表
private void ReadXml()
{
// 1. 创建XML文档对象
XmlDocument xmlDoc = new XmlDocument();
// 2. 加载XML文件(路径根据实际情况调整)
xmlDoc.Load("XMLFile1.xml");
// 3. 获取根节点(<Students>)
XmlNode rootNode = xmlDoc.DocumentElement;
List<Student> students = new List<Student>();
// 4. 遍历根节点的所有子节点
foreach (XmlNode node in rootNode.ChildNodes)
{
// 只处理<Student>节点
if (node.Name == "Student")
{
Student student = new Student();
// 遍历<Student>的子节点(如<StuName>、<StuAge>)
foreach (XmlNode childNode in node.ChildNodes)
{
switch (childNode.Name)
{
case "StuName":
student.StuName = childNode.InnerText; // 获取节点内容
break;
case "StuAge":
student.StuAge = int.Parse(childNode.InnerText);
break;
case "StuGender":
student.StuGender = childNode.InnerText;
break;
case "StuClass":
student.StuClass = childNode.InnerText;
break;
}
}
students.Add(student);
}
}
// 输出结果
foreach (var stu in students)
{
Console.WriteLine($"姓名:{stu.StuName},年龄:{stu.StuAge},班级:{stu.StuClass}");
}
}
五、XML 与 JSON 的区别
XML 和 JSON 都是常用的数据交换格式,但各有特点:
对比维度 | XML | JSON |
---|---|---|
重量级别 | 重量级(标签冗余,如<Name></Name> ) |
轻量级(简洁的键值对,如"Name":"" ) |
带宽占用 | 较高(冗余标签多) | 较低(格式简洁) |
可读性 | 结构清晰,但标签较多略显繁琐 | 更简洁,易于人类阅读 |
解析方式 | 使用XmlDocument 、XmlSerializer 等 |
内置DataContractJsonSerializer 或第三方Newtonsoft.Json |
扩展性 | 支持命名空间、注释,扩展性强 | 不支持注释,扩展性较弱 |
适用场景 | 配置文件(如 App.config)、WebService | 接口数据交互、轻量级存储 |
总结
XML 作为一种可扩展的标记语言,在配置文件、跨平台数据交换(如 WebService)中应用广泛。通过XmlSerializer
可实现对象与 XML 的快速转换,而XmlDocument
则提供了手动操作 XML 节点的能力。与 JSON 相比,XML 更适合需要复杂结构和强扩展性的场景,而 JSON 在轻量级数据交互中更具优势。