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
}