C#操作XML文件 C#如何使用XmlDocument读写XML

来源:这里教程网 时间:2026-02-21 17:41:29 作者:

XmlDocument.Load() 读取 XML 文件时路径错误或编码异常

常见报错是

System.IO.FileNotFoundException
System.Text.Encoding.GetEncoding()
抛出异常,本质是路径没找到,或文件用了 UTF-8 with BOM / GB2312 等非默认编码但未显式指定。

用绝对路径或确保相对路径基于
AppDomain.CurrentDomain.BaseDirectory
计算,比如:
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.xml")
若 XML 声明含
<?xml version="1.0" encoding="GB2312"?>
,直接
doc.Load(path)
会失败;改用
XmlReader.Create()
并传入对应
Encoding
var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore };
using var reader = XmlReader.Create(path, new XmlReaderSettings { Encoding = Encoding.GetEncoding("GB2312") });
var doc = new XmlDocument();
doc.Load(reader);

用 SelectSingleNode() 和 GetElementsByTagName() 区分使用场景

SelectSingleNode()
支持 XPath,适合精确定位;
GetElementsByTagName()
返回所有同名节点,不支持条件过滤,性能略高但灵活性差。

要找
<user id="1001"></user>
:用
doc.SelectSingleNode("//user[@id='1001']")
只要所有
<name></name>
节点:用
doc.GetElementsByTagName("name")
更快,且返回
XmlNodeList
可直接遍历
XPath 中注意引号嵌套:属性值含单引号时,改用双引号包裹 XPath 字符串,或用
@attr='value'
配合
string.Format()
拼接(需防注入)

修改节点内容后调用 Save() 却没生效?

常见原因是只改了

InnerText
却忘了节点本身是只读的(比如来自
GetElementsByTagName()
的只读集合),或保存路径权限不足、文件被其他进程占用。

务必检查节点是否可编辑:
node.ParentNode != null && node.OwnerDocument != null
修改文本优先用
node.InnerText = "new value"
,而非直接赋值给
node.FirstChild.Value
(可能为 null)
保存前确认目录存在:
Directory.CreateDirectory(Path.GetDirectoryName(savePath))
若 XML 文件正被记事本、VS 等打开,
Save()
会抛
UnauthorizedAccessException
,需先关闭外部程序

XmlDocument 不适合大文件,别硬扛超过 10MB

XmlDocument
是 DOM 模型,整个 XML 加载进内存构建树结构。10MB XML 往往膨胀到 50MB+ 托管堆内存,且 GC 压力明显。

读大文件优先考虑
XmlReader
流式解析,用
ReadToFollowing()
+
IsStartElement()
跳过无关节点
写大文件用
XmlWriter
,配合
WriteStartElement()
/
WriteElementString()
,避免拼接字符串
若必须用
XmlDocument
且节点不多,可先用
XmlReader
过滤出目标片段再 Load 到新 Document 中处理

DOM 操作看着简单,但节点引用、命名空间、空白文本节点(

XmlNodeType.Text
vs
XmlNodeType.Whitespace
)这些细节,一不留神就让
FirstChild
返回 null 或删错内容。

相关推荐