C# XmlReader与XmlWriter流式读写XML操作指南
在.NET开发中,处理大型XML文件时推荐使用流式读写器以避免内存溢出。XmlReader提供只进、非缓存的快速读取能力,而XmlWriter则用于高效生成XML流。本文将演示如何通过配置XmlReaderSettings增强安全性与功能,并遍历不同节点类型;同时介绍使用XmlWriter创建结构良好且格式整洁的XML文档的具体步骤。
结果或目标
本教程旨在帮助开发者掌握C#中基于流的XML处理核心类:System.Xml.XmlReader和System.Xml.XmlWriter。前者采用提取模式(Pull Pattern),允许按需获取数据,适合状态管理复杂的场景;后者以快速、非缓存的方式生成XML,适合构建包含大量数据的输出流。相比传统的DOM加载方式,这两种方法显著降低了内存消耗并提升了I/O性能。
准备条件
在进行操作前,请确保环境满足以下要求:
- 运行环境:.NET Framework 或 .NET Core/.NET 5+ 项目。
- 命名空间引用:需添加
using System.Xml;以访问相关类。 - 配置文件:准备一个待解析的本地XML文件(如
books.xml),或指定输出路径。
真实操作顺序
第1步:配置并使用XmlReader读取XML节点
目的:安全地打开XML文件,并根据节点类型(元素、文本、注释等)输出内容。
入口:通过静态工厂方法XmlReader.Create()初始化。
动作与参数:
- 设置选项:实例化
XmlReaderSettings对象,根据需求配置属性,例如ProhibitDtd = false以允许DTD处理。 - 创建读取器:调用
XmlReader.Create(path, settings)传入文件路径和设置。 - 循环读取:使用
reader.Read()推进游标。在while循环中检查reader.NodeType,匹配枚举值如XmlNodeType.Element。 - 属性处理:若节点为元素且有属性(
reader.HasAttributes),内部嵌套循环reader.MoveToNextAttribute()提取名称与值。 - 资源释放:在
finally块中务必调用reader.Close()。
重要逻辑说明:由于读取是“只进”的,必须按顺序消费节点。对于DocumentType或CData等特殊节点需单独处理逻辑。
// ReadXml.cs
// XmlReader示例 - 演示如何解析并打印每个节点的结构
using System;
using System.Xml;
class Test
{
public static void Main(string[] args)
{
// 替换为你的实际测试路径
string path = @"G:\资料\C#面向对象编程\C#面向对象编程\CSharp\Chapter17\books.xml";
XmlReader reader = null;
try
{
// 1. 创建并配置 Settings
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false; // 允许 DTD 处理
// 2. 创建 Reader
reader = XmlReader.Create(path, settings);
ReadXml(reader); // 执行自定义读取逻辑
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (reader != null) reader.Close();
}
}
private static void ReadXml(XmlReader reader)
{
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.IsEmptyElement)
{
Console.WriteLine("<{0}/>", reader.Name);
}
else
{
Console.Write("<{0}", reader.Name);
if (reader.HasAttributes)
{
while (reader.MoveToNextAttribute())
{
Console.Write(" {0}=\"{1}\"", reader.Name, reader.Value);
}
}
Console.WriteLine(">");
}
break;
case XmlNodeType.Text:
Console.WriteLine(reader.Value);
break;
case XmlNodeType.CDATA:
Console.WriteLine("<![CDATA[{0}]]>", reader.Value);
break;
case XmlNodeType.ProcessingInstruction:
Console.WriteLine("<?{0} {1}?>", reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
Console.WriteLine("<!--{0}-->", reader.Value);
break;
case XmlNodeType.XmlDeclaration:
Console.WriteLine("<?xml version='1.0'?>");
break;
case XmlNodeType.DocumentType:
Console.WriteLine("<!DOCTYPE {0} [{1}]>", reader.Name, reader.Value);
break;
case XmlNodeType.EntityReference:
Console.WriteLine(reader.Name);
break;
case XmlNodeType.EndElement:
Console.WriteLine("</{0}>", reader.Name);
break;
case XmlNodeType.Document:
break;
}
}
}
}
完成判断:控制台能正确输出XML中的标签结构、属性及内容,无异常抛出。
第2步:配置并使用XmlWriter生成XML文件
目的:创建一个格式化良好的XML文件,写入书籍列表信息。
入口:通过XmlWriter.Create()指定输出路径。
动作与参数:
- 设置格式:实例化
XmlWriterSettings,开启settings.Indent = true以实现代码缩进,使生成的XML更易读。 - 创建编写器:调用
XmlWriter.Create(path, settings)。 - 写入逻辑:使用三个核心方法组合:
writer.WriteStartElement("name"):开始标签。writer.WriteValue(value):写入中间文本内容。writer.WriteEndElement():闭合当前层级标签。
- 闭合资源:操作结束后调用
writer.Close()。
using System.Xml;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string path = @"C:\Users\dell\Desktop\test.xml"; // 替换为你希望输出的路径
XmlWriter writer = null;
// 1. 设置 Writer 属性:启用缩进
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = " "; // 可选:设置具体的缩进字符
// 2. 创建 Writer
writer = XmlWriter.Create(path, settings);
// 3. 执行写入逻辑
WriteXml(writer);
// 4. 关闭 Writer (注意:Close前数据可能未完全刷盘)
writer.Close();
}
private static void WriteXml(XmlWriter writer)
{
// 根节点
writer.WriteStartElement("books");
// 插入子节点数据
WriteChildNode(writer, "红楼梦", "曹雪芹", "25");
WriteChildNode(writer, "三国演义", "罗贯中", "20");
WriteChildNode(writer, "水浒传", "施耐庵", "18");
WriteChildNode(writer, "聊斋志异", "蒲松龄", "16");
// 闭合根节点
writer.WriteEndElement();
}
private static void WriteChildNode(XmlWriter writer, string title, string author, string price)
{
writer.WriteStartElement("book");
// Title 节点
writer.WriteStartElement("title");
writer.WriteValue(title);
writer.WriteEndElement();
// Author 节点
writer.WriteStartElement("author");
writer.WriteValue(author);
writer.WriteEndElement();
// Price 节点
writer.WriteStartElement("price");
writer.WriteValue(price);
writer.WriteEndElement();
writer.WriteEndElement(); // 闭合 book
}
}
}
完成判断:在指定目录成功生成.xml文件,且文件内容缩进整齐,无语法错误。
完成判断
- 读取端:程序能稳定读取指定路径的XML,并在控制台逐行展示所有节点结构。
- 写入端:生成的XML文件不仅符合W3C标准,且具有良好的可读性缩进。
- 注意事项:
XmlReader和XmlWriter均为“只进”模式。调用Close()方法前,底层缓冲区中的数据通常不会被立即持久化或完全刷新,因此必须保证在最后时刻调用关闭操作。
简要总结
以上就是C#中基于流的XmlReader与XmlWriter操作XML文件的详细内容。XmlReader擅长处理只读流并支持多种节点类型的灵活提取,而XmlWriter则是构建结构化数据的高效工具。掌握这两个类的配置与核心API,可以应对大多数高性能XML处理需求。更多关于C#高级特性的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













