You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lj_plc/Main/Mesnac.Basic/XmlHandler.cs

864 lines
30 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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);
}
}
}
}