web-dev-qa-db-fra.com

Sérialiser un objet en XML

J'ai une classe C # dont j'ai hérité. J'ai réussi à "construire" l'objet. Mais j'ai besoin de sérialiser l'objet en XML. Y a-t-il un moyen facile de le faire?

Il semble que la classe ait été configurée pour la sérialisation, mais je ne sais pas comment obtenir la représentation XML. Ma définition de classe ressemble à ceci:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.domain.com/test")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.domain.com/test", IsNullable = false)]
public partial class MyObject
{
  ...
}

Voici ce que je pensais pouvoir faire, mais cela ne fonctionne pas:

MyObject o = new MyObject();
// Set o properties
string xml = o.ToString();

Comment puis-je obtenir la représentation XML de cet objet?

230
user462166

Vous devez utiliser XmlSerializer pour la sérialisation XML. Vous trouverez ci-dessous un extrait de code.

 XmlSerializer xsSubmit = new XmlSerializer(typeof(MyObject));
 var subReq = new MyObject();
 var xml = "";

 using(var sww = new StringWriter())
 {
     using(XmlWriter writer = XmlWriter.Create(sww))
     {
         xsSubmit.Serialize(writer, subReq);
         xml = sww.ToString(); // Your XML
     }
 }
415
RameshVel

J'ai modifié le mien pour retourner une chaîne plutôt que d'utiliser une variable ref comme ci-dessous.

public static string Serialize<T>(this T value)
{
    if (value == null)
    {
        return string.Empty;
    }
    try
    {
        var xmlserializer = new XmlSerializer(typeof(T));
        var stringWriter = new StringWriter();
        using (var writer = XmlWriter.Create(stringWriter))
        {
            xmlserializer.Serialize(writer, value);
            return stringWriter.ToString();
        }
    }
    catch (Exception ex)
    {
        throw new Exception("An error occurred", ex);
    }
}

Son utilisation serait comme ceci:

var xmlString = obj.Serialize();
96
Kwex

La fonction suivante peut être copiée dans n'importe quel objet pour ajouter une fonction de sauvegarde XML à l'aide de l'espace de noms System.Xml.

/// <summary>
/// Saves to an xml file
/// </summary>
/// <param name="FileName">File path of the new xml file</param>
public void Save(string FileName)
{
    using (var writer = new System.IO.StreamWriter(FileName))
    {
        var serializer = new XmlSerializer(this.GetType());
        serializer.Serialize(writer, this);
        writer.Flush();
    }
}

Pour créer l'objet à partir du fichier enregistré, ajoutez la fonction suivante et remplacez [ObjectType] par le type d'objet à créer.

/// <summary>
/// Load an object from an xml file
/// </summary>
/// <param name="FileName">Xml file name</param>
/// <returns>The object created from the xml file</returns>
public static [ObjectType] Load(string FileName)
{
    using (var stream = System.IO.File.OpenRead(FileName))
    {
        var serializer = new XmlSerializer(typeof([ObjectType]));
        return serializer.Deserialize(stream) as [ObjectType];
    }
}
35
Ben Gripka

Vous pouvez utiliser la fonction comme ci-dessous pour obtenir du XML sérialisé à partir de n'importe quel objet.

public static bool Serialize<T>(T value, ref string serializeXml)
{
    if (value == null)
    {
        return false;
    }
    try
    {
        XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
        StringWriter stringWriter = new StringWriter();
        XmlWriter writer = XmlWriter.Create(stringWriter);

        xmlserializer.Serialize(writer, value);

        serializeXml = stringWriter.ToString();

        writer.Close();
        return true;
    }
    catch (Exception ex)
    {
        return false;
    }
}

Vous pouvez appeler cela du client.

28
Imrul

Pour sérialiser un objet, faites:

 using (StreamWriter myWriter = new StreamWriter(path, false))
 {
     XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
     mySerializer.Serialize(myWriter, objectToSerialize);
 }

Rappelez-vous également que pour que XmlSerializer fonctionne, vous avez besoin d'un constructeur sans paramètre.

17
Rox

Je commencerai par la réponse en copie de Ben Gripka:

public void Save(string FileName)
{
    using (var writer = new System.IO.StreamWriter(FileName))
    {
        var serializer = new XmlSerializer(this.GetType());
        serializer.Serialize(writer, this);
        writer.Flush();
    }
}

J'ai utilisé ce code plus tôt. Mais la réalité a montré que cette solution est un peu problématique. En général, la plupart des programmeurs ne font que sérialiser les paramètres d’enregistrement et les paramètres de désérialisation au chargement. C'est un scénario optimiste. Une fois que la sérialisation a échoué, pour une raison quelconque, le fichier est partiellement écrit, le fichier XML n'est pas complet et il n'est pas valide. En conséquence, la désérialisation XML ne fonctionne pas et votre application peut se bloquer au démarrage. Si le fichier n'est pas énorme, je suggère tout d'abord de sérialiser l'objet en MemoryStream, puis d'écrire le flux dans le fichier. Ce cas est particulièrement important en cas de sérialisation complexe et personnalisée. Vous ne pouvez jamais tester tous les cas.

public void Save(string fileName)
{
    //first serialize the object to memory stream,
    //in case of exception, the original file is not corrupted
    using (MemoryStream ms = new MemoryStream())
    {
        var writer = new System.IO.StreamWriter(ms);    
        var serializer = new XmlSerializer(this.GetType());
        serializer.Serialize(writer, this);
        writer.Flush();

        //if the serialization succeed, rewrite the file.
        File.WriteAllBytes(fileName, ms.ToArray());
    }
}

