硬件管理平台-硬件网关-XML操作
硬件管理平台-硬件网关-XML操作
简介
本周主要接上一章,将与硬件交互的部分进行说明。
创建交互类
在上一篇我们将相关的辅助类进行了编写,本文主要介绍的是xml与硬件的交互有哪些,他们的作用是什么及相关代码。
按照我们约定的HardwareInfo.xml可知,我们需要对xml进行增删改查操作,并通过相关的查询信息来获取硬件标签(HardwareInfo标签)。
下面为相关操作代码,每个方法上我都加上了注释。
/// <summary>
/// 硬件与xml交互的操作类,主要用于操作xml来转换为硬件的类(HardwareXmlEntity)
/// </summary>
public class HardwareOptXml
{
private readonly XmlHelper _xmlHelper;
private const string _hardwareXmlFile = "HardwareInfo.xml";
/// <summary>
/// 初始化时实例化XmlHelper类
/// 将默认操作的xml当作参数传递给XmlHelper类
/// </summary>
public HardwareOptXml()
{
_xmlHelper = new XmlHelper(_hardwareXmlFile);
}
/// <summary>
/// 根据硬件主键删除硬件信息
/// </summary>
/// <param name="key">硬件主键</param>
/// <returns>删除成功则返回true;否则返回false</returns>
public bool RemoveHardwareInfo(string key)
{
//找到设备主键属性等于key的Node
XmlNode xmlNode = _xmlHelper.GetNode(@"HardwareInfos/HardwareInfo[@设备主键='" + key + "']");
if (xmlNode != null)
{
// 删除该Node
_xmlHelper.RemoveNode(@"HardwareInfos/HardwareInfo[@设备主键='" + key + "']");
return true;
}
return false;
}
/// <summary>
/// 获得HardwareInfos标签并在该标签中添加HardwareInfo标签及硬件的相关属性值
/// HardwareInfo标签中添加的内容为属性是HardwareInfo类(或者他的重载类)的变量名称及变量值
/// HardwareInfo标签中的子标签分别保存了初始化功能,定时功能和操作功能,每个类型的功能独立标签存储
/// 注意:HardwareInfos标签在调用本方法之前必须是存在的,否则将无法添加
/// </summary>
/// <param name="hardwareDic">xml和硬件的操作类</param>
public void AddHardwareInfo(HardwareXmlEntity hardwareDic)
{
XmlNode xmlNode = _xmlHelper.GetNode(@"HardwareInfos");
// 判断如果存在则直接删除
RemoveHardwareInfo(hardwareDic.PrimaryKey);
// 创建一个新的HardwareInfo标签
XmlElement hardwareInfo = _xmlHelper.CreateElement("HardwareInfo");
// 如果有属性变量则新增,如果没有则跳出
if (hardwareDic.Param != null && hardwareDic.Param.Count > 0)
{
// 遍历属性值
foreach (string key in hardwareDic.Param.Keys)
{
// 添加属性及属性值,例如设备主键、设备类型等
hardwareInfo.SetAttribute(key, hardwareDic.Param[key]);
}
// 判断功能是否存在,如果存在则创建“操作标签”,然后将操作功能的描述保存到xml中
// 这里使用描述可以通过查看xml来知道相关的操作功能,如果使用编码,还需要看对应的意思,太麻烦了
if (hardwareDic.OperationFun != null && hardwareDic.OperationFun.Count > 0)
{
// 创建新的标签:操作功能
XmlElement operationNode = _xmlHelper.CreateElement("操作功能");
// 向”操作功能“标签添加功能的描述项
operationNode.InnerText = AssemblyUtil.GetDescriptionByEnumLis(hardwareDic.OperationFun);
hardwareInfo.AppendChild(operationNode);
}
// 添加初始化功能,例如与操作功能一致,唯一的区别是操作功能是点击或者调用的,而初始化则是需要立马加载的
if (hardwareDic.InitializationFun != null && hardwareDic.InitializationFun.Count > 0)
{
XmlElement initNode = _xmlHelper.CreateElement("初始化");
initNode.InnerText = AssemblyUtil.GetDescriptionByEnumLis(hardwareDic.InitializationFun);
hardwareInfo.AppendChild(initNode);
}
// 添加定时功能的标签,该功能后期会进行描述,这里的标签还有子标签,原因是每个定时任务都应该有独立的标签
if (hardwareDic.SettingsFun != null && hardwareDic.SettingsFun.Count > 0)
{
XmlElement timingNode = _xmlHelper.CreateElement("定时功能");
hardwareDic.SettingsFun.ForEach(setting => {
timingNode.AppendChild(GetSettingNode(setting));
});
hardwareInfo.AppendChild(timingNode);
}
xmlNode.AppendChild(hardwareInfo);
_xmlHelper.Save();
}
}
/// <summary>
/// 定时任务的子标签,用于表示某个功能对应的Cron
/// </summary>
/// <param name="setting"></param>
/// <returns></returns>
private XmlNode GetSettingNode(FunctionSetting setting)
{
XmlElement hardwareInfo = _xmlHelper.CreateElement("FunctionSetting");
hardwareInfo.SetAttribute("RunFunction", AssemblyUtil.GetDescriptionByEnum<Function>(setting.RunFunction));
return hardwareInfo;
}
/// <summary>
/// 根据节点属性获得数值
/// </summary>
/// <param name="node"></param>
/// <param name="key"></param>
/// <param name="defaultStr"></param>
/// <returns></returns>
private String GetAttribute(XmlNode node, String key, String defaultStr = "")
{
if (node.Attributes.Count > 0)
{
if (node.Attributes[key] != null)
{
return node.Attributes[key].Value;
}
}
return defaultStr;
}
/// <summary>
/// 根据主键获取硬件类,没有则返回null
/// </summary>
/// <param name="key">硬件主键</param>
/// <returns></returns>
public HardwareXmlEntity GetHardwareDic(String key)
{
XmlNode xmlNode = _xmlHelper.GetNode(@"HardwareInfos/HardwareInfo[@设备主键='" + key + "']");
if (xmlNode != null)
{
// 将node转换为硬件与xml的操作类
return GetHardwareInfo(xmlNode);
}
return null;
}
/// <summary>
/// 获取所有硬件信息
/// </summary>
/// <returns>硬件与xml的操作类的数组</returns>
public List<HardwareXmlEntity> GetHardwareInfos()
{
List<HardwareXmlEntity> hardwares = new List<HardwareXmlEntity>();
XmlNode rootNode = _xmlHelper.GetNode(@"HardwareInfos");
if (rootNode != null)
{
XmlNodeList hardwareList = rootNode.ChildNodes;
foreach (XmlNode node in hardwareList)
{
hardwares.Add(GetHardwareInfo(node));
}
return hardwares;
}
return new List<HardwareXmlEntity>();
}
/// <summary>
/// 只获取该Node的属性部分信息
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private Dictionary<string, string> GetParam(XmlNode node)
{
Dictionary<string, string> valuePairs = new Dictionary<string, string>();
//遍历属性名称与属性值
foreach (XmlAttribute attribute in node.Attributes)
{
valuePairs.Add(attribute.Name, attribute.Value);
}
return valuePairs;
}
/// <summary>
/// 根据内嵌的值获得功能列表
/// 也就是将功能的描述变为功能的enum
/// </summary>
/// <param name="node">功能标签,例如操作功能</param>
/// <returns>功能实例的list</returns>
private List<Function> GetParamByFunction(XmlNode node)
{
if (node == null)
{
return new List<Function>();
}
string[] strFun = node.InnerText.Split(',');
return AssemblyUtil.GetEnumByDescriptions(strFun);
}
/// <summary>
/// 说白了就是把当前的xml关闭然后重新读取
/// </summary>
public void RefreshXml()
{
_xmlHelper.RefreshXml();
}
/// <summary>
/// 根据定时功能标签的node遍历获取定时任务,并返回
/// </summary>
/// <param name="nodes"></param>
/// <param name="settingList"></param>
/// <returns></returns>
private List<FunctionSetting> GetParamBySetting(XmlNodeList nodes, ref List<string> settingList)
{
List<FunctionSetting> settings = new List<FunctionSetting>();
foreach (XmlNode node in nodes)
{
settings.Add(GetSettionFunction(node, ref settingList));
}
return settings;
}
/// <summary>
/// 获取定时任务的相关功能的迭代方法
/// </summary>
/// <param name="node"></param>
/// <param name="settingList"></param>
/// <returns></returns>
private FunctionSetting GetSettionFunction(XmlNode node, ref List<string> settingList)
{
FunctionSetting setting = new FunctionSetting();
if (node.Attributes["RunFunction"] != null && !string.IsNullOrEmpty(node.Attributes["RunFunction"].Value))
{
settingList.Add(node.Attributes["RunFunction"].Value);
setting.FunctionStr = node.Attributes["RunFunction"].Value;
setting.RunFunction = AssemblyUtil.GetEnumByDescription<Function>(node.Attributes["RunFunction"].Value);
}
return setting;
}
/// <summary>
/// 将单个node转换为HardwareXmlEntity(xml和硬件的entity)
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private HardwareXmlEntity GetHardwareInfo(XmlNode node)
{
HardwareXmlEntity info = new HardwareXmlEntity
{
// 先获得属性信息
Param = GetParam(node),
// 操作功能部分
OperationFun = GetParamByFunction(node["操作功能"])
};
if (info.OperationFun.Count > 0)
{
// 操作的功能说明
info.OperationTxt = node["操作功能"].InnerText;
}
// 初始化的赋值
info.InitializationFun = GetParamByFunction(node["初始化"]);
if (info.InitializationFun.Count > 0)
{
// 初始化的功能说明
info.InitializationTxt = node["初始化"].InnerText;
}
List<string> settingList = new List<string>();
if (node["定时功能"] != null && node["定时功能"].ChildNodes != null)
{
// 定时功能
info.SettingsFun = GetParamBySetting(node["定时功能"].ChildNodes, ref settingList);
// 功能说明
info.SettingsTxt = string.Join(",", settingList);
}
return info;
}
}
交互类说明
该类的作用是在Xml帮助类和硬件中间包了一层,当硬件业务需要调用xml时,可通过在交互类中找到相关方法,如果没有可以继续添加,这样的好处是使得操作xml类只有一种方式,不需要到处编写方法。按照Mvc三层原则(虽然这个没有),每层之间建议只有一个口区输入输出,不然多个类来回使用,指不定哪天就发现自己都忘记这个类的作用和为什么要分这么多类去调用了。
四种标签的说明
HardwareInfo的属性标签
该标签主要存储的是HardwareInfo类的属性信息,例如设备主键,设备类型,设备编号,ip地址,端口号等等,HardwareInfo类为基类,硬件项目可通过该类来集成并添加新的属性值,就像门禁中添加了用户名和密码属性,此时该标签中也会保存用户名和密码的属性信息及相关数值。
操作功能
操作功能标签内存储的是操作功能的文字描述,例如空调的开机、关机、设置温度等,表述的是这个硬件的哪些功能能被操作或者说类似遥控器,哪些功能可以被遥控到。
初始化功能
初始化功能主要存储的是当要初始化的功能,当xml被转换为硬件相关类(HardwareXmlEntity)时,如果发现有该标签的存在,应该马上调用,例如我们计划门禁在被初始化以后,马上获得人员名称列表,那么就可以在初始化功能中添加获取人员列表的功能,当获得HardwareXmlEntity后,直接调用初始化,后台调用获取人员列表。
定时功能
定时功能存储的是定时任务信息,后期添加定时模块后会再进行说明。