664 字
3 分钟
WPF 进阶:使用 XmlDocument 实现 XML 文件的深度读写

1. 概述#

在 WPF 开发中,XML 常用于存储本地配置、离线数据或简单的报文交互。虽然现代开发中 JSON 流行,但 XML 在处理具有复杂嵌套关系的结构化数据时依然具有无可比拟的优势。

本文将通过封装 XmlReader(读取流)和 XmlWriter(写入流)两个工具类,演示如何快速操作 XML 文档对象模型 (DOM)。


2. 封装 XmlReader:高效检索数据#

XmlReader 类封装了常用的 Xpath 检索和节点转换逻辑。

using System.Xml;
namespace WpfApp4
{
public static class XmlReader
{
private static XmlDocument _doc = new XmlDocument();
/// <summary>
/// 加载XML文件
/// </summary>
public static void LoadXml(string url)
{
if (System.IO.File.Exists(url))
_doc.Load(url);
}
public static XmlElement GetRoot() => _doc.DocumentElement;
/// <summary>
/// 获取指定节点的属性值
/// </summary>
public static string GetAttribute(XmlNode node, string attrName)
{
return (node as XmlElement)?.GetAttribute(attrName) ?? string.Empty;
}
/// <summary>
/// 使用 XPath 获取子节点的文本内容
/// </summary>
public static string GetNodeInnerText(XmlNode node, string childName)
{
return node.SelectSingleNode(childName)?.InnerText ?? string.Empty;
}
}
}

3. 封装 XmlWriter:构建结构化文档#

XmlWriter 简化了节点的创建与层级挂载。

using System.Xml;
namespace WpfApp4
{
public static class XmlWriter
{
private static XmlDocument _doc = new XmlDocument();
public static void InitializeDoc() => _doc = new XmlDocument();
/// <summary>
/// 创建并挂载根节点
/// </summary>
public static XmlElement CreateRoot(string rootName)
{
InitializeDoc();
XmlElement root = _doc.CreateElement(rootName);
_doc.AppendChild(root);
return root;
}
/// <summary>
/// 为节点添加属性
/// </summary>
public static void AddAttribute(XmlElement element, string name, string value)
{
XmlAttribute attr = _doc.CreateAttribute(name);
attr.Value = value;
element.Attributes.Append(attr);
}
/// <summary>
/// 创建子节点
/// </summary>
public static XmlNode CreateNode(string name, string text)
{
XmlNode node = _doc.CreateElement(name);
node.InnerText = text;
return node;
}
/// <summary>
/// 保存并添加 XML 声明
/// </summary>
public static void Save(string path)
{
if (_doc.FirstChild.NodeType != XmlNodeType.XmlDeclaration)
{
XmlDeclaration dec = _doc.CreateXmlDeclaration("1.0", "UTF-8", null);
_doc.InsertBefore(dec, _doc.DocumentElement);
}
_doc.Save(path);
}
}
}

4. 前端界面与交互逻辑#

XAML 布局#

<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Content="一键生成国家数据" Click="btnCreatXml" Margin="10" Padding="10"/>
<Button Content="读取第一个首都" Click="btnReadXml" Margin="10" Padding="10"/>
</StackPanel>

后台逻辑实现#

private void btnCreatXml(object sender, RoutedEventArgs e)
{
try
{
XmlElement root = XmlWriter.CreateRoot("WorldData");
// 数据准备
var countries = new[] {
new { Name = "中国", Capital = "北京" },
new { Name = "美国", Capital = "华盛顿" }
};
foreach (var c in countries)
{
XmlElement node = (XmlElement)XmlWriter.CreateNode("Country", "");
XmlWriter.AddAttribute(node, "Name", c.Name);
XmlWriter.AddAttribute(node, "Capital", c.Capital);
root.AppendChild(node);
}
XmlWriter.Save("data.xml");
MessageBox.Show("XML 文件已成功创建于运行目录!");
}
catch (Exception ex)
{
MessageBox.Show($"写入错误: {ex.Message}");
}
}
private void btnReadXml(object sender, RoutedEventArgs e)
{
try
{
XmlReader.LoadXml("data.xml");
XmlElement root = XmlReader.GetRoot();
// 读取第一个子节点的属性
if (root?.HasChildNodes == true)
{
string capital = XmlReader.GetAttribute(root.FirstChild, "Capital");
MessageBox.Show($"读取到的首都是: {capital}");
}
}
catch (Exception ex)
{
MessageBox.Show($"读取错误: {ex.Message}");
}
}

5. 总结#

通过封装,我们将繁琐的 XML 节点操作抽象成了可读性更强的业务方法。在实际项目中,这种封装有助于统一 XML 格式,减少硬编码。

WPF 进阶:使用 XmlDocument 实现 XML 文件的深度读写
https://sw.rscclub.website/posts/wpfdqxml/
作者
杨月昌
发布于
2016-09-08
许可协议
CC BY-NC-SA 4.0