C# XML文件基础

一、XML介绍

1.1 概念

在C#中,XML文件是一种用来存储和传输数据的标记语言文档。XML代表可扩展标记语言(eXtensible Markup Language)。它设计用来传输和存储数据,具有自我描述性,并且对人和机器都是可读的。

XML文件的作用包括:

  1. 数据存储: XML是一种流行的方式,用于存储应用程序设置、配置信息或其他数据。例如,微软的.NET框架中的配置文件(如 app.configweb.config)就是XML格式的。

  2. 数据交换: 由于其文本本质和广泛的可读性,XML是一个常用的数据交换格式,可以在不同的系统和程序间传递信息,尤其是在Web服务和SOA(面向服务的架构)中。

  3. 数据结构描述: XML可以描述数据的结构,通过元素和属性来表示数据的层次和语义。这对于确保数据的一致性和完整性很有帮助。

  4. 平台无关性: 作为一个文本格式,XML文件可以在不同的操作系统和环境间轻松地移植和使用。

  5. 可扩展性: 如其名称所示,XML是可扩展的,这意味着你可以设计自己的标记元素和文档结构,以满足特定的需要,而不必依赖于标准的数据格式。

  6. 支持国际化: XML支持Unicode,使得它可以表示几乎所有人类语言中的文本,这对于国际化的应用程序来说非常重要。

  7. 验证: 使用XML Schema定义语言(XSD),可以定义XML文档的结构和数据类型,并对XML文档进行验证,确保数据的正确性。

  8. 转换和呈现: 使用XSLT(Extensible Stylesheet Language Transformations),可以把XML文档转换为其他格式的文档,例如HTML,用于在浏览器中显示。

在C#中操作XML文件,你可以使用System.Xml命名空间中的类,如XmlDocument, XmlReader, XmlWriter, XmlSerializer等,来读取、修改、创建和序列化XML文档。

1.2 例子

在C#或其他编程语言中,有专门的库和工具可以帮助开发者生成或解析XML格式的数据,而不需要手动编写或解析XML的标签和结构。这些工具通常为数据提供了一个高层抽象,允许开发者用编程语言中的数据结构来操作数据,然后这些工具负责将这些数据结构转换成合适的XML格式,或者将XML数据解析成可在程序中使用的数据结构。所以不用去细致了解它的语法;

以下是一个简单的XML文件内容的例子,它描述了一个图书馆中书籍的集合:

<?xml version="1.0" encoding="UTF-8"?>
<library>
  <book id="1">
    <title>The Great Gatsby</title>
    <author>F. Scott Fitzgerald</author>
    <year>1925</year>
    <genre>Fiction</genre>
  </book>
  <book id="2">
    <title>Nineteen Eighty-Four</title>
    <author>George Orwell</author>
    <year>1949</year>
    <genre>Dystopian</genre>
  </book>
  <book id="3">
    <title>To Kill a Mockingbird</title>
    <author>Harper Lee</author>
    <year>1960</year>
    <genre>Fiction</genre>
  </book>
</library>

这个XML文档遵循以下结构和特点:

  • XML声明: <?xml version="1.0" encoding="UTF-8"?> 是XML声明,它定义了这个文档的XML版本和字符编码。

  • 根元素: <library> 标签是文档的根元素,所有其他元素都包含在其中。

  • 元素(或标签):<book><title><author><year><genre>。每个 <book> 元素表示图书馆中的一本书。

  • 属性: <book> 元素中的 id 是一个属性,它为每本书提供了一个唯一的标识符。

  • 文本内容: 标签如 <title><author> 的文本内容存储了书的标题和作者。

XML文件可以被各种程序和服务用来读取、显示和处理图书馆集合中书籍的信息。因为XML是可扩展的,所以如果需要,我们可以很容易地添加更多的数据字段,比如出版社、ISBN号,或者其他元数据。

1.3创建一个xml文件