Le scénario de désérialisation dans le monde réel devrait compter avec un fichier de sérialisation corrompu, cela arrive parfois. La fonction de charge fournie par Ben Gripka est satisfaisante.

public static [ObjectType] Load(string fileName)
{
    using (var stream = System.IO.File.OpenRead(fileName))
    {
        var serializer = new XmlSerializer(typeof([ObjectType]));
        return serializer.Deserialize(stream) as [ObjectType];        
    }    
}

Et il pourrait être enveloppé par un scénario de récupération. Il convient aux fichiers de paramètres ou à d’autres fichiers pouvant être supprimés en cas de problème.

public static [ObjectType] LoadWithRecovery(string fileName)
{
    try
    {
        return Load(fileName);
    }
    catch(Excetion)
    {
        File.Delete(fileName); //delete corrupted settings file
        return GetFactorySettings();
    }
}
16
Tomas Kubes

C'est un peu plus compliqué que d'appeler la méthode ToString de la classe, mais pas beaucoup.

Voici une fonction simple à utiliser que vous pouvez utiliser pour sérialiser tout type d'objet. Il retourne une chaîne contenant le contenu XML sérialisé:

public string SerializeObject(object obj)
{
    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
    using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) {
        serializer.Serialize(ms, obj);
        ms.Position = 0;
        xmlDoc.Load(ms);
        return xmlDoc.InnerXml;
    }
}
6
Cody Gray

Voici un bon tutoriel sur la façon de faire cela

Vous devriez essentiellement utiliser la classe System.Xml.Serialization.XmlSerializer pour le faire.

3
Aamir
    string FilePath = ConfigurationReader.FileLocation;   //Getting path value from web.config            
    XmlSerializer serializer = new XmlSerializer(typeof(Devices)); //typeof(object)
            MemoryStream memStream = new MemoryStream();
            serializer.Serialize(memStream, lstDevices);//lstdevices : I take result as a list.
            FileStream file = new FileStream(folderName + "\\Data.xml", FileMode.Create, FileAccess.ReadWrite); //foldername:Specify the path to store the xml file
            memStream.WriteTo(file);
            file.Close();

Vous pouvez créer et stocker le résultat sous forme de fichier XML à l'emplacement souhaité.

2
Dev Try

mon code de travail. Renvoie utf8 xml active un espace de noms vide.

// override StringWriter
public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding => Encoding.UTF8;
}

private string GenerateXmlResponse(Object obj)
{    
    Type t = obj.GetType();

    var xml = "";

    using (StringWriter sww = new Utf8StringWriter())
    {
        using (XmlWriter writer = XmlWriter.Create(sww))
        {
            var ns = new XmlSerializerNamespaces();
            // add empty namespace
            ns.Add("", "");
            XmlSerializer xsSubmit = new XmlSerializer(t);
            xsSubmit.Serialize(writer, obj, ns);
            xml = sww.ToString(); // Your XML
        }
    }
    return xml;
}

Exemple de réponse réponse Paiement Yandex api URL Aviso:

<?xml version="1.0" encoding="utf-8"?><paymentAvisoResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" performedDatetime="2017-09-01T16:22:08.9747654+07:00" code="0" shopId="54321" invoiceId="12345" orderSumAmount="10643" />
2
dev-siberia

J'ai un moyen simple de sérialiser un objet en XML en utilisant C #, cela fonctionne très bien et il est hautement réutilisable. Je sais que c'est un fil plus ancien, mais je voulais le poster car quelqu'un pourrait trouver cela utile.

Voici comment j'appelle la méthode:

var objectToSerialize = new MyObject();
var xmlString = objectToSerialize.ToXmlString();

Voici la classe qui fait le travail:

Remarque: Étant donné qu'il s'agit de méthodes d'extension, elles doivent appartenir à une classe statique.

using System.IO;
using System.Xml.Serialization;

public static class XmlTools
{
    public static string ToXmlString<T>(this T input)
    {
        using (var writer = new StringWriter())
        {
            input.ToXml(writer);
            return writer.ToString();
        }
    }

    private static void ToXml<T>(this T objectToSerialize, StringWriter writer)
    {
        new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
    }
}
0
Tyler Kalosza

Voici un code de base qui vous aidera à sérialiser les objets C # en XML:

using System;

public class clsPerson
{
  public  string FirstName;
  public  string MI;
  public  string LastName;
}

class class1
{ 
   static void Main(string[] args)
   {
      clsPerson p=new clsPerson();
      p.FirstName = "Jeff";
      p.MI = "A";
      p.LastName = "Price";
      System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
      x.Serialize(Console.Out, p);
      Console.WriteLine();
      Console.ReadLine();
   }
}    
0
Ali Asad

Ou vous pouvez ajouter cette méthode à votre objet:

    public void Save(string filename)
    {
        var ser = new XmlSerializer(this.GetType());
        using (var stream = new FileStream(filename, FileMode.Create))
            ser.Serialize(stream, this);
    }
0
Bigjim

Toutes les réponses votées ci-dessus sont correctes. Ceci est juste la version la plus simple:

private string Serialize(Object o)
{
    using (var writer = new StringWriter())
    {
        new XmlSerializer(o.GetType()).Serialize(writer, o);
        return writer.ToString();
    }
}
0
avj