由於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 }