在 .NET 中使用 C# 读写 XML 文档
在本文中,您将了解到如何使用 C# 语言在 Microsoft .NET 框架中读取和写入 XML 文档。首先,我们会讨论 .NET 框架中与 XML 相关的命名空间和类。然后,我们将展示如何读取和写入 XML 文档。最后,我们会介绍如何利用 ADO.NET 和 XML .NET 模型来从关系数据库中读写 XML 文档,反之亦然。
一、.NET 框架中的 XML 命名空间和类
1.1 .NET 提供的 XML 命名空间
在开始处理 .NET 框架中的 XML 文档之前,了解 .NET 运行时库提供的命名空间和类是非常重要的。.NET 框架提供了五个与 XML 相关的命名空间:System.Xml、System.Xml.Schema、System.Xml.Serialization、System.Xml.XPath 和 System.Xml.Xsl。
1.1.1 System.Xml 命名空间
这个命名空间包含主要的 XML 类。它提供了许多用于读取和写入 XML 文档的类。我们将会专注于阅读器(reader)和写入器(writer)类。这些类用于读取和写入 XML 文档。
-
XmlReader
: 抽象基类,包含读取文档的方法和属性。 -
XmlTextReader
: 用于读取文本。 -
XmlValidatingReader
: 用于验证读取的数据。 -
XmlNodeReader
: 用于读取节点。 -
XmlWriter
: 用于写入数据到 XML 文档。 -
XmlTextWriter
: 用于写入 XML 文档的文本表示形式。
1.1.2 XmlReader 类
XmlReader
类是一个抽象基类,它包含了用于读取文档的方法和属性。例如,Read
方法读取流中的一个节点。此外,这个类还包含了导航文档节点的方法,如 MoveToAttribute
、MoveToFirstAttribute
、MoveToContent
、MoveToFirstContent
、MoveToElement
和 MoveToNextAttribute
。ReadString
、ReadInnerXml
、ReadOuterXml
和 ReadStartElement
是其他一些读取方法。这个类还有一个叫做 Skip
的方法用来跳过当前节点并移动到下一个节点。
1.1.3 XmlWriter 类
XmlWriter
类提供了写入 XML 文档项的方法。它是 XmlTextWriter
类的基础类。
1.1.4 XmlNode 类
XmlNode
类代表 XML 中的一个单个节点,它可以是 XML 文档的根节点,也可以代表整个文件。这是一个抽象基类,用于插入、删除和替换节点,以及导航文档。XmlNode
的派生类包括 XmlDocument
、XmlDataDocument
和 XmlDocumentFragment
。XmlDocument
类代表一个 XML 文档,并提供加载和保存文档的方法。Load
和 LoadXml
方法用于加载 XML 文档,而 Save
方法则用于保存文档。XmlDocumentFragment
类代表一个文档片段,可以添加到文档中。XmlDataDocument
类提供了与 ADO.NET 数据集对象一起工作的方法和属性。
二、读取 XML 文档
2.1 使用 XmlTextReader 读取 XML 文件
在我们的示例应用中,我将使用 books.xml
文件来读取并显示其数据。此文件随 VS.NET 示例一同提供。您可以在此机器上查找该文件并更改以下行中的文件路径:
// 创建一个 XmlTextReader 实例并指定文件路径
XmlTextReader textReader = new XmlTextReader("C:\\books.xml");
2.2 读取 XML 文件并显示内容
下面的例子展示了如何使用 XmlTextReader
类逐个读取 XML 文件的节点,直到文件结束,并将内容显示到控制台输出。
using System;
using System.Xml;
namespace ReadXml1 {
class Program {
static void Main(string[] args) {
// 创建一个 XmlTextReader 实例并指定文件路径
XmlTextReader textReader = new XmlTextReader("C:\\books.xml");
// 开始读取文件
textReader.Read();
// 如果节点有值
while (textReader.Read()) {
// 移动到第一个元素
textReader.MoveToElement();
// 显示 XmlTextReader 属性测试
Console.WriteLine("XmlTextReader Properties Test");
Console.WriteLine("===================");
// 读取该元素的属性并将其显示在控制台上
Console.WriteLine("Name:" + textReader.Name);
Console.WriteLine("Base URI:" + textReader.BaseURI);
Console.WriteLine("Local Name:" + textReader.LocalName);
Console.WriteLine("Attribute Count:" + textReader.AttributeCount.ToString());
Console.WriteLine("Depth:" + textReader.Depth.ToString());
Console.WriteLine("Line Number:" + textReader.LineNumber.ToString());
Console.WriteLine("Node Type:" + textReader.NodeType.ToString());
Console.WriteLine("Value:" + textReader.Value.ToString());
}
}
}
}
2.3 节点类型的统计
在这个示例中,我们将读取 XML 文件并使用 XmlTextReader
类逐个读取其节点直到文件结束。读取每个节点后,检查其 NodeType
属性以确定节点类型,并将节点内容写入控制台,同时记录特定类型节点的数量。最后,显示文档中不同类型的节点总数。
using System;
using System.Xml;
namespace ReadingXML2 {
class Program {
static void Main(string[] args) {
int ws = 0; // 白空格节点计数
int pi = 0; // 处理指令节点计数
int dc = 0; // 文档类型节点计数
int cc = 0; // 注释节点计数
int ac = 0; // 属性节点计数
int et = 0; // 实体节点计数
int el = 0; // 元素节点计数
int xd = 0; // XML 声明节点计数
// 创建一个 XmlTextReader 实例并指定文件路径
XmlTextReader textReader = new XmlTextReader("C:\\books.xml");
// 读取直到文件末尾
while (textReader.Read()) {
XmlNodeType nType = textReader.NodeType;
// 如果节点类型为声明
if (nType == XmlNodeType.XmlDeclaration) {
Console.WriteLine("Declaration:" + textReader.Name.ToString());
xd++;
}
// 如果节点类型为注释
if (nType == XmlNodeType.Comment) {
Console.WriteLine("Comment:" + textReader.Name.ToString());
cc++;
}
// 如果节点类型为属性
if (nType == XmlNodeType.Attribute) {
Console.WriteLine("Attribute:" + textReader.Name.ToString());
ac++;
}
// 如果节点类型为元素
if (nType == XmlNodeType.Element) {
Console.WriteLine("Element:" + textReader.Name.ToString());
el++;
}
// 如果节点类型为实体
if (nType == XmlNodeType.Entity) {
Console.WriteLine("Entity:" + textReader.Name.ToString());
et++;
}
// 如果节点类型为处理指令
if (nType == XmlNodeType.ProcessingInstruction) {
Console.WriteLine("Process Instruction:" + textReader.Name.ToString());
pi++;
}
// 如果节点类型为文档
if (nType == XmlNodeType.DocumentType) {
Console.WriteLine("Document:" + textReader.Name.ToString());
dc++;
}
// 如果节点类型为空白
if (nType == XmlNodeType.Whitespace) {
ws++;
}
}
// 打印各种节点的总数
Console.WriteLine($"Total WhiteSpaces: {ws}");
Console.WriteLine($"Total ProcessingInstructions: {pi}");
Console.WriteLine($"Total Comments: {cc}");
Console.WriteLine($"Total Attributes: {ac}");
Console.WriteLine($"Total Elements: {el}");
Console.WriteLine($"Total Entities: {et}");
Console.WriteLine($"Total DocumentTypes: {dc}");
Console.WriteLine($"Total XmlDeclarations: {xd}");
}
}
}
三、从关系数据库读取 XML 文档
3.1 从数据库读取数据并写入 XML 文件
在本示例中,我们首先创建一个连接到 Northwind 数据库的连接,然后使用一个数据适配器对象通过传递一个 SELECT SQL 查询和连接来填充数据集对象。一旦有了数据适配器,就可以使用它的 Fill
方法填充一个数据集对象。然后,使用 DataSet
的 WriteXml
方法创建一个 XML 文档并将内容写入 XML 文件。在本示例中,我们读取 Customers 表中的记录,并将数据集内容写入 C:\ 目录下的 OutputXml.xml 文件。
using System;
using System.Xml;
using System.Data;
using System.Data.OleDb;
namespace ReadingXML2 {
class Program {
static void Main(string[] args) {
// 创建一个数据库连接
OleDbConnection con = new OleDbConnection();
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Northwind.mdb";
// 创建一个数据适配器
OleDbDataAdapter da = new OleDbDataAdapter("Select * from Customers", con);
// 创建一个新的数据集
DataSet ds = new DataSet();
// 填充数据集
da.Fill(ds, "Customers");
// 通过调用 WriteXml 方法将数据集内容写入 XML 文件
ds.WriteXml("C:\\OutputXML.xml");
}
}
}
四、总结
.NET 框架库提供了良好的支持来处理 XML 文档。XmlReader
、XmlWriter
及其派生类包含用于读取和写入 XML 文档的方法和属性。借助 XmlDocument
和 XmlDataDocument
类,您可以读取整个文档。XmlDocument
的 Load
和 Save
方法分别用于加载读取器或文件和保存文档。ADO.NET 提供了使用数据提供者和 DataSet
对象从数据库读取并将内容写入 XML 文档的功能。