Serializacja jest fajna póki robi dokładnie to co chcemy, lub jest nam to wszystko jedno.
Nagle potem okazuje się, że czegoś się zrobić nie da, albo wymaga to ogromnej gimnastyki.
Takiego XML-a można sobie zapisywać i odczytywać "ręcznie". Przynajmniej ma się dokładną kontrolę nad wyglądem XML-a:
using System;
using System.IO;
using System.Collections.Generic;
using System.Xml.Linq;
namespace serializacja
{
public struct Klasa
{
public int id;
public string name;
public Klasa(int aid,string aname)
{
id = aid;
name = aname;
}
}
public class Modul : List<Klasa>
{
public string name;
public Modul(string aname)
{
name = aname;
}
}
public class ListaModulow:List<Modul>
{
public static ListaModulow FromXml(XDocument xml)
{
ListaModulow Result = new ListaModulow();
foreach (var mnode in xml.Root.Elements("module"))
{
var modul = new Modul(mnode.Attribute("name").Value);
foreach (var cnode in mnode.Elements("class"))
modul.Add(new Klasa(int.Parse(cnode.Attribute("id").Value),
cnode.Attribute("name").Value));
Result.Add(modul);
}
return Result;
}
public XDocument ToXml()
{
XDocument xml = new XDocument();
var root=new XElement("modules");
foreach (var modul in this)
{
var mnode = new XElement("module");
mnode.Add(new XAttribute("name", modul.name));
foreach (var klasa in modul)
{
var cnode = new XElement("class");
cnode.Add(new XAttribute("id", klasa.id));
cnode.Add(new XAttribute("name", klasa.name));
mnode.Add(cnode);
}
root.Add(mnode);
}
xml.Add(root);
return xml;
}
}
class Program
{
static void Main(string[] args)
{
// tworzenie listy
ListaModulow lista = new ListaModulow() {
new Modul("module1") {
new Klasa(1,"class1"),
new Klasa(2,"class2"),
new Klasa(3,"class3")},
new Modul("module2") {
new Klasa(1,"class4"),
new Klasa(2,"class5")
}};
// tworzenie xml i zapis do pliku
lista.ToXml().Save(@"plik.xml");
// wyświetl plik xml
Console.WriteLine("Zawartość pliku XML:");
var xdoc = XDocument.Load(@"plik.xml");
Console.WriteLine(xdoc);
// odczyt z pliku
var lista2=ListaModulow.FromXml(XDocument.Load(@"plik.xml"));
// wyświetl zawartość odczytanej listy
foreach (var m in lista2)
{
Console.WriteLine(m.name);
foreach (var c in m)
Console.WriteLine("{0} - {1}",c.id,c.name);
}
Console.ReadKey();
}
}
}
Tylko gdy już jesteśmy przy LINQ, może się okazać że te klasy w ogóle nie będą potrzebne, bo można operować tworząc zapytania na obiektach xml-owych bezpośrednio…
projektowanie napisał(a)
public class ClassInfo
{
private StringCollection sCol;
public class StringCollection
To jest zbyteczne. Tworzysz kulawego wrappera na listę, jak możesz po prostu dziedziczyć po tej liście.
Jeśli nie chcesz, aby wszystkie pola były publiczne, możesz przenieść część kodu z metod FromXml/ToXml z powyższego przykładu do tych "pomniejszych" klas.