using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization; using System.IO; using System.Xml; namespace Utils.Files { /// /// 通过XML文件保存配置信息;读取通过XML文件保存配置信息 /// 只处理两级信息:根、根的下一级。如果有更多级,则读取的信息将会出错 /// /// 配置数据保存在类型为T的对象中 public class XmlConfig { /// /// 通过XML文件设置配置信息 /// /// 文件名(程序所在目录)或路径+文件名 /// 配置信息 public static void SetConfig(string fileName_pathAndFileName, T setting) { XmlSerializer ser = new XmlSerializer(typeof(T)); TextWriter wr = new StreamWriter(fileName_pathAndFileName); ser.Serialize(wr, setting); wr.Close(); } /// /// 获取所有配置信息。只包含两级信息,即:根、根的下一级 /// /// 文件名(程序所在目录)或路径+文件名 public static Dictionary GetAllConfigs(string fileName_pathAndFileName) { XmlDocument xmlDoc = Load(fileName_pathAndFileName); return GetAllConfigs(xmlDoc); } /// /// 获取所有配置信息。只包含两级信息,即:根、根的下一级 /// /// 读取出的xml文档信息 public static Dictionary GetAllConfigs(XmlDocument xmlDoc) { XmlNode rootNode = xmlDoc.ChildNodes[1];//根节点 return findChild(rootNode, true); } /// /// 向配置文件中增加配置信息。如果已存在,则为修改配置信息 /// /// 配置文件的文件名 /// 配置信息的名字 /// 配置信息的内容 public static void AddConfig(string fileName_pathAndFileName, string name, string value) { XmlDocument xmlDoc = Load(fileName_pathAndFileName); var configs = GetAllConfigs(xmlDoc); AddOrChange(xmlDoc, configs, name, value); xmlDoc.Save(fileName_pathAndFileName); } /// /// 向配置文件中增加配置信息。如果已存在,则为修改配置信息 /// /// 配置文件的文件名 /// 配置信息。key为名字,value为内容 public static void AddConfig(string fileName_pathAndFileName, Dictionary configs) { XmlDocument xmlDoc = Load(fileName_pathAndFileName); var oldConfigs = GetAllConfigs(xmlDoc); foreach (var config in configs) { AddOrChange(xmlDoc, oldConfigs, config.Key, config.Value); } xmlDoc.Save(fileName_pathAndFileName); } /// /// 获取指定的配置。没有则返回null /// /// 文件名(程序所在目录)或路径+文件名 /// 要获取的配置的名称 public static string GetConfig(string fileName_pathAndFileName, string name) { if (GetAllConfigs(fileName_pathAndFileName).Keys.Contains(name)) return GetAllConfigs(fileName_pathAndFileName)[name]; return null; } /// /// 获取指定的配置,结果为字符串数组。没有则返回空数组,即:{} /// /// 文件名(程序所在目录)或路径+文件名 /// 要获取的配置的名称 /// 配置内容 public static void GetConfig(string fileName_pathAndFileName, string name, out string[] values) { var valuesArr = GetConfig(fileName_pathAndFileName, name); if (!string.IsNullOrEmpty(valuesArr)) values = valuesArr.Split(','); else values = new string[] { }; } private static Dictionary findChild(XmlNode rootNode, bool includeEmpty) { Dictionary reslut = new Dictionary(); XmlNodeList list = rootNode.ChildNodes; if (list == null || list.Count == 0) return reslut; foreach (XmlNode node in list) { if (node.HasChildNodes && node.ChildNodes.Count > 0) { if (node.ChildNodes.Count == 1 && node.FirstChild.NodeType == XmlNodeType.Text) { reslut.Add(node.Name, node.InnerText); } else { throw new ApplicationException("配置不正确"); } } else { if (includeEmpty) reslut.Add(node.Name, node.InnerText); } } return reslut; } /// /// 从配置文件中读取信息。成功则返回true,并返回代表该配置文件的对象;文件不存在则返回false。 /// /// 配置文件的名称或路径名称 /// 代表读取出来的文件的对象 /// 成功则返回true,并返回代表该配置文件的对象;文件不存在则返回false。 protected static bool Load(string fileName_pathAndFileName, out XmlDocument xmlDoc) { xmlDoc = new XmlDocument(); try { xmlDoc.Load(fileName_pathAndFileName); } catch (FileNotFoundException) { return false; } return true; } /// /// 获取代表配置文件的对象。如果不存在,则创建空配置文件,并返回代表该配置文件的对象。 /// /// 文件名 protected static XmlDocument Load(string fileName_pathAndFileName) { XmlDocument xmlDoc; if (!Load(fileName_pathAndFileName, out xmlDoc)) {//当文件不存在时 Configs setting = new Configs(); XmlConfig.SetConfig(fileName_pathAndFileName, setting); Load(fileName_pathAndFileName, out xmlDoc); } return xmlDoc; } /// /// 添加或修改配置信息。添加、修改取决于name是否存在 /// 要使修改生效,还需要在调用该方法后,进行保存操作 /// /// 代表配置文件的对象 /// 从配置文件中读取出来的配置信息(用于方法内的查询) /// 配置名字 /// 配置对应的值 private static void AddOrChange(XmlDocument xmlDoc, Dictionary configs, string name, string value) { if (configs.Keys.Contains(name)) foreach (XmlNode node in xmlDoc.ChildNodes[1].ChildNodes) { if (node.Name == name) { node.InnerText = value; return; } } XmlNode rootNode = xmlDoc.ChildNodes[1];//根节点 XmlElement element = xmlDoc.CreateElement(name); element.InnerText = value; rootNode.AppendChild(element); } } #region public struct Configs//空结构,用于创建配置信息为空的配置文件(并不是什么信息都没有) { } public class XmlConfig : XmlConfig { public static Dictionary GetAllSystemConfigs(string fileName_pathAndFileName) { XmlDocument xmlDoc; return GetAllSystemConfigs(fileName_pathAndFileName, out xmlDoc); } private static Dictionary GetAllSystemConfigs(string fileName_pathAndFileName, out XmlDocument xmlDoc) { Dictionary result = new Dictionary(); //XmlDocument xmlDoc; if (Load(fileName_pathAndFileName, out xmlDoc)) { XmlNodeList list = xmlDoc.ChildNodes[1].ChildNodes; if (list == null || list.Count == 0) return new Dictionary(); foreach (XmlNode node in list) { if (node.Attributes.Count > 0) { TrinaryValue value = new TrinaryValue(); foreach (XmlAttribute attr in node.Attributes) { switch (attr.Name) { case "Name": value.Key = attr.Value; break; case "DisplayName": value.DisplayName = attr.Value; break; case "WebRoot": value.Value = attr.Value; break; default: break; } } if (value.Key.Length > 0) result.Add(value.Key, value); } } } return result; } public static void AddConfig(string fileName_pathAndFileName, TrinaryValue attributeValue) { XmlDocument xmlDoc; var configs = GetAllSystemConfigs(fileName_pathAndFileName, out xmlDoc); if (!configs.Keys.Contains(attributeValue.Key)) throw new ApplicationException("错误!\n要修改的项不存在!\n这个错误不应出现"); bool hasChanged = false; foreach (XmlNode node in xmlDoc.ChildNodes[1].ChildNodes) { if (hasChanged) break; foreach (XmlAttribute attr in node.Attributes) { if (attr.Name == "Name" && attr.Value == attributeValue.Key) { ChangeAttribute(node, attributeValue); hasChanged = true; } } } xmlDoc.Save(fileName_pathAndFileName); } private static void ChangeAttribute(XmlNode node, TrinaryValue attributeValue) { foreach (XmlAttribute attr in node.Attributes) { switch (attr.Name) { case "DisplayName": attr.Value = attributeValue.DisplayName; break; case "WebRoot": attr.Value = attributeValue.Value; break; default: break; } } } } public struct TrinaryValue { public string Key { get; set; } public string DisplayName { get; set; } public string Value { get; set; } } #endregion }