Scrivi facilmente un’intera istanza di class in XML File e leggi di nuovo

Ho una class principale chiamata theGarage , che contiene istanze delle nostre classi di clienti, fornitori e lavori.

Voglio salvare i dati del programma in un file XML, ho usato il codice qui sotto (solo un frammento, ho il codice corrispondente per le altre classi). Mi chiedo se c’è un modo più semplice per me di farlo, come scrivere l’intera class theGarage in un file XML e leggerlo senza dover scrivere tutto questo codice come ho sotto.

  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(); } } } 

C’è un modo molto più semplice di serializzare oggetti, invece usa XmlSerializer . Vedi la documentazione qui .

Lo snippet di codice per serializzare il tuo garage su file potrebbe essere simile a:

 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); 

E codice per caricare il garage dal file:

 using(var sr = new StreamReader(@"c:\temp\garage.xml")) { garage = (theGarage)xs.Deserialize(sr); } 

Che ne dici di un paio di metodi di estensione nifty, quindi puoi facilmente leggere / scrivere questo in / da file.

 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(this string data) { XmlSerializer s = new XmlSerializer(typeof(T)); using (StringReader reader = new StringReader(data)) { object obj = s.Deserialize(reader); return (T)obj; } } } 

esempio

  var xmlData = myObject.ToXml(); var anotherObject = xmlData.FromXml(); 

Ho appena scritto un post sul blog sul salvataggio dei dati di un object su Binary, XML o Json . Ecco le funzioni per scrivere e leggere l’istanza di class da / a XML. Vedi il mio post sul blog per ulteriori dettagli.

Richiede l’assembly System.Xml da includere nel progetto.

 ///  /// Writes the given object instance to an XML file. /// Only Public properties and variables will be written to the file. These can be any type though, even other classs. /// If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute. /// Object type must have a parameterless constructor. ///  /// The type of object being written to the file. /// The file path to write the object instance to. /// The object instance to write to the file. /// If false the file will be overwritten if it already exists. If true the contents will be appended to the file. public static void WriteToXmlFile(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(); } } ///  /// Reads an object instance from an XML file. /// Object type must have a parameterless constructor. ///  /// The type of object to read from the file. /// The file path to read the object instance from. /// Returns a new instance of the object read from the XML file. public static T ReadFromXmlFile(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(); } } 

Esempio

 // Write the list of salesman objects to file. WriteToXmlFile("C:\TheGarage.txt", customer); // Read the list of salesman objects from the file back into a variable. Customer customer = ReadFromXmlFile("C:\TheGarage.txt"); 

Per il mio progetto utilizzo DataContractSerializer . Io contrasto con XmlSerializer che può gestire più riferimenti allo stesso object in modo tale che i dati non vengano duplicati in xml e ripristinati come salvati.