我已经设法从几个类中轻松生成XML文件,如下所示;
public class AllConfig : XMLEncapsulator
{
[XmlElement("Database-Settings")]
public DataBaseConfiguration databaseConfiguration { get; set; }
[XmlElement("Merlin-Settings")]
public MerlinConfiguration merlinConfiguration { get; set; }
}
public class DataBaseConfiguration : XMLEncapsulator
{
public string dbIP { get; set; }
public int ?port { get; set; }
public string username { get; set; }
public string password { get; set; }
}
public class MerlinConfiguration : XMLEncapsulator
{
public string MerlinIP { get; set; }
public int ?MerlinPort { get; set; }
public int ?RecievingPort { get; set; }
}
// load classes with information, then;
try
{
allConfig.databaseConfiguration = dbConfig;
allConfig.merlinConfiguration = merlinConfig;
allConfig.Save();
}
catch (Exception ErrorFinalisingSave)
{
MessageBox.Show(ErrorFinalisingSave.Message + "3");
}
这很有效,并且给了我:
<AllConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<databaseConfiguration>
<dbIP></dbIP>
<port></port>
<username></username>
<password></password>
</databaseConfiguration>
<merlinConfiguration>
<MerlinIP></MerlinIP>
<MerlinPort></MerlinPort>
<RecievingPort></RecievingPort>
</merlinConfiguration>
</AllConfig>
但是,我如何将这个检索回到我的表格中?所以我有这样的东西,但我似乎无法让它工作;
AllConfig allConfig;
DataBaseConfiguration dbConfig;
MerlinConfiguration merlinConfig;
//need to load here.
//check if values loaded are null, and then load them if they exist into textboxes and such.
我应该加载两个配置类,然后将它们分配给整个配置类?或者我是否需要加载整个类并分配子配置类,如此;
allConfig = new AllConfig();
dbConfig = new DataBaseConfiguration();
merlinConfig = new MerlinConfiguration();
allConfig.databaseConfiguration = dbConfig;
allConfig.merlinConfiguration = merlinConfig;
allConfig.databaseConfiguration.Load();
allConfig.merlinConfiguration.Load();
编辑:继承我的加载方法;
public virtual void Load()
{
if (File.Exists(DeviceManager.path))
{
StreamReader sr = new StreamReader(DeviceManager.path);
XmlTextReader xr = new XmlTextReader(sr);
XmlSerializer xs = new XmlSerializer(this.GetType());
object c;
if (xs.CanDeserialize(xr))
{
c = xs.Deserialize(xr);
Type t = this.GetType();
PropertyInfo[] properties = t.GetProperties();
foreach (PropertyInfo p in properties)
{
p.SetValue(this, p.GetValue(c, null), null);
}
}
xr.Close();
sr.Close();
}
}
答案 0 :(得分:1)
这是一个用于从Xml反序列化对象的通用方法。这有帮助吗?
public static T Deserialize<T>(string xml) where T : class, new()
{
if (string.IsNullOrEmpty(xml))
{
throw new ArgumentNullException("xml");
}
return (T)Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
}
public static T Deserialize<T>(Stream xmlStream) where T : class, new()
{
if (xmlStream == null)
{
throw new ArgumentNullException("xmlStream");
}
return (T)xmlSerializer.Deserialize(xmlStream);
}
答案 1 :(得分:1)
您使用allConfig.Save();
保存课程,然后尝试使用
allConfig.databaseConfiguration.Load();
allConfig.merlinConfiguration.Load();
看起来您没有正确使用XmlSerializer
。
所以试试这个:
public class Person
{
public string Name;
public int Age;
}
p.Name = "Stacey"; p.Age = 30;
//serialize
XmlSerializer xs = new XmlSerializer (typeof (Person));
using (Stream s = File.Create ("person.xml"))
xs.Serialize (s, p);
//deserialize
Person p2;
using (Stream s = File.OpenRead ("person.xml"))
p2 = (Person) xs.Deserialize (s);
Console.WriteLine (p2.Name + " " + p2.Age); // Stacey 30
更新: 在这里,我对您的代码采用示例。我删除XmlEncapsulator因为我认为它实现了Save and Load方法,这并不是真正需要的。如果你真的需要它,你可以退货。不要以为某些事情可能会改变; 所以,这里是代码:
AllConfig all = new AllConfig();
all.databaseConfiguration = new DataBaseConfiguration();
all.databaseConfiguration.dbIP = "123";
all.databaseConfiguration.password = "asd";
all.databaseConfiguration.port = 123;
all.databaseConfiguration.username = "sad";
all.merlinConfiguration = new MerlinConfiguration();
all.merlinConfiguration.MerlinIP = "123";
all.merlinConfiguration.MerlinPort = 123;
all.merlinConfiguration.RecievingPort = 123;
//serialize
XmlSerializer xs = new XmlSerializer(typeof(AllConfig));
using (Stream s = File.Create ("config.xml"))
xs.Serialize (s, all);
//deserialize
AllConfig all2;
using (Stream s = File.OpenRead ("config.xml"))
all2 = (AllConfig)xs.Deserialize(s);
Console.WriteLine(all2.ToString());
答案 2 :(得分:1)
以下是我如何使用您的数据类型实现它。正如其他人所说,我只是删除您从中派生数据类型的XMLEncapsulator
。另请注意,在生成的xml中,您指定的XmlElement
属性现在正在受到尊重。
public void Test()
{
var dbConfig = new DataBaseConfiguration();
dbConfig.dbIP = "127.0.0.1";
dbConfig.port = 12345;
dbConfig.username = "harlam357";
dbConfig.password = "password";
var merlinConfig = new MerlinConfiguration();
merlinConfig.MerlinIP = "192.168.0.1";
merlinConfig.MerlinPort = 8080;
merlinConfig.RecievingPort = 8081;
var config = new AllConfig { databaseConfiguration = dbConfig, merlinConfiguration = merlinConfig };
string xml = Serialize(config);
var config2 = Deserialize<AllConfig>(xml);
Debug.Assert(config2.databaseConfiguration.dbIP == "127.0.0.1");
Debug.Assert(config2.databaseConfiguration.port == 12345);
Debug.Assert(config2.databaseConfiguration.username == "harlam357");
Debug.Assert(config2.databaseConfiguration.password == "password");
Debug.Assert(config2.merlinConfiguration.MerlinIP == "192.168.0.1");
Debug.Assert(config2.merlinConfiguration.MerlinPort == 8080);
Debug.Assert(config2.merlinConfiguration.RecievingPort == 8081);
}
public static string Serialize<T>(T value) where T : class
{
if (value == null) return null; // throw or whatever fits your use case
var xmlSerializer = new XmlSerializer(typeof(T));
using (var stream = new MemoryStream())
{
xmlSerializer.Serialize(stream, value);
return Encoding.UTF8.GetString(stream.GetBuffer());
}
}
public static T Deserialize<T>(string xml) where T : class
{
if (xml == null) return null; // throw or whatever fits your use case
var xmlSerializer = new XmlSerializer(typeof(T));
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
return (T)xmlSerializer.Deserialize(stream);
}
}
生成的XML
<?xml version="1.0"?>
<AllConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Database-Settings>
<dbIP>127.0.0.1</dbIP>
<port>12345</port>
<username>harlam357</username>
<password>password</password>
</Database-Settings>
<Merlin-Settings>
<MerlinIP>192.168.0.1</MerlinIP>
<MerlinPort>8080</MerlinPort>
<RecievingPort>8081</RecievingPort>
</Merlin-Settings>
</AllConfig>
答案 3 :(得分:0)
修复了我自己的问题。这是我加载它的方式,最后我最终这样做了;
allConfig = new AllConfig();
dbConfig = new DataBaseConfiguration();
merlinConfig = new MerlinConfiguration();
allConfig.databaseConfiguration = dbConfig;
allConfig.merlinConfiguration = merlinConfig;
allConfig.Load();
所以我创建了一个类序列化的实例,然后创建了包含的类,并将它们分配给主类。然后我加载了主类(我假设通过序列化程序填充它所包含的类,然后我像这样访问它们;
allConfig.databaseConfiguration.port;
allConfig.databaseConfiguration.username;
等等。感谢大家的建议,真的帮助了我。