一、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 在轻量级数据交互中更具优势。