作者:陈广 日期:2019-7-5
XML 是指可扩展标记语言(Extensible Markup Language)。可以把它理解为一个极为简化的数据库,它主要用来存储数据,在一些简单的桌面应用中可以用来代替数据库存储数据。但 XML 又跟数据库有所不同。数据库不但存储数据,还自带有极为复杂的数据处理方法和手段。而 XML 只有数据,没有任何处理数据的手段。处理数据需要通过自行编程实现。
XML 最大的优势是使用文本来存储数据,即使是声音、图像这样的二进制数据,也可以使用文本的方式来存储。这带来了一些优势:
现阶段,XML 主要用来存储应用程序的配置文件,在编写 WPF 应用程序和 Android 应用程序时,您会发现,界面 UI 的编写就是使用 XML 来实现的。对于存储或传输数据来说,现在有了更好的选择 —— JSON。JSON(JavaScript Object Notation)和 XML 类似,但它的语法更为简化,占用存储空间更小,所以在传输数据时更有优势。但 XML 功能更为强大,在一些特殊的场合还是需要使用到 XML 的。
假设数据库里有一张存储学生信息的表,表结构和数据如下图所示:
ID | StuName | Sex | Birthday |
---|---|---|---|
20190101 | 张三 | 男 | 1991-1-1 |
20190102 | 李四 | 女 | 1990-2-1 |
20190103 | 王五 | 男 | 1992-3-1 |
20190104 | 马六 | 女 | 1991-4-1 |
如果这些数据使用 XML 来存储,该如何表示呢?新建一个文本文件,输入如下代码:
清单 2-1
<?xml version="1.0" encoding="utf-8" ?>
<StuInfo>
<Student ID="20190101" StuName="张三" Sex="男" Birthday=1991-1-1 />
<Student ID="20190102" StuName="李四" Sex="女" Birthday=1990-2-1/>
<Student ID="20190103" StuName="王五" Sex="男" Birthday=1992-3-1/>
<Student ID="20190104" StuName="马六" Sex="女" Birthday=1991-4-1/>
</StuInfo>
文档的第一行是 XML 声明,定义XML的版本和文档所用字体的编码。第二行定义了文档的根元素<StuInfo>
,可以称之为元素的开始标签。最后一行定义了根元素的结尾</StuInfo>
,称为结束标签,斜杠/
表明了一个元素的结尾。一个元素内可以嵌套其他元素,本例中,<StuInfo>
根元素中包含了四个<Student>
子元素,表示 4 个学生。
元素的开始标签内可以包含属性,以属性名称 = 属性值
的方式来表示,示例中的每个<Student>
元素都包含了ID
、StuName
、Sex
和Birthday
四个属性。如果元素内部无任何内容,可以在开始标签结尾处的尖括号前加/
表示该元素的结尾,这样可以省略单独的结束标签。如果元素内包含有内容,则结束标签不能省略。比如要给学生加入成绩信息,可以这样编写:
清单 2-2
<?xml version="1.0" encoding="utf-8" ?>
<StuInfo>
<Student ID="20190101" StuName="张三" Sex="男" Birthday=1991-1-1>
<程序设计基础 学期='2019春'>85</程序设计基础>
<单片机 学期='2019秋'>90</单片机>
<RFID 学期='2019秋'>76</RFID>
</Student>
</StuInfo>
将清单 2-1 所示的 XML 文档保存在 D 盘根目录下。新建一个控制台应用程序,输入如下代码:
清单 2-3
using System;
using System.Xml;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("D://StuTable.xml");
XmlNodeList nodes = xmlDoc.SelectNodes("StuInfo/Student");
foreach(XmlElement ele in nodes)
{
Console.Write(ele.GetAttribute("ID"));
Console.Write(" " + ele.GetAttribute("StuName"));
Console.Write(" " + ele.GetAttribute("Sex"));
Console.WriteLine(" " + ele.GetAttribute("Birthday"));
}
Console.ReadLine();
}
}
}
运行程序,结果如下:
20190101 张三 男 1991-1-1
20190102 李四 女 1990-2-1
20190103 王五 男 1992-3-1
20190104 马六 女 1991-4-1
上例使用了XmlDocument
来操作 XML 文档,也可以使用 LINQ 来操作 XML 文档。LINQ 全称是 Language Integrated Query,即语言集成查询,它将查询功能和语言结合起来,为我们提供一种统一的方式查询和操作各类数据,如 C# 中的集合、XML、以及各种数据库等。
更改控制台代码如下:
清单 2-4
using System;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
XDocument xDoc = XDocument.Load("D://StuTable.xml");
var query = xDoc.Descendants("Student")
.Select(item => new
{
ID = item.Attribute("ID"),
StuName = item.Attribute("StuName"),
Sex = item.Attribute("Sex"),
Birthday = item.Attribute("Birthday")
});
foreach (var item in query)
{
Console.Write(item.ID.Value);
Console.Write(" " + item.StuName.Value);
Console.Write(" " + item.Sex.Value);
Console.WriteLine(" " + item.Birthday.Value);
}
Console.ReadLine();
}
}
}
运行程序,可以看到结果是一样的。可能您会觉得使用 LINQ 后代码变得更多了,但在进行复杂查询时,方能感受到 LINQ 的强大之处。为演示复杂查询,接下来在 XML 文档中存入更多信息。将 XML 文档内容更改如下:
清单 2-5
<?xml version="1.0" encoding="utf-8" ?>
<StuInfo>
<Student>
<ID>20190101</ID>
<StuName>张三</StuName>
<Sex>男</Sex>
<Phone Type="Home">0771-2345678</Phone>
<Phone Type="mobile ">18077156565</Phone>
<Native>
<Province>广西</Province>
<City>南宁</City>
</Native>
</Student>
<Student>
<ID>20190102</ID>
<StuName>李四</StuName>
<Sex>女</Sex>
<Phone Type="Home">0771-2225678</Phone>
<Phone Type="mobile ">18177632323</Phone>
<Native>
<Province>广西</Province>
<City>南宁</City>
</Native>
</Student>
<Student>
<ID>20190103</ID>
<StuName>王五</StuName>
<Sex>男</Sex>
<Phone Type="Home">0771-2668765</Phone>
<Phone Type="mobile ">13877638383</Phone>
<Native>
<Province>广西</Province>
<City>桂林</City>
</Native>
</Student>
<Student>
<ID>20190104</ID>
<StuName>马六</StuName>
<Sex>女</Sex>
<Phone Type="Home">0771-2778765</Phone>
<Phone Type="mobile ">13077169696</Phone>
<Native>
<Province>广西</Province>
<City>桂林</City>
</Native>
</Student>
</StuInfo>
清单 2-5 中给每个学生增加了电话和籍贯的信息,这一次,学号和姓名等信息并不是使用属性的方式表示,而是使用了元素来表示。这表明了 XML 表示数据的方式并不受限,具体使用属性还是元素来表示一个数据,可根据实际情况来灵活运用。
接下来查询籍贯为 “广西南宁” 的所有女生信息,将 C# 代码更改如下:
清单 2-6
XDocument xDoc = XDocument.Load("D://StuTable.xml");
var query = xDoc.Descendants("Student")
.Where(item =>
item.Element("Native").Element("Province").Value == "广西"
&& item.Element("Native").Element("City").Value == "南宁"
&& item.Element("Sex").Value == "女"
)
.Select(item => new
{
ID = item.Element("ID").Value,
StuName = item.Element("StuName").Value,
Sex = item.Element("Sex").Value,
Native = item.Element("Native").Element("Province").Value +
item.Element("Native").Element("City").Value
});
foreach (var item in query)
{
Console.Write(item.ID);
Console.Write(" " + item.StuName);
Console.Write(" " + item.Sex);
Console.WriteLine(" " + item.Native);
}
运行结果:
20190102 李四 女 广西南宁
本例使用了三个条件来限定查询结果,代码非常简洁,甚至如果要对结果进行排序或返回指定数量的前几条记录,对 LINQ 来说只需要加一句代码便可实现。总之 LINQ 是一个非常强大的工具,这里只介绍简单用法以方便读者管中窥豹。如需要做进一步了解,请在网上查找相关资料进行学习。
;