Сериализация XML - можно ли сериализовать модель таким образом? - PullRequest
0 голосов
/ 04 февраля 2010

У меня есть следующая модель:

public class ABaseObject
{
    private Guid id = Guid.NewGuid();

    public ABaseObject()
    {
    }

    public Guid ID { get { return id; } }
}

public class ADerivedObject : ABaseObject
{
    public ADerivedObject()
    {
    }

    public string Name { get; set; }
}

public class AObjectCollection<T>
{
    private List<T> items = new List<T>();

    public AObjectCollection()
    {
    }

    public IEnumerable<T> Items { get { return items; } }
    public void Add(T item)
    {
        items.Add(item);
    }

    public void Save(string filePath)
    {
        FileStream writer = new FileStream(filePath, FileMode.Create);
        DataContractSerializer s = new DataContractSerializer(typeof(T));
        s.WriteObject(writer, this);
        writer.Close();
    }

    public void Load(string filePath)
    {
        FileStream fs = new FileStream(filePath, FileMode.Open);
        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
        DataContractSerializer ser = new DataContractSerializer(typeof(T));

        // Deserialize the data and read it from the instance.
        T deserializedObj = (T)ser.ReadObject(reader, true);
        reader.Close();
        fs.Close();
    }
}

Итак, в основном я хочу иметь возможность сделать следующее:

var der = new ADerivedObject();
der.Name = "Test";
var col = new AObjectCollection<ADerivedObject>();
col.Add(der);
col.Save("C:\MyCollection.xml");
...
var col2 = new AObjectCollection<ADerivedObject>();
col2.Load("C:\MyCollection.xml");

При сериализации это должно выглядеть примерно так:

<Collection>
    <Item>
        <ID></ID>
        <Name></Name>
    </Item>
</Collection>

Я поиграл с DataContracts и XmlSerializer, но не могу найти способ сделать это.

1 Ответ

1 голос
/ 04 февраля 2010

Этот код:

public class ABaseObject
{
    public ABaseObject() { }
    public Guid ID { get; set;}
}

[XmlType("Item")]
public class ADerivedObject : ABaseObject
{
    public ADerivedObject() {}
    public string Name { get; set; }
}

[XmlType("Collection")]
public class AObjectCollection<T>
{
    private System.Xml.Serialization.XmlSerializerNamespaces ns;
    private System.Xml.Serialization.XmlSerializer s;

    public AObjectCollection()
    {
        ns= new System.Xml.Serialization.XmlSerializerNamespaces();
        ns.Add( "", "");
        s= new System.Xml.Serialization.XmlSerializer(this.GetType());
        Items = new List<T>();
    }

    public List<T> Items { get; set; }
    public DateTime LastSaved { get;set; }

    public void Add(T item)
    {
        Items.Add(item);
    }

    public void Save(string filePath)
    {
        LastSaved= System.DateTime.Now;
        var xmlws = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };

        using ( var writer = System.Xml.XmlWriter.Create(filePath, xmlws))
        {
            s.Serialize(writer, this, ns);
        }
    }

    public static AObjectCollection<T2> Load<T2>(string filepath)
    {
        AObjectCollection<T2> obj;
        try
        {
            var s= new System.Xml.Serialization.XmlSerializer(typeof(AObjectCollection<T2>));
            using(System.IO.StreamReader reader= System.IO.File.OpenText(filepath))
            {
                obj= (AObjectCollection<T2>) s.Deserialize(reader);
            }
        }
        catch
        {
            obj= new AObjectCollection<T2>();
        }

        return obj;
    }
}

производит этот вывод:

<Collection>
  <Items>
    <Item>
      <ID>00000000-0000-0000-0000-000000000000</ID>
      <Name>Test</Name>
    </Item>
  </Items>
  <LastSaved>2010-02-04T07:32:05.812-05:00</LastSaved>
</Collection>

Существуют способы настройки XML для удаления слоя Collection / Items. Ищите SO по другим вопросам Коллекции / Сериализации.

...