J'ai une classe principale appelée theGarage
, qui contient des instances de nos classes client, fournisseur et travaux.
Je veux sauvegarder les données du programme dans un fichier XML, j'ai utilisé le code ci-dessous (juste un extrait, j'ai le code correspondant pour les autres classes). Je me demande s’il existe un moyen plus simple de le faire, comme écrire toute la classe theGarage dans un fichier XML et le lire sans avoir à écrire tout ce code comme ci-dessous.
public void saveToFile()
{
using (XmlWriter writer = XmlWriter.Create("theGarage.xml"))
{
writer.WriteStartDocument();
///
writer.WriteStartElement("theGarage");
writer.WriteStartElement("Customers");
foreach (Customer Customer in Program.theGarage.Customers)
{
writer.WriteStartElement("Customer");
writer.WriteElementString("FirstName", Customer.FirstName);
writer.WriteElementString("LastName", Customer.LastName);
writer.WriteElementString("Address1", Customer.Address1);
writer.WriteElementString("Address2", Customer.Address2);
writer.WriteElementString("Town", Customer.Town);
writer.WriteElementString("County", Customer.County);
writer.WriteElementString("PostCode", Customer.Postcode);
writer.WriteElementString("TelephoneHome", Customer.TelephoneHome);
writer.WriteElementString("TelephoneMob", Customer.TelephoneMob);
//begin vehicle list
writer.WriteStartElement("Vehicles");
foreach (Vehicle Vehicle in Customer.Cars)
{
writer.WriteStartElement("Vehicle");
writer.WriteElementString("Make", Vehicle.Make);
writer.WriteElementString("Model", Vehicle.Model);
writer.WriteElementString("Colour", Vehicle.Colour);
writer.WriteElementString("EngineSize", Vehicle.EngineSize);
writer.WriteElementString("Registration", Vehicle.Registration);
writer.WriteElementString("Year", Vehicle.YearOfFirstReg);
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndElement();
}
}
}
Il existe un moyen beaucoup plus simple de sérialiser des objets, utilisez plutôt XmlSerializer
. Voir la documentation ici .
L'extrait de code permettant de sérialiser votre garage dans un fichier peut ressembler à:
var garage = new theGarage();
// TODO init your garage..
XmlSerializer xs = new XmlSerializer(typeof(theGarage));
TextWriter tw = new StreamWriter(@"c:\temp\garage.xml");
xs.Serialize(tw, garage);
Et le code pour charger le garage à partir du fichier:
using(var sr = new StreamReader(@"c:\temp\garage.xml"))
{
garage = (theGarage)xs.Deserialize(sr);
}
Qu'en est-il de quelques méthodes d'extension astucieuses, alors vous pouvez facilement lire/écrire ceci dans/depuis un fichier.
public static class Extensions
{
public static string ToXml(this object obj)
{
XmlSerializer s = new XmlSerializer(obj.GetType());
using (StringWriter writer = new StringWriter())
{
s.Serialize(writer, obj);
return writer.ToString();
}
}
public static T FromXml<T>(this string data)
{
XmlSerializer s = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(data))
{
object obj = s.Deserialize(reader);
return (T)obj;
}
}
}
exemple
var xmlData = myObject.ToXml();
var anotherObject = xmlData.FromXml<ObjectType>();
Je viens d'écrire un article de blog sur la sauvegarde des données d'un objet au format binaire, XML ou Json . Voici les fonctions pour écrire et lire l'instance de classe dans/à partir de XML. Voir mon blog pour plus de détails.
Nécessite l'assembly System.Xml pour être inclus dans votre projet.
/// <summary>
/// Writes the given object instance to an XML file.
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute.</para>
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToXmlFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var serializer = new XmlSerializer(typeof(T));
writer = new StreamWriter(filePath, append);
serializer.Serialize(writer, objectToWrite);
}
finally
{
if (writer != null)
writer.Close();
}
}
/// <summary>
/// Reads an object instance from an XML file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the XML file.</returns>
public static T ReadFromXmlFile<T>(string filePath) where T : new()
{
TextReader reader = null;
try
{
var serializer = new XmlSerializer(typeof(T));
reader = new StreamReader(filePath);
return (T)serializer.Deserialize(reader);
}
finally
{
if (reader != null)
reader.Close();
}
}
// Write the list of salesman objects to file.
WriteToXmlFile<Customer>("C:\TheGarage.txt", customer);
// Read the list of salesman objects from the file back into a variable.
Customer customer = ReadFromXmlFile<Customer>("C:\TheGarage.txt");
Pour mon projet, j'utilise DataContractSerializer . Je contraste avec XmlSerializer il peut gérer plusieurs références au même objet de manière à ce que les données ne soient pas dupliquées au format XML et restaurées telles quelles.