使用对象序列化实现xml操作
问题:在程序开发中,经常会涉及对xml的操作,在c#中常用的方法有两种
1. xpath解析
2. XmlDocument解析
在解析时什么很麻烦,c#提供了xml序列化的方法,非常方便进实现xml和以象间的转换,在插件系统框架程序中,实现插件的管理配置,使用序列化确实方便了不少,扩展性非常方便,有些朋友会提到性能的问题,在这个系统中,结合缓存问题不是问题。
首先来看类结构图:
类名 |
说明 |
备注 |
FrameworkConfiguraconfigManager |
配置文件管理类 |
实现config管理,load、save |
FrameworkConfiguraconfig |
配置文件类 |
|
PluginSettings |
插件配置文件集合适配器 |
利用索引实现集合访问 |
PluginSetting |
插件配置文件 |
例如UserCenterPlugin |
AssemblyFile |
插件对应配置文件 |
|
AppSettings |
应用程序配置集合适配器 |
得 key value |
AppSetting |
应用程序配置 |
本文主要是实现对象读取与保存,类结构就不做过多分析,主要看FrameworkConfiguration 、FrameworkConfigurationManager类
FrameworkConfigurationManager实现FrameworkConfiguration 保存与读取,FrameworkConfiguration包含了AppSettings对象及PluginSettiongs对象,后续还可以扩展。
关键代码
//名称空间引入
using System.IO;
using System.Xml.Serialization;
//指定xml序列化属性 根结点名间
[Serializable]
[XmlRootAttribute("configuration", Namespace = "http://www.codemarks.net ")]
public class FrameworkConfiguration
//序列化保存
[XmlElementAttribute(ElementName = "pluginSetting", IsNullable = false)]
public List<PluginSetting> Items
{
get { return _items; }
set { _items = value; }
}
public void Save()
{
FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
XmlSerializer ser = new XmlSerializer(typeof(FrameworkConfiguration), new Type[] {
typeof(PluginSettings),
typeof(PluginSetting),
typeof(AssemblyFile),
});
ser.Serialize(fs, this.config);
fs.Close();
}
//序列化读取
public void Load()
{
//不存配置文件
if (!File.Exists(fileName))
{
this.config = new FrameworkConfiguration();
return;
}
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
XmlSerializer ser = new XmlSerializer(typeof(FrameworkConfiguration), new Type[] {
typeof(PluginSetting),
typeof(PluginSettings),
typeof(AssemblyFile)
});
this.config = (FrameworkConfiguration)ser.Deserialize(fs);
fs.Close();
}
在Test类中读到插件对象
FrameworkConfigurationManager.Instance.Config.PluginSettings["UserCenter"]; // UserCenter为插件名称
结果
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<pluginSettings>
<plugin name="UserPlugin" author="codemarks" descript="" version="1.0" webroot="/plugin/user/web/">
<assemblys>
<assembly name="CodeMarks.Framework.Plugin.Adapter.User" descript="">cn.CodeMarks.Framework.Plugin.Adapter.UserAdapter</assembly>
<assembly name="CodeMarks.Framework.Plugin.AddIn.User" descript=""/>
<assembly name="CodeMarks.Framework.Plugin.Model.User" descript=""/>
<assembly name="CodeMarks.Framework.Plugin.View.User" descript=""/>
</assemblys>
</plugin>
</pluginSettings>
<appSettings>
<add key="pluginRoot" value="/Plugin/"></add>
</appSettings>
</configuration>
//FrameworkConfiguraconfigManager完成代码 using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Xml.Serialization; namespace cn.CodeMarks.Framework.Plugin { public class FrameworkConfigurationManager { private static FrameworkConfigurationManager instance = null; public static FrameworkConfigurationManager Instance { get { if (FrameworkConfigurationManager.instance == null) { FrameworkConfigurationManager.instance = new FrameworkConfigurationManager(); } return FrameworkConfigurationManager.instance; } } private FrameworkConfiguration config = new FrameworkConfiguration(); public FrameworkConfiguration Config { get { return config; } set { config = value; } } public void Save() { FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); XmlSerializer ser = new XmlSerializer(typeof(FrameworkConfiguration), new Type[] { typeof(PluginSettings), typeof(PluginSetting), typeof(AssemblyFile), }); ser.Serialize(fs, this.config); fs.Close(); } private string fileName = "FrameworkConfig.xml"; public void Load() { //不存配置文件 if (!File.Exists(fileName)) { this.config = new FrameworkConfiguration(); return; } FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); XmlSerializer ser = new XmlSerializer(typeof(FrameworkConfiguration), new Type[] { typeof(PluginSetting), typeof(PluginSettings), typeof(AssemblyFile) }); this.config = (FrameworkConfiguration)ser.Deserialize(fs); fs.Close(); } public void TestData() { PluginSetting ps1 = new PluginSetting(); ps1.PluginName = "UserPlugin"; ps1.Author = "codemarks"; ps1.Descript = " "; ps1.Version = "1.0"; ps1.WebRoot = "/plugin/user/webroot/"; AssemblyFile af1 = new AssemblyFile(); af1.Name = "CodeMarks.Framework.Plugin.Adapter.User"; af1.AdapterClassName = "CodeMarks.Framework.Plugin.Adapter.User.UserAdapter"; ps1.Items.Add(af1); this.config.PluginSettings.AddPlugin(ps1); PluginSetting ps = new PluginSetting(); ps.PluginName = "UserPlugin2"; ps.Author = "codemarks2"; ps.Descript = " "; ps.Version = "1.0"; ps.WebRoot = "/plugin/user/webroot/"; AssemblyFile af = new AssemblyFile(); af.Name = "CodeMarks.Framework.Plugin.Adapter.User2"; af.AdapterClassName = "CodeMarks.Framework.Plugin.Adapter.User.UserAdapter"; ps.Items.Add(af); this.config.PluginSettings.AddPlugin(ps); this.config.AppSettings.Items.Add(new AppSetting("conn", ".\\nbaqn")); this.config.AppSettings.Items.Add(new AppSetting("config", "frame.config")); this.config.AppSettings.Items.Add(new AppSetting("catch", "sql")); } } } //FrameworkConfiguraconfig完整代码 using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Xml.Serialization; using System.IO; namespace cn.CodeMarks.Framework.Plugin { [Serializable] [XmlRootAttribute("configuration", Namespace = "http://www.codemarks.net ", IsNullable = false)] public class FrameworkConfiguration { public FrameworkConfiguration() { _PluginSettings = new PluginSettings(); _appSettings = new AppSettings(); } private PluginSettings _PluginSettings; /// <summary> /// 插件配置 /// </summary> public PluginSettings PluginSettings { get { return _PluginSettings; } set { _PluginSettings = value; } } private AppSettings _appSettings; public AppSettings AppSettings { get { return _appSettings; } set { _appSettings = value; } } } } //PluginSettings完整代码 using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; namespace cn.CodeMarks.Framework.Plugin { [Serializable] public class PluginSettings { public PluginSettings() { _items = new List<PluginSetting>(); } private List<PluginSetting> _items; [XmlElementAttribute(ElementName = "pluginSetting", IsNullable = false)] public List<PluginSetting> Items { get { return _items; } set { _items = value; } } public PluginSetting this[string pluginName] { get { return GetPlugin(pluginName); } } /// <summary> /// 根据插件名称获取插件 /// </summary> /// <param name="plugName"></param> /// <returns></returns> public PluginSetting GetPlugin(string plugName) { PluginSetting ret = null; foreach (PluginSetting plug in Items) { if (plugName == plug.PluginName) { ret = plug; break; } } return ret; } /// <summary> /// 添加插件成功返回true /// </summary> /// <param name="plugin"></param> /// <returns></returns> public bool AddPlugin(PluginSetting plugin) { bool ret = false; foreach (PluginSetting plug in Items) { if (plugin.PluginName == plug.PluginName) { ret = true; break; } } if (!ret) { Items.Add(plugin); } return ret; } /// <summary> /// 移除插件,成功返回true /// </summary> /// <param name="pluginName"></param> /// <returns></returns> public bool ReMovePlugin(string pluginName) { bool ret = false; foreach (PluginSetting plug in Items) { if (pluginName == plug.PluginName) { Items.Remove(plug); ret = true; break; } } return ret; } } //PluginSetting完整代码 [Serializable] public class PluginSetting { public PluginSetting() { _items = new List<AssemblyFile>(); } private string _pluginName; /// <summary> /// 插件名称 /// </summary> [XmlAttribute("name")] public string PluginName { get { return _pluginName; } set { _pluginName = value; } } private string _descript; /// <summary> /// 插件描述 /// </summary> [XmlAttribute("descript")] public string Descript { get { return _descript; } set { _descript = value; } } private string _version; /// <summary> /// 插件版本 /// </summary> [XmlAttribute("version")] public string Version { get { return _version; } set { _version = value; } } private string _author; /// <summary> /// 插件作者 /// </summary> [XmlAttribute("author")] public string Author { get { return _author; } set { _author = value; } } private string webRoot; /// <summary> /// 页面路径 /// </summary> [XmlAttribute("webroot")] public string WebRoot { get { return webRoot; } set { webRoot = value; } } private List<AssemblyFile> _items; [XmlArrayAttribute("assemblyFiles")] public List<AssemblyFile> Items { get { return _items; } set { _items = value; } } } } //AssemblyFile完整代码 using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; namespace cn.CodeMarks.Framework.Plugin { [Serializable] public class AssemblyFile { string name; [XmlAttribute("name")] public string Name { get { return name; } set { name = value; } } string descript; [XmlAttribute("descript")] public string Descript { get { return descript; } set { descript = value; } } string adapterClassName; [XmlAttribute("adapter")] public string AdapterClassName { get { return adapterClassName; } set { adapterClassName = value; } } } } //AppSettings完整代码 //AppSetting完整代码 using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.Xml.Serialization; namespace cn.CodeMarks.Framework.Plugin { public class AppSettings { public AppSettings() { _items = new List<AppSetting>(); } private List<AppSetting> _items; [XmlElementAttribute(ElementName = "add", IsNullable = false)] public List<AppSetting> Items { get { return _items; } set { _items = value; } } /// <summary> /// 根据key获取配置对象 /// </summary> /// <param name="key"></param> /// <returns></returns> public AppSetting this[string key] { get { AppSetting ret = null; foreach (AppSetting app in Items) { if (app.Key == key) { ret = app; break; } } return ret; } } public AppSetting this[AppSetting appSetting] { set { bool isAlready = false; foreach (AppSetting app in Items) { if (app.Key == appSetting.Key) { isAlready = true; break; } } if (!isAlready) { Items.Add(appSetting); } } } } /// <summary> /// 应用程序设置 /// </summary> public class AppSetting { public AppSetting() { } public AppSetting(string _key, string _value) { this.Key = _key; this.Value = _value; } private string _key; [XmlAttribute("key")] public string Key { get { return _key; } set { _key = value; } } private string value; [XmlAttribute("value")] public string Value { get { return this.value; } set { this.value = value; } } } } //生成的xml文件 <?xml version="1.0" encoding="utf-8"?> <configuration> <pluginSettings> <plugin name="UserPlugin" author="codemarks" descript=" " version="1.0" webroot="/plugin/user/web/"> <assemblys> <assembly name="CodeMarks.Framework.Plugin.Adapter.User" descript="">cn.CodeMarks.Framework.Plugin.Adapter.UserAdapter</assembly> <assembly name="CodeMarks.Framework.Plugin.AddIn.User" descript=""/> <assembly name="CodeMarks.Framework.Plugin.Model.User" descript=""/> <assembly name="CodeMarks.Framework.Plugin.View.User" descript=""/> </assemblys> </plugin> </pluginSettings> <appSettings> <add key="pluginRoot" value="/Plugin/"></add> </appSettings> </configuration>