XML-сериализация хеш-таблицы (C # 3.0) - PullRequest
3 голосов
/ 27 мая 2010

Привет! Я пытаюсь сериализовать хэш-таблицу, но не происходит

private void Form1_Load(object sender, EventArgs e)
        {
            Hashtable ht = new Hashtable();        

            DateTime dt = DateTime.Now;
            for (int i = 0; i < 10; i++)
                ht.Add(dt.AddDays(i), i);           
            SerializeToXmlAsFile(typeof(Hashtable), ht);
        }

private void SerializeToXmlAsFile(Type targetType, Object targetObject)
        {
            try
            {
                string fileName = @"C:\output.xml";
                //Serialize to XML
                XmlSerializer s = new XmlSerializer(targetType);
                TextWriter w = new StreamWriter(fileName);
                s.Serialize(w, targetObject);
                w.Flush();
                w.Close();
            }
            catch (Exception ex) { throw ex; }
        }

После поиска в Google я обнаружил, что объекты, приводящие в движение IDictonary, не могут быть сериализованы. Тем не менее, я добился успеха с двоичной сериализацией.

Но я хочу иметь XML. Есть ли способ сделать это?

Я использую C # 3.0

Спасибо

Ответы [ 3 ]

3 голосов
/ 10 июня 2010

Прежде всего, начиная с C # 2.0, вы можете использовать безопасную версию очень старой Hashtable, которая вышла из .NET 1.0. Так что вы можете использовать Dictionary<DateTime, int>.

Начиная с .NET 3.0 вы можете использовать DataContractSerializer. Таким образом, вы можете переписать свой код следующим образом

private void Form1_Load(object sender, EventArgs e)
    {
        MyHashtable ht = new MyHashtable();        

        DateTime dt = DateTime.Now;
        for (int i = 0; i < 10; i++)
            ht.Add(dt.AddDays(i), i);           
        SerializeToXmlAsFile(typeof(Hashtable), ht);
    }

где SerializeToXmlAsFile и MyHashtable тип, который вы определяете следующим образом:

[CollectionDataContract (Name = "AllMyHashtable", ItemName = "MyEntry",
                         KeyName = "MyDate", ValueName = "MyValue")]
public class MyHashtable : Dictionary<DateTime, int> { }

private void SerializeToXmlAsFile(Type targetType, Object targetObject)
    {
        try {
            string fileName = @"C:\output.xml";
            DataContractSerializer s = new DataContractSerializer (targetType);
            XmlWriterSettings settings = new XmlWriterSettings ();
            settings.Indent = true;
            settings.IndentChars = ("    ");
            using (XmlWriter w = XmlWriter.Create (fileName, settings)) {
                s.WriteObject (w, targetObject);
                w.Flush ();
            }
        }
        catch (Exception ex) { throw ex; }
    }

Этот код создает C: \ output.xml файл со следующим содержанием:

<?xml version="1.0" encoding="utf-8"?>
<AllMyHashtable xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://schemas.datacontract.org/2004/07/DataContractXmlSerializer">
    <MyEntry>
        <MyDate>2010-06-09T22:30:00.9474539+02:00</MyDate>
        <MyValue>0</MyValue>
    </MyEntry>
    <MyEntry>
        <MyDate>2010-06-10T22:30:00.9474539+02:00</MyDate>
        <MyValue>1</MyValue>
    </MyEntry>
    <!-- ... -->
</AllMyHashtable>

Итак, как мы можем видеть все имена элементов целевых XML-файлов, которые мы можем свободно определить.

1 голос
/ 27 мая 2010

Вы можете создать свой собственный Hashtable, полученный из стандартного Hashtable с реализацией IXmlSerializable . Таким образом, вы будете иметь значение ReadXml (XmlReader reader) & WriteXml (XmlWriter writer) , где вы можете поместить свою собственную логику о том, как читать и записывать значения из вашего Hashtablw с помощью данных XmlReader & XmlWriter.

0 голосов
/ 27 мая 2010

Я предлагаю вам использовать DataContractSerializer, он более мощный и простой в использовании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...