使用C#读写xml文件
由于xml文件的易读特性,使得它非常适合作为程序配置文件。和ini文件相比,xml文件可以实现列表等复杂参数配置,灵活性比较大。
使用C#读取xml文件,首先要加载xml文件获取XmlDocument对象,然后通过该对象获取XmlNode类型的根节点,之后再对根节点获取相应子节点的属性或值。写入xml文件时,获取对应的节点后设置其属性或者值即可。
本文对C#操作xml文件进行了封装处理,方便代码复用。
1、xml文件内容
<?xml version="1.0" encoding="utf-8"?> <AppSettings> <!-- 调试模式:0-否,1-是 --> <DebugMode>0</DebugMode> <!-- FTP服务器参数 --> <FTP IP="127.0.0.1" Port="21" UserName="user" Password="user"/> <!-- 学生信息:Grade-年级,Class-班级 --> <Students Grade="1" Class="7"> <!-- 学生:Name-姓名,Age-年龄 --> <Student Name="Name1" Age="6"/> <Student Name="Name2" Age="7"/> <Student Name="Name3" Age="7"/> <Student Name="Name4" Age="6"/> </Students> </AppSettings>
2、XmlHelper.cs
public static class XmlHelper { public static bool GetNodeInnerInt(XmlNode node, string xpath, out int value) { var text = node?.SelectSingleNode(xpath)?.InnerText.Trim(); return int.TryParse(text, out value); } public static bool GetNodeInnerStr(XmlNode node, string xpath, out string value) { value = node?.SelectSingleNode(xpath)?.InnerText.Trim(); return !string.IsNullOrEmpty(value); } public static void SetNodeInnerValue(XmlNode node, string xpath, string text) { var item = node?.SelectSingleNode(xpath); if (item != null) { item.InnerText = text; } } public static bool GetNodeAttributeInt(XmlNode node, string xpath, out int value) { var text = node?.Attributes?.GetNamedItem(xpath)?.Value.Trim(); return int.TryParse(text, out value); } public static bool GetNodeAttributeStr(XmlNode node, string xpath, out string value) { value = node?.Attributes?.GetNamedItem(xpath)?.Value.Trim(); return !string.IsNullOrEmpty(value); } public static void SetNodeAttributeValue(XmlNode node, string xpath, string text) { var item = node?.Attributes?.GetNamedItem(xpath); if (item != null) { item.Value = text; } } }
3、XmlConfigManager.cs
internal class StudentInfo { public string Name { get; set; } public int Age { get; set; } public StudentInfo(string name, int age) { Name = name; Age = age; } } internal class ClassInfo { public int Grade { get; set; } public int Class { get; set; } public List<StudentInfo> StudentInfoList { get; } public ClassInfo() { StudentInfoList = new List<StudentInfo>(); } } internal sealed class XmlConfigManager { public bool DebugMode { get; private set; } //调试模式 public ClassInfo ClassInfo { get; } //班级信息 #region 数据库参数 public string DbIp { get; private set; } //数据库IP public int DbPort { get; private set; } = 1433; //数据库端口 public string DbCatalog { get; private set; } //数据库名称 public string DbUser { get; private set; } //数据库用户名 public string DbPassword { get; private set; } //数据库密码 public string ConnectionString => $@"data source={DbIp},{DbPort};initial catalog={DbCatalog};persist security info=True;user id={DbUser};password={DbPassword}"; #endregion private string _configName; private static readonly ILog Logger = LogManager.GetLogger(nameof(XmlConfigManager)); /// <summary> /// 初始化配置 /// </summary> public void LoadConfig(string configName) { _configName = configName; //Get Config file var info = new DirectoryInfo(Assembly.GetExecutingAssembly().Location); var xmlFilePath = Path.Combine(info.Parent?.FullName ?? string.Empty, _configName); //从配置文件读取数据 var xmlDoc = new XmlDocument(); try { xmlDoc.Load(xmlFilePath); } catch (Exception e) { Logger.Error($@"加载配置文件[{configName}]失败:{e.Message}."); return; } var root = xmlDoc.SelectSingleNode("/AppSettings"); LoadDebugModeConfig(root); //加载调试模式 LoadDatabaseConfig(root); //加载数据库参数 LoadClassInfoConfig(root); //加载班级信息 } #region 获取参数 private void LoadDebugModeConfig(XmlNode root) { try { var node = root?.SelectSingleNode("Common"); if (XmlHelper.GetNodeInnerStr(node, "DebugMode", out var str)) { DebugMode = str == "1"; } } catch (Exception e) { Logger.Error($@"加载调试模式异常:{e.Message}."); } } private void LoadDatabaseConfig(XmlNode root) { try { var node = root?.SelectSingleNode("Database"); if (XmlHelper.GetNodeAttributeStr(node, "Ip", out var ip)) { DbIp = ip; } if (XmlHelper.GetNodeAttributeInt(node, "Port", out var port)) { DbPort = port; } if (XmlHelper.GetNodeAttributeStr(node, "Catalog", out var catalog)) { DbCatalog = catalog; } if (XmlHelper.GetNodeAttributeStr(node, "User", out var user)) { DbUser = user; } if (XmlHelper.GetNodeAttributeStr(node, "Password", out var password)) { DbPassword = password; } } catch (Exception e) { Logger.Error($@"加载数据库参数异常:{e.Message}."); } } private void LoadClassInfoConfig(XmlNode root) { try { var node = root?.SelectSingleNode("ClassInfo"); if (XmlHelper.GetNodeAttributeInt(node, "Grade", out var val)) { ClassInfo.Grade = val; } if (XmlHelper.GetNodeAttributeInt(node, "Class", out val)) { ClassInfo.Class = val; } var nodeList = node?.SelectNodes("Student"); if (nodeList == null || nodeList.Count == 0) { return; } foreach (XmlNode item in nodeList) { if (XmlHelper.GetNodeAttributeStr(item, "Name", out var str) && XmlHelper.GetNodeAttributeInt(item, "Age", out val)) { ClassInfo.StudentInfoList.Add(new StudentInfo(str, val)); } } } catch (Exception e) { Logger.Error($@"加载班级信息异常:{e.Message}."); } } #endregion #region 设置参数 public void SetDatabaseConfig(string ip, string catalog, string user, string password) { DbIp = ip; DbCatalog = catalog; DbUser = user; DbPassword = password; //Get Config file var info = new DirectoryInfo(Assembly.GetExecutingAssembly().Location); var xmlFilePath = Path.Combine(info.Parent?.FullName ?? string.Empty, _configName); //从配置文件读取数据 var xmlDoc = new XmlDocument(); try { xmlDoc.Load(xmlFilePath); var node = xmlDoc.SelectSingleNode("/AppSettings/Database"); XmlHelper.SetNodeAttributeValue(node, "Ip", ip); XmlHelper.SetNodeAttributeValue(node, "Catalog", catalog); XmlHelper.SetNodeAttributeValue(node, "User", user); XmlHelper.SetNodeAttributeValue(node, "Password", password); xmlDoc.Save(xmlFilePath); } catch (Exception e) { Logger.Error($@"设置数据库参数失败:{e.Message}."); throw; } } #endregion #region 单例模式 private static XmlConfigManager _instance; private static readonly object LockInstanceHelper = new object(); private XmlConfigManager() { ClassInfo = new ClassInfo(); } public static XmlConfigManager Instance { get { if (_instance != null) { return _instance; } lock (LockInstanceHelper) { _instance = _instance ?? new XmlConfigManager(); } return _instance; } } #endregion }