using System; using System.Collections.Generic; using System.Linq; using System.Drawing; using System.Text; using System.Xml; using System.IO; using ICSharpCode.Core; using System.Reflection; namespace Mesnac.Basic { #region XML操作主类 /// <summary> /// XML解析类 /// </summary> public class XmlHandler { #region 平台设计环境下对XML操作的主要方法 /// <summary> /// 解析工程向导文件 /// </summary> /// <param name="fileName">工程向导文件</param> /// <returns></returns> public static Dictionary<string, ProjectWizard> ParseFromProjectWizardXml(string fileName) { Dictionary<string, ProjectWizard> dic = new Dictionary<string, ProjectWizard>(); if (File.Exists(fileName)) { XmlDocument doc = new XmlDocument(); doc.Load(fileName); XmlNodeList nodeListProjectWizard = doc.GetElementsByTagName("ProjectWizard"); ProjectWizard projectWizard = null; foreach (XmlNode node in nodeListProjectWizard) { projectWizard = new ProjectWizard(); projectWizard.Name = node.Attributes["Name"].Value; projectWizard.EnglishName = node.Attributes["EnglishName"].Value; projectWizard.EnglishShortName = node.Attributes["EnglishShortName"].Value; projectWizard.ImageIndex = String.IsNullOrWhiteSpace(node.Attributes["ImageIndex"].Value) ? -1 : Convert.ToInt32(node.Attributes["ImageIndex"].Value); projectWizard.Description = node.Attributes["Description"].Value; projectWizard.EnglishDescription = node.Attributes["EnglishDescription"].Value; dic.Add(projectWizard.Name, projectWizard); } } return dic; } /// <summary> /// 解析数据源文件 /// </summary> /// <param name="fileName">数据源文件</param> /// <returns>数据源集合</returns> public static Dictionary<string, DataSourceItem> ParseFromDataSourceXml(string fileName) { Dictionary<string, DataSourceItem> dic = new Dictionary<string, DataSourceItem>(); if (File.Exists(fileName)) { XmlDocument doc = new XmlDocument(); doc.Load(fileName); XmlNodeList nodeListDataSource = doc.GetElementsByTagName("DataSourceItem"); DataSourceItem dataSourceItem = null; foreach (XmlNode node in nodeListDataSource) { dataSourceItem = new DataSourceItem(); dataSourceItem.Name = node.Attributes["Name"].Value; dataSourceItem.Driver = node.Attributes["Driver"].Value; dataSourceItem.Server = node.Attributes["Server"].Value; dataSourceItem.UserName = node.Attributes["UserName"].Value; dataSourceItem.Password = node.Attributes["Password"].Value; dataSourceItem.Database = node.Attributes["DataBase"].Value; dataSourceItem.ConnectionTimeout = GetAttributeIntValue(node, "ConnectionTimeout", 5); //默认连接超时 dataSourceItem.DriverAssembly = node.Attributes["DriverAssembly"].Value; dataSourceItem.DriverClass = node.Attributes["DriverClass"].Value; dataSourceItem.DataSourceClass = node.Attributes["DataSourceClass"].Value; dic.Add(dataSourceItem.Name, dataSourceItem); } } return dic; } /// <summary> /// 生成数据源配置文件 /// </summary> /// <param name="dic">数据源集合</param> /// <param name="fileName">数据源文件</param> public static void GenerateDataSourceXml(Dictionary<string, DataSourceItem> dic, string fileName) { XmlDocument doc = new XmlDocument(); XmlElement eroot = doc.CreateElement("DataSources"); foreach (DataSourceItem dataSourceItem in dic.Values) { XmlElement eDataSourceItem = doc.CreateElement("DataSourceItem"); XmlAttribute attName = doc.CreateAttribute("Name"); attName.Value = dataSourceItem.Name; eDataSourceItem.Attributes.Append(attName); XmlAttribute attDriver = doc.CreateAttribute("Driver"); attDriver.Value = dataSourceItem.Driver; eDataSourceItem.Attributes.Append(attDriver); XmlAttribute attServer = doc.CreateAttribute("Server"); attServer.Value = dataSourceItem.Server; eDataSourceItem.Attributes.Append(attServer); XmlAttribute attUserName = doc.CreateAttribute("UserName"); attUserName.Value = dataSourceItem.UserName; eDataSourceItem.Attributes.Append(attUserName); XmlAttribute attPassword = doc.CreateAttribute("Password"); attPassword.Value = dataSourceItem.Password; eDataSourceItem.Attributes.Append(attPassword); XmlAttribute attDataBase = doc.CreateAttribute("DataBase"); attDataBase.Value = dataSourceItem.Database; eDataSourceItem.Attributes.Append(attDataBase); XmlAttribute attConnectionTimeout = doc.CreateAttribute("ConnectionTimeout"); attConnectionTimeout.Value = dataSourceItem.ConnectionTimeout.ToString(); eDataSourceItem.Attributes.Append(attConnectionTimeout); XmlAttribute attDriverAssembly = doc.CreateAttribute("DriverAssembly"); attDriverAssembly.Value = dataSourceItem.DriverAssembly; eDataSourceItem.Attributes.Append(attDriverAssembly); XmlAttribute attDriverClass = doc.CreateAttribute("DriverClass"); attDriverClass.Value = dataSourceItem.DriverClass; eDataSourceItem.Attributes.Append(attDriverClass); XmlAttribute attDataSourceClass = doc.CreateAttribute("DataSourceClass"); attDataSourceClass.Value = dataSourceItem.DataSourceClass; eDataSourceItem.Attributes.Append(attDataSourceClass); eroot.AppendChild(eDataSourceItem); } doc.AppendChild(eroot); doc.Save(fileName); } /// <summary> /// 解析画面文件 /// </summary> /// <param name="fileName">画面文件名</param> /// <returns></returns> public static Dictionary<string, ObjectDescriptor> ParseFormXml(string fileName) { Dictionary<string, ObjectDescriptor> dic = new Dictionary<string, ObjectDescriptor>(); if (File.Exists(fileName)) { XmlDocument doc = ReadXmlFile(fileName); XmlNodeList nodeListObject = doc.GetElementsByTagName("Object"); ObjectDescriptor objectDescriptor = null; foreach (XmlNode node1 in nodeListObject) { objectDescriptor = new ObjectDescriptor(); objectDescriptor.Name = node1.Attributes["name"].Value; if (dic.ContainsKey(objectDescriptor.Name)) { continue; } if (node1.ParentNode != node1.OwnerDocument && node1.ParentNode.Attributes["name"] != null) { objectDescriptor.ParentName = node1.ParentNode.Attributes["name"].Value; } XmlNodeList nodeListProperty = node1.ChildNodes; foreach (XmlNode node2 in nodeListProperty) { if (node2.Name == "Property") { objectDescriptor.Properties.Add(node2.Attributes["name"].Value); } } dic.Add(node1.Attributes["name"].Value, objectDescriptor); } System.GC.Collect(); //回收内存 } return dic; } #endregion #region 平台运行环境下对XML操作的主要方法 /// <summary> /// 获取组态工程目录下所有的DLL集合 /// </summary> /// <param name="mcProjectPath">组态工程目录(.mprj文件所在目录)</param> /// <returns>返回DLL集合</returns> public static Dictionary<string, string> GetProjectDLLNode(string mcProjectPath) { Dictionary<string, string> formsDic = new Dictionary<string, string>(); string formListPath = mcProjectPath + "\\extend\\"; if (Directory.Exists(formListPath)) { DirectoryInfo formsDir = new DirectoryInfo(formListPath); foreach (FileInfo item in formsDir.GetFiles("*.dll")) { formsDic.Add(Path.GetFileNameWithoutExtension(item.Name), GetFormTextFromDLL(Path.GetFileNameWithoutExtension(item.Name),item.FullName)); } } return formsDic; } /// <summary> /// 获取组态工程目录下所有的画面集合 /// </summary> /// <param name="mcProjectPath">组态工程目录(.mprj文件所在目录)</param> /// <returns>返回画面集合</returns> public static Dictionary<string, string> GetProjectFormNode(string mcProjectPath) { Dictionary<string, string> formsDic = new Dictionary<string, string>(); string formListPath = Path.Combine(mcProjectPath, FixNodeName.NodeFormName); if (Directory.Exists(formListPath)) { DirectoryInfo formsDir = new DirectoryInfo(formListPath); foreach (FileInfo item in formsDir.GetFiles("*.xml",SearchOption.TopDirectoryOnly)) { formsDic.Add(Path.GetFileNameWithoutExtension(item.Name), GetFormText(item.FullName)); } } return formsDic; } /// <summary> /// 获取工程命令列表 /// </summary> /// <param name="mcProjectPath">工程路径</param> /// <returns>返回工程命令集合</returns> public static Dictionary<string, List<string>> GetProjectCommands(string mcProjectPath) { Dictionary<string, List<string>> commandsDic = new Dictionary<string, List<string>>(); string commandListPath = Path.Combine(mcProjectPath, FixNodeName.NodeCommandName + ".xml"); if (File.Exists(commandListPath)) { XmlDocument doc = new XmlDocument(); doc.Load(commandListPath); XmlNodeList nodeList = doc.GetElementsByTagName("Property"); List<string> valueList = null; foreach (XmlNode node in nodeList) { string key = node.Attributes["actionname"].Value; if (!commandsDic.ContainsKey(key)) { valueList = new List<string>(); valueList.Add(node.Attributes["guid"].Value); commandsDic.Add(key, valueList); } else { commandsDic[key].Add(node.Attributes["guid"].Value); } } } return commandsDic; } /// <summary> /// 获取组态工程目录下所有的画面菜单集合 /// </summary> /// <param name="mcProjectPath">组态工程目录(.mprj文件所在目录)</param> /// <returns>返回画面菜单集合</returns> public static List<RunConfigMenuItem> GetProjectFormMenus(string mcProjectPath) { Dictionary<string, string> formsDic = GetProjectFormNode(mcProjectPath); List<RunConfigMenuItem> lst = new List<RunConfigMenuItem>(); RunConfigMenuItem menuItem = null; foreach (string key in formsDic.Keys) { menuItem = new RunConfigMenuItem(); menuItem.FormFile = key; menuItem.ID = key; menuItem.FormText = formsDic[key]; menuItem.Text = formsDic[key]; menuItem.IsSystem = false; lst.Add(menuItem); } Dictionary<string, List<string>> commandsDic = GetProjectCommands(mcProjectPath); foreach (string key in commandsDic.Keys) { menuItem = new RunConfigMenuItem(); menuItem.ID = "Command_" + key; menuItem.FormText = key; menuItem.Text = key; menuItem.CreateType = CreateType.Command; menuItem.CommandValue = commandsDic[key]; menuItem.IsSystem = false; lst.Add(menuItem); } Dictionary<string, string> formsDll = GetProjectDLLNode(mcProjectPath); foreach (string key in formsDll.Keys) { menuItem = new RunConfigMenuItem(); menuItem.FormFile = key; menuItem.ID = "dll_" + key; menuItem.FormText = formsDll[key]; menuItem.Text = formsDll[key]; menuItem.IsSystem = false; lst.Add(menuItem); } return lst; } /// <summary> /// 获取画面文件中窗体的Text属性值 /// </summary> /// <param name="fileName"></param> /// <returns></returns> private static string GetFormText(string fileName) { string returnstr = String.Empty; XmlDocument doc = ReadXmlFile(fileName); XmlNode formNode = doc.SelectSingleNode("DOCUMENT_ELEMENT/Object"); foreach (XmlNode item in formNode.ChildNodes) { if (item.Name == "Property" && item.Attributes["name"].InnerText == "Text") { returnstr = item.InnerText; } } return returnstr; } /// <summary> /// 获取DLL文件中窗体的FormName属性值 /// </summary> /// <param name="fileName">不带扩展名的文件名称</param> /// <param name="fileFullName">文件全路径名称</param> /// <returns></returns> private static string GetFormTextFromDLL(string fileName,string fileFullName) { string returnstr = String.Empty; Assembly ass = Assembly.LoadFrom(fileFullName); Type ob = ass.GetType(fileName + ".App"); if (ob.IsClass) { object obj = (object)Activator.CreateInstance(ob); FieldInfo[] fieldInfo = ob.GetFields(); for (int i = 0; i < fieldInfo.Length; i++) { if(fieldInfo[i].Name == "FormName") { returnstr = fieldInfo[i].GetValue(obj).ToString(); break; } } } return returnstr; } #endregion #region 通用辅助方法 /// <summary> /// 加载画面文件,把XML文件加载为XmlDocument对象 /// </summary> /// <param name="fileName">画面文件名</param> /// <returns>返回加载后的XmlDocument对象</returns> private static XmlDocument ReadXmlFile(string fileName) { try { StreamReader sr = new StreamReader(fileName); string cleandown = sr.ReadToEnd(); sr.Close(); cleandown = "<DOCUMENT_ELEMENT>" + cleandown + "</DOCUMENT_ELEMENT>"; XmlDocument doc = new XmlDocument(); doc.LoadXml(cleandown); return doc; } catch (Exception ex) { Console.Write(ex.Message); throw ex; } } /// <summary> /// 获取XML文档那个节点字符串属性值 /// </summary> /// <param name="node">XML文档节点对象</param> /// <param name="attributeName">属性名称</param> /// <param name="defaultValue">如果获取失败,返回此默认值</param> /// <returns>返回对应的节点值</returns> public static string GetAttributeStringValue(XmlNode node, string attributeName, string defaultValue) { if (node.Attributes[attributeName] != null) { return node.Attributes[attributeName].Value; } else { return defaultValue; } } /// <summary> /// 获取XML文档那个节点整型属性值 /// </summary> /// <param name="node">XML文档节点对象</param> /// <param name="attributeName">属性名称</param> /// <param name="defaultValue">如果获取失败,返回此默认值</param> /// <returns>返回对应的节点值</returns> public static int GetAttributeIntValue(XmlNode node, string attributeName, int defaultValue) { if (node.Attributes[attributeName] != null) { int.TryParse(node.Attributes[attributeName].Value, out defaultValue); } return defaultValue; } /// <summary> /// 获取XML文档那个节点布尔属性值 /// </summary> /// <param name="node">XML文档节点对象</param> /// <param name="attributeName">属性名称</param> /// <param name="defaultValue">如果获取失败,返回此默认值</param> /// <returns>返回对应的节点值</returns> public static bool GetAttributeBoolValue(XmlNode node, string attributeName, bool defaultValue) { if (node.Attributes[attributeName] != null) { bool.TryParse(node.Attributes[attributeName].Value, out defaultValue); } return defaultValue; } #endregion } #endregion #region XML操作中用到的实体类定义 #region 工程向导实体类,对应工程向导配置文件中的一条配置项 /// <summary> /// 工程向导实体类,对应工程向导配置文件中的一条配置项 /// </summary> [Serializable] public class ProjectWizard { /// <summary> /// 工程向导中文名称 /// </summary> public string Name { get; set; } /// <summary> /// 工程向导英文名称 /// </summary> public string EnglishName { get; set; } /// <summary> /// 工程向导英文名称缩写 /// </summary> public string EnglishShortName { get; set; } /// <summary> /// 工程向导对应的图标索引 /// </summary> public int ImageIndex { get; set; } /// <summary> /// 中文描述信息 /// </summary> public string Description { get; set; } /// <summary> /// 英文描述信息 /// </summary> public string EnglishDescription { get; set; } } #endregion #region 画面文件中的对象描述器实体类,对应Form.xml中的Object元素 /// <summary> /// 画面文件中的对象描述器实体类,对应Form.xml中的Object元素 /// </summary> [Serializable] public class ObjectDescriptor { private string parentName; private string name; private List<string> properties = new List<string>(); public ObjectDescriptor() { } /// <summary> /// 父级对象名称 /// </summary> public string ParentName { get { return parentName; } set { parentName = value; } } /// <summary> /// 对象名称 /// </summary> public string Name { get { return name; } set { name = value; } } /// <summary> /// 对象属性名称列表 /// </summary> public List<string> Properties { get { return properties; } set { properties = value; } } } #endregion #region 画面对应的菜单项实体 /// <summary> /// 画面对应的菜单项实体 /// </summary> [Serializable] public class RunConfigMenuItem { #region 字段定义 private string _ID = String.Empty; private string _msgId = String.Empty; private string _text = String.Empty; private string _formFile = String.Empty; private string _formText = String.Empty; private string _icon = String.Empty; private Image _img = null; private int _index = 0; private string _shortCut = String.Empty; private FormShowType _showType = FormShowType.Document; private CreateType _createType = CreateType.Form; private bool _isSystem = false; private bool _isAutoLoad = false; private RunConfigMenuItem _parent = null; private List<string> _commandValue = null; #endregion /// <summary> /// 标识 /// </summary> public string ID { get { return this._ID; } set { this._ID = value; } } /// <summary> /// 国际化资源ID /// </summary> public string MsgId { get { return _msgId; } set { _msgId = value; } } /// <summary> /// 显示文本 /// </summary> public string Text { get { return this._text; } set { this._text = value; } } /// <summary> /// 画面文件名 /// </summary> public string FormFile { get { return this._formFile; } set { this._formFile = value; } } /// <summary> /// 原始画面窗体Text属性 /// </summary> public string FormText { get { return this._formText; } set { this._formText = value; } } /// <summary> /// 图标文件路径 /// </summary> public string ICON { get { return this._icon; } set { this._icon = value; } } /// <summary> /// 图标对象 /// </summary> public Image Img { get { return this._img; } set { this._img = value; } } /// <summary> /// 索引位置 /// </summary> public int Index { get { return this._index; } set { this._index = value; } } /// <summary> /// 快捷键文本 /// </summary> public string ShortCut { get { return this._shortCut; } set { this._shortCut = value; } } /// <summary> /// 是否已对话框显示 /// </summary> public FormShowType ShowType { get { return this._showType; } set { this._showType = value; } } /// <summary> /// 菜单的创建类型 /// </summary> public CreateType CreateType { get { return this._createType; } set { this._createType = value; } } /// <summary> /// 是否为系统菜单 /// </summary> public bool IsSystem { get { return this._isSystem; } set { this._isSystem = value; } } /// <summary> /// 是否自动加载 /// </summary> public bool IsAutoLoad { get { return this._isAutoLoad; } set { this._isAutoLoad = value; } } /// <summary> /// 父级菜单对象 /// </summary> public RunConfigMenuItem Parent { get { return this._parent; } set { this._parent = value; } } public List<string> CommandValue { get { return this._commandValue; } set { this._commandValue = value; } } public override string ToString() { if (this._createType == CreateType.Form) { if (String.IsNullOrEmpty(this.FormFile)) { return String.Format("{0}", this._text); } else if (this._ID.Contains("dll_")) { return String.Format("{0}({1}.dll)", this._text, this.FormFile); } else { return String.Format("{0}({1}.xml)", this._text, this.FormFile); } } else if (this._createType == CreateType.Command) { return String.Format("{0}", this._text); } else { return String.Empty; } } } /// <summary> /// 菜单命令调用窗体时,窗体的显示方式 /// </summary> [Serializable] public enum FormShowType { /// <summary> /// 文档方式,放入DockPanel /// </summary> Document = 1, /// <summary> /// 独立窗体方式 /// </summary> Form = 2, /// <summary> /// 对话框方式 /// </summary> Dialog = 3, /// <summary> /// 多屏方式 /// </summary> MultiScreen = 4, /// <summary> /// 浮动 /// </summary> FloatWindow = 5 } #endregion #endregion /// <summary> /// Xml辅助类 /// </summary> public static class XmlHelper { /// <summary> /// 扩展方法-判断2个节点的Name属性值是否相等 /// </summary> /// <param name="node1">当前节点</param> /// <param name="node2">要比较的节点</param> /// <returns>相等返回true,否则返回false</returns> public static bool NodeEquals(this XmlNode node1, XmlNode node2) { if (node1.Attributes["Name"] != null && node2.Attributes["Name"] != null) { return node1.Attributes["Name"].Value.Equals(node2.Attributes["Name"].Value); } return node1.Equals(node2); } /// <summary> /// 节点集合中是否包含此节点 /// </summary> /// <param name="nodeList"></param> /// <param name="node"></param> /// <returns></returns> public static bool ContainsNode(this List<XmlNode> nodeList, XmlNode node) { foreach (XmlNode n in nodeList) { if (n.NodeEquals(node)) { return true; } } return false; } /// <summary> /// 扩展方法-从节点集合中删除一个节点 /// </summary> /// <param name="nodeList">当前节点集合</param> /// <param name="node">要移除的节点</param> public static void Remove(this List<XmlNode> nodeList, XmlNode node) { foreach (XmlNode n in nodeList) { if (n.NodeEquals(node)) { nodeList.Remove(n); break; } } } /// <summary> /// 集合转换 /// </summary> /// <param name="nodeList">要转换的XmlNodeList对象</param> /// <returns>变为XmlNode集合</returns> public static List<XmlNode> ConvertListFromNodeList(XmlNodeList nodeList) { List<XmlNode> lst = new List<XmlNode>(); foreach (XmlNode node in nodeList) { lst.Add(node); } return lst; } /// <summary> /// 求2个集合的交集 /// </summary> /// <param name="list1"></param> /// <param name="list2"></param> /// <returns></returns> public static List<XmlNode> IntersectNode(this List<XmlNode> list1, List<XmlNode> list2) { List<XmlNode> list = new List<XmlNode>(); foreach (XmlNode node in list1) { if (list2.ContainsNode(node)) { list.Add(node); } } return list; } /// <summary> /// 获取一组控件的属性值 /// </summary> /// <param name="comps"></param> /// <param name="propertyName"></param> /// <returns></returns> public static object GetPropertyValue(object[] comps, string propertyName) { object value = String.Empty; bool beginFlag = true; foreach (object obj in comps) { System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName); if (propertyInfo == null) { return String.Empty; } if (beginFlag) { value = propertyInfo.GetValue(obj, null); beginFlag = false; } else { if (value == propertyInfo.GetValue(obj, null)) { continue; } else { return String.Empty; } } } return value; } /// <summary> /// 为一组控件的属性赋值 /// </summary> /// <param name="comps"></param> /// <param name="propertyName"></param> /// <param name="value"></param> public static void SetPropertyValue(object[] comps, string propertyName, object value) { foreach (object obj in comps) { System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName); if (propertyInfo == null) { continue; } propertyInfo.SetValue(obj, value, null); } } } }