假设我们有一个C#对象,并希望将其转换为XML,我们可以使用 XmlSerializer 来序列化这个对象:

using System;
using System.IO;
using System.Xml.Serialization;

// 假设有一个Book类
public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }
    public int Year { get; set; }
    public string Genre { get; set; }
}

class Program
{
    static void Main()
    {
        // 创建一个Book实例
        Book myBook = new Book
        {
            Title = "The Great Gatsby",
            Author = "F. Scott Fitzgerald",
            Year = 1925,
            Genre = "Fiction"
        };

        // 创建一个XmlSerializer对象来进行序列化
        XmlSerializer serializer = new XmlSerializer(typeof(Book));

        // 使用StreamWriter写入文件
        using (StreamWriter writer = new StreamWriter("D:\\IDE\\book.xml"))
        {
            serializer.Serialize(writer, myBook);
        }

        Console.WriteLine("XML文件已生成。");
    }
}

在这里插入图片描述

于是在我们的目标地址生成了这样的一个文件,而且无法被打开。需要注意的是:在上面的例子,.NET中对XML的处理主要是对象到XML的转换,所以使用XmlSerializer更合适。
如果涉及到需要读取或修改XML文档,或者创建新的XML文档结构,那么XmlDocument可能更适合。此外,XmlDocument在.NET Core中被一个更快和更现代的XDocument类(位于System.Xml.Linq命名空间下)所替代,它提供了LINQ集成和更简洁的API。

二、读取XML文件

假如我们得到了一个这样的XML文件,我们需要使用C#文件读取,文件是这样,里面记载了几个班级学生的信息(姓名 年龄 行别 班级):

<?xml version="1.0" encoding="utf-8" ?>
<Students>
  <Student>
    <StuName>王五</StuName>
    <StuAge>19</StuAge>
    <Gender>男</Gender>
    <ClassName>机械1班</ClassName>
  </Student>
  <Student>
    <StuName>王六</StuName>
    <StuAge>22</StuAge>
    <Gender>男</Gender>
    <ClassName>机械2班</ClassName>
  </Student>
  <Student>
    <StuName>刘九</StuName>
    <StuAge>21</StuAge>
    <Gender>男</Gender>
    <ClassName>机械3班</ClassName>
  </Student>
  <Student>
    <StuName>阿红</StuName>
    <StuAge>23</StuAge>
    <Gender>女</Gender>
    <ClassName>机械4班</ClassName>
  </Student>
  <Student>
    <StuName>阿七</StuName>
    <StuAge>20</StuAge>
    <Gender>女</Gender>
    <ClassName>机械5班</ClassName>
  </Student>
  <DataInfo>
    <Version vNo="1.2" pTime="2012-12-12">数据版本信息</Version>
  </DataInfo>
</Students>

我们希望可以这样显示出来:
在这里插入图片描述
应该怎么办呢,我们可以按照这样的步骤来进行:

  1. 加载XML文件:

    • 使用XmlDocument类或者XDocument类(如果是使用LINQ to XML)来加载XML文件。这通常通过调用这些类的Load方法来实现,传入文件的路径或者一个Stream对象。
  2. 获取根节点:

    • 通过DocumentElement属性(对于XmlDocument)或者Root属性(对于XDocument)来获取XML文档的根节点。
  3. 遍历节点:

    • 使用循环结构遍历根节点的子节点。如果XML结构更为复杂,可能需要嵌套循环或递归方法来遍历子节点的子节点等。
  4. 读取节点信息:

    • 根据节点的类型或名称获取所需的信息。这可能包括节点的文本内容(通常是InnerTextValue属性)以及节点的属性(可以通过Attributes集合或直接访问特定属性)。
  5. 对象映射:

    • 将读取的XML数据映射到对象属性。创建对象实例,根据XML节点的内容来设置对象的属性。这个步骤通常需要你有一个与XML数据结构相对应的对象模型。
  6. 填充数据结构:

    • 如果要处理多个相似的节点(例如,在XML中表示多个学生的多个Student节点),则可以创建对象的集合,如List<T>。读取每个节点的信息,创建并填充对象实例,然后将对象添加到集合中。
  7. 绑定到用户界面(可选):

    • 将对象集合绑定到用户界面控件,如在Windows窗体中的DataGridView。这允许自动地将集合中的数据显示在用户界面上。
  8. 异常处理(建议):

    • 添加异常处理逻辑来捕获并处理可能发生的任何错误,例如文件找不到、文件损坏或XML结构不匹配等异常情况。

接下来我们就按照这个步骤完后读取xml文件的任务。

2.1加载XML文件

XmlDocument xml_Doc = new XmlDocument();  //【1】创建XML文档操作对象
xml_Doc.Load("StuScore.xml");  //【2】加载XML文件到文档对象中(路径)

我们先实例化一个XmlDocument对象,名为xml_Doc。XmlDocument是.NET框架中的一个类,它提供了一个表示XML文档的对象模型。这个类可以用来加载、编辑和保存XML文档。此时,xml_Doc是一个空的XML文档对象,还没有加载任何数据。

接下来我们使用了xml_Doc对象(其实还是XmlDocument的方法)的Load方法,以加载一个名为"StuText.xml"的XML文件。这里的字符串"StuText.xml"指定了XML文件的名称和路径。如果没有指定路径,程序将在应用程序的当前工作目录中查找该文件。(这里就是文件在程序目录中,所以没有具体路径)。
当调用Load方法时,会有下面几种情况:

XmlDocument对象xml_Doc会尝试找到并打开指定的XML文件。
如果成功找到并能够访问该文件,XmlDocument将读取文件的内容,并基于这些内容构建内部的DOM(文档对象模型)树。这个DOM树是一个节点的层次结构,它表示XML文档的结构,可以通过程序进行查询和修改。
如果在加载过程中发现任何语法错误(比如不匹配的标签、不正确的属性格式等),将抛出一个XmlException异常,所以需要在调用Load方法的代码周围添加相应的异常处理逻辑(try-catch块)来捕获并处理这些异常。
加载完毕后,可以通过xml_Doc对象访问和操作XML文档的内容。例如,可以读取特定的节点、属性或进行其他的查询和修改操作。这些操作可以用来提取数据,或者在内存中对XML文档进行更改,并最终将更改写回到文件或其他输出流中。

2.2 获取根节点、读取信息、对象映射、填充结构,绑定用户界面

 XmlNode rootNode = xml_Doc.DocumentElement;  //【3】获取XML文档根目录

这行代码是在加载XML文档后,从XmlDocument对象中获取文档的根元素(root element)。根元素是XML文档结构的最顶层元素,也就是所有其他元素的父元素。

在这里:

  • xml_Doc是前面代码中创建并加载了XML文件内容的XmlDocument对象。
  • DocumentElementXmlDocument类的一个属性,它返回一个XmlElement对象,该对象代表文档的根元素。
    因为xml其实是一个树结构
    在这里插入图片描述

rootNode变量现在包含了对XML文档根元素的引用。持有这个引用之后,就可以遍历整个XML文档的元素,因为所有的节点都是从这个根元素开始嵌套的。我们可以使用这个引用来访问、修改或查询XML文档的各个部分。例如,我们可以访问根节点的子节点、属性等等。

2.3 遍历节点、

 List<Student> list = new List<Student>();//创建对象集合         
            foreach (XmlNode stuNode in rootNode.ChildNodes)  //【4】遍历根节点(根节点包含所有节点)
            {
                if (stuNode.Name == "Student")
                {
                    Student xml_Stu = new Student();
                    foreach (XmlNode subNode in stuNode)  //【5】遍历子节点
                    {
                        switch (subNode.Name)//根据子节点的名称封装到对象的属性
                        {
                            case "StuName":
                                xml_Stu.StuName = subNode.InnerText;//获取《节点名称》对应的《节点值》
                                break;
                            case "StuAge":
                                xml_Stu.StuAge = Convert.ToInt16(subNode.InnerText);
                                break;
                            case "Gender":
                                xml_Stu.Gender = subNode.InnerText;
                                break;
                            case "ClassName":
                                xml_Stu.ClassName = subNode.InnerText;
                                break;
                        }
                    }
                    list.Add(xml_Stu);
                }
            }
            this.dgvStuList.DataSource = list;

这段代码是在C#中使用的,它展示了如何从XML文档中读取数据并将这些数据封装到一个对象列表中。接着,将这个列表设置为数据网格视图控件(也就是我们的显示窗口)的数据源,以便在用户界面上展示数据。
首先我们创建了一个名为list的新列表,这个列表用来存储Student类型的对象。Student是我们自定义的类,它有StuName(姓名)、StuAge(年龄)、Gender(性别)和ClassName(班级)等属性。
foreach (XmlNode stuNode in rootNode.ChildNodes)
该循环遍历前面提到的根节点的直接子节点。这里,stuNode代表当前遍历到的子节点。循环的每次迭代都会处理一个子节点。
//
//
这里插播一条直接子节点:
"直接子节点"是一个术语,用来描述在一个文档对象模型(DOM)树中,某个节点下一级的节点。在XML或HTML文档中,一个节点(例如一个元素)可以有子节点,这些子节点可以是元素节点、文本节点、注释节点等等。

以XML为例,考虑以下简单的结构:

<Parent>
    <Child>First child</Child>
    <Child>Second child</Child>
</Parent>

在这个例子中,<Parent>元素有两个直接子节点,都是<Child>元素。这些<Child>元素是<Parent>元素的直接子节点,因为它们是<Parent>下第一层的节点。如果这些<Child>元素内部还有其他元素,则这些内部元素将被视为<Child>元素的直接子节点,而不是<Parent>的直接子节点。

在处理DOM时,能够区分"直接子节点"(也就是某个特定节点的第一级子节点)与所有后代节点(即所有层级的子节点)是很重要的,因为它们之间的关系会影响你如何设计代码来遍历和操作DOM。
///
///

if (stuNode.Name == "Student")

在遍历子节点时,代码检查节点的名称是否为"Student"。如果是,这意味着这个节点包含了一个学生对象的数据。

Student xml_Stu = new Student();

一旦找到一个名为"Student"的节点,代码就会创建一个新的Student对象实例,名为xml_Stu。

foreach (XmlNode subNode in stuNode) //【5】遍历Student节点的子节点

接着,代码遍历"Student"节点的所有子节点,这些子节点包含了关于学生的具体信息,如姓名、年龄等。

switch (subNode.Name)
{
    // ...
}

在此switch语句中,代码根据子节点的名称来判断应该将节点内的文本(InnerText)赋值给xml_Stu对象的哪个属性。例如,如果子节点的名称是"StuName",则将它的文本内容赋值给xml_Stu对象的StuName属性。

list.Add(xml_Stu);

一旦填充完xml_Stu对象的所有属性,这个对象就会被添加到list列表中。

this.dgvStuList.DataSource = list;

最后,list列表被设置为名为dgvStuList的数据网格视图控件的数据源。dgvStuList是一个Windows窗体应用程序中的控件,用于显示数据。这样设置后,dgvStuList将显示list列表中的所有学生信息。

总之呢,这段代码的作用是将XML文档中特定结构的数据(在这个例子中是学生信息)读取出来,创建对应的C#对象列表,并将这些数据展示在用户界面上。

2.4例子源代码

链接:https://pan.baidu.com/s/1fSmI2USsrVWHxh5zXtQWYg?pwd=1234
提取码:1234

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值