Serializar um objecto para XML

Tenho uma classe C# que herdei. Eu construí com sucesso o objeto. Mas preciso de serializar o objecto em XML. Há uma maneira fácil de o fazer?

parece que a classe foi configurada para serialização, mas não sei como obter a representação XML. A minha definição de classe é a seguinte:

[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
{
  ...
}
Eis o que pensei que podia fazer, mas não funciona.
MyObject o = new MyObject();
// Set o properties
string xml = o.ToString();
Como consigo a representação XML deste objecto?

Author: Peter Mortensen, 2010-11-08

13 answers

Tem de usar o Xmlserializador para a serialização XML. Abaixo está um excerto de amostra.

 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
     }
 }
 392
Author: RameshVel, 2016-11-15 11:37:53

Modifiquei o meu para devolver um texto em vez de usar uma variável ref como em baixo.

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

O seu uso seria assim:

var xmlString = obj.Serialize();
 88
Author: Kwex, 2015-05-13 21:32:29

A seguinte função pode ser copiada para qualquer objecto para adicionar uma função de gravação XML usando o sistema.Espaço de nomes 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();
    }
}

Para criar o objecto a partir do ficheiro gravado, adicione a seguinte função e substitua [ObjectType] pelo tipo de objecto a criar.

/// <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];
    }
}
 32
Author: Ben Gripka, 2015-05-13 21:31:08

Pode usar a função abaixo para obter XML serializado a partir de qualquer objecto.

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;
    }
}
Podes ligar do cliente.
 28
Author: Imrul, 2015-05-13 21:30:08

Classe de extensão:

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

namespace MyProj.Extensions
{
    public static class XmlExtension
    {
        public static string Serialize<T>(this T value)
        {
            if (value == null) return string.Empty;

            var xmlSerializer = new XmlSerializer(typeof(T));

            using (var stringWriter = new StringWriter())
            {
                using (var xmlWriter = XmlWriter.Create(stringWriter,new XmlWriterSettings{Indent = true}))
                {
                    xmlSerializer.Serialize(xmlWriter, value);
                    return stringWriter.ToString();
                }    
            }
        }
    }
}

Utilização:

Foo foo = new Foo{MyProperty="I have been serialized"};

string xml = foo.Serialize();

Basta referenciar o espaço de nomes que contém o seu método de extensão no ficheiro em que gostaria de O usar e irá funcionar (no meu exemplo, seria: using MyProj.Extensions;)

Lembre-se que se quiser tornar o método de extensão específico a apenas uma classe em particular(eg., Foo), você pode substituir o argumento T no método de extensão, por exemplo.

public static string Serialize(this Foo value){...}

 26
Author: Aleksandr Albert, 2016-02-10 00:40:37

Para serializar um objecto, faça:

 using (StreamWriter myWriter = new StreamWriter(path, false))
 {
     XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
     mySerializer.Serialize(myWriter, objectToSerialize);
 }
{[[2]}lembre-se também que para o Xmlserialiser funcionar, você precisa de um construtor sem parâmetros.
 17
Author: Rox, 2015-05-13 21:29:16
Vou começar com a cópia da resposta 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();
    }
}
Usei este código antes. Mas a realidade mostrou que esta solução é um pouco problemática. Normalmente, a maioria dos programadores apenas serializa a configuração em Salvar e deserializar Configurações na carga. Este é um cenário otimista. Uma vez que a serialização falhou, por alguma razão, o arquivo é parcialmente escrito, O arquivo XML não está completo e é inválido. Em consequência, a deserialização XML não funciona e a sua aplicação pode falhar a começar. Se o arquivo não é enorme, eu sugiro primeiro serializar objeto para MemoryStream em seguida, escreva o fluxo para o arquivo. Este caso é especialmente importante se houver alguma serialização personalizada complicada. Nunca se pode testar todos os casos.
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());
    }
}
A deseralização no cenário do mundo real deve contar com arquivos de serialização corrompidos, isso acontece em algum momento. A função de carga fornecida por Ben Gripka é boa.
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];        
    }    
}
E pode ser embrulhado por algum cenário de recuperação. É adequado para configuração arquivos ou outros arquivos que podem ser excluídos em caso de problemas.
public static [ObjectType] LoadWithRecovery(string fileName)
{
    try
    {
        return Load(fileName);
    }
    catch(Excetion)
    {
        File.Delete(fileName); //delete corrupted settings file
        return GetFactorySettings();
    }
}
 16
Author: qub1n, 2016-10-24 07:25:02
É um pouco mais complicado do que chamar o método da classe, mas não muito.

Aqui está uma simples função drop-in que você pode usar para serializar qualquer tipo de objeto. Devolve um texto que contém o conteúdo em XML serializado:

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
Author: Cody Gray, 2010-11-08 12:13:49

Aqui está um bom tutorial sobre como fazer isso

Você deve basicamente usar System.Xml.Serialization.XmlSerializer classe para fazer isso.

 3
Author: Aamir, 2010-11-08 12:03:29
    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();

Pode criar e guardar o resultado como ficheiro xml no local desejado.

 2
Author: Dev Try, 2016-06-14 05:03:19
O meu código de trabalho. Devolve utf8 xml activar o espaço de nomes vazio.
// 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;
}

O exemplo devolve a resposta ao pagamento Yandex api Aviso url:

<?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
Author: dev-siberia, 2017-09-01 10:04:18

Ou pode adicionar este método ao seu objecto:

    public void Save(string filename)
    {
        var ser = new XmlSerializer(this.GetType());
        using (var stream = new FileStream(filename, FileMode.Create))
            ser.Serialize(stream, this);
    }
 0
Author: Bigjim, 2015-04-24 21:19:54

Aqui está um código básico que irá ajudar a serializar os objectos C# em 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();
   }
}    
 -1
Author: Ali Asad, 2018-02-06 12:33:14