XML 序列化与操作详解笔记

一、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. 序列化步骤

  1. 定义实体类:需序列化的类(无需特殊特性标记);

  2. 创建文件流 :通过FileStream指定 XML 文件路径和模式(如FileMode.Create创建文件);

  3. 实例化序列化器XmlSerializer需指定对象类型(如typeof(People));

  4. 执行序列化 :调用Serialize()方法,将对象写入 XML 文件;

  5. 释放资源:关闭文件流和写入器。

3. 反序列化步骤

  1. 创建文件流 :通过FileStream打开已有的 XML 文件;

  2. 实例化序列化器:与序列化时的类型一致;

  3. 执行反序列化 :调用Deserialize()方法,将 XML 内容转换为对象;

  4. 释放资源:关闭文件流和读取器。

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":""
带宽占用 较高(冗余标签多) 较低(格式简洁)
可读性 结构清晰,但标签较多略显繁琐 更简洁,易于人类阅读
解析方式 使用XmlDocumentXmlSerializer 内置DataContractJsonSerializer或第三方Newtonsoft.Json
扩展性 支持命名空间、注释,扩展性强 不支持注释,扩展性较弱
适用场景 配置文件(如 App.config)、WebService 接口数据交互、轻量级存储

总结

XML 作为一种可扩展的标记语言,在配置文件、跨平台数据交换(如 WebService)中应用广泛。通过XmlSerializer可实现对象与 XML 的快速转换,而XmlDocument则提供了手动操作 XML 节点的能力。与 JSON 相比,XML 更适合需要复杂结构和强扩展性的场景,而 JSON 在轻量级数据交互中更具优势。

相关推荐
前端小万2 分钟前
一次紧急的现场性能问题排查
前端·性能优化
excel18 分钟前
为什么相同卷积代码在不同层学到的特征完全不同——基于 tfjs-node 猫图像识别示例的逐层解析
前端
知识分享小能手19 分钟前
React学习教程,从入门到精通,React 使用属性(Props)创建组件语法知识点与案例详解(15)
前端·javascript·vue.js·学习·react.js·前端框架·vue
用户214118326360221 分钟前
dify案例分享-免费玩转即梦 4.0 多图生成!Dify 工作流从搭建到使用全攻略,附案例效果
前端
CodeSheep21 分钟前
稚晖君又开始摇人了,有点猛啊!
前端·后端·程序员
JarvanMo24 分钟前
Flutter Web vs Mobile:主要区别以及如何调整你的UI
前端
IT_陈寒43 分钟前
Java性能优化:从这8个关键指标开始,让你的应用提速50%
前端·人工智能·后端
天生我材必有用_吴用1 小时前
Vue3+Node.js 实现大文件上传:断点续传、秒传、分片上传完整教程(含源码)
前端
大筒木老辈子1 小时前
Linux笔记---协议定制与序列化/反序列化
网络·笔记
摸鱼的春哥1 小时前
前端程序员最讨厌的10件事
前端·javascript·后端