2012-06-28 3 views
1

Мне удалось легко сгенерировать XML-файл из нескольких классов, как показано ниже;десериализация 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. 

Следует ли загружать два класса конфигурации и назначать их в общий класс конфигурации? или мне нужно загрузить общий класс и назначить классы sub-config, например;

allConfig = new AllConfig(); 

       dbConfig = new DataBaseConfiguration(); 
       merlinConfig = new MerlinConfiguration(); 

       allConfig.databaseConfiguration = dbConfig; 
       allConfig.merlinConfiguration = merlinConfig; 

       allConfig.databaseConfiguration.Load(); 
       allConfig.merlinConfiguration.Load(); 

изменить: heres мой метод загрузки;

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

Вы спрашиваете, как вы десериализации XML в свой объект? – Kane

+0

Думаю, да, да. edit: у меня уже есть .load() для загрузки, я просто не знаю, какой заказ их загрузить. Имеет ли это смысл? –

+0

Что такое '' XMLEncapsulator'? Пожалуйста, покажите нам код, который вы используете для сериализации объекта. Не похоже, что вы используете XmlSerializer напрямую. В противном случае результирующий xml будет иметь элементы «Database-Settings» и «Merlin-Settings» в качестве элементов. – harlam357

ответ

0

Исправлены мои собственные проблемы, ребята. Это было то, как я загружал его, в конце концов я закончил так делать;

allConfig = new AllConfig(); 
       dbConfig = new DataBaseConfiguration(); 
       merlinConfig = new MerlinConfiguration(); 
       allConfig.databaseConfiguration = dbConfig; 
       allConfig.merlinConfiguration = merlinConfig; 
       allConfig.Load(); 

так я создал экземпляр класса я сериализация, затем создал классы, который является состоит прочь, и назначил их основному классу. Тогда я загрузил основной класс (который я предполагаю, что через сериализатору заполнит классы он состоит прочь, а затем я получить доступ к ним как так,

allConfig.databaseConfiguration.port; 
allConfig.databaseConfiguration.username; 

и так далее спасибо за советы, хотя ребята, действительно помогли мне. .

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

см. Править: извините, я не сделал этого яснее раньше –

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 

C# in Nutshell

UPDATE: Здесь я принимаю пример кода. Я удаляю 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()); 
+0

первый бит выглядел неплохо, но, к сожалению, не работал. я попробую посмотреть, почему .. –

+0

Я все еще не могу заставить его работать. от того, как я сериализую его, я создаю общую конфигурацию и две подконфигуры, назначаю вспомогательные конфиги в общую конфигурацию и сериализую общую версию. Но я не знаю, как вернуть ее таким образом. edit: может быть просто зафиксировал его. –

+0

@ Shane.C Я принимаю пример к вашему коду – Eugene

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> 
+0

спасибо за ваш вклад:) это был только десериализатор, на который я застрял, но я исправил это сейчас! –

Смежные вопросы