it-swarm.dev

Serializovat objekt na XML

Mám třídu C #, kterou jsem zdědil. Úspěšně jsem "postavil" objekt. Ale musím serializovat objekt do XML. Existuje snadný způsob, jak to udělat?

Vypadá to, že třída byla nastavena pro serializaci, ale nejsem si jistý, jak získat reprezentaci XML. Moje definice třídy vypadá takto:

[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
{
  ...
}

Tady je to, co jsem si myslel, že můžu udělat, ale nefunguje to:

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

Jak mohu získat XML reprezentaci tohoto objektu?

230
user462166

Musíte použít XmlSerializer pro serializaci XML. Níže je ukázkový úryvek.

 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á jsem upravil mé vrátit řetězec spíše než používat ref proměnnou jako dole.

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

Jeho použití by bylo toto:

var xmlString = obj.Serialize();
96
Kwex

Následující funkce lze zkopírovat do libovolného objektu přidat funkci ukládání XML pomocí oboru názvů 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();
    }
}

Chcete-li vytvořit objekt z uloženého souboru, přidejte následující funkci a nahraďte [ObjectType] typem objektu, který má být vytvořen.

/// <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

Pomocí této funkce můžete získat serializovaný XML z libovolného objektu.

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

Můžete to zavolat od klienta.

28
Imrul

Třída rozšíření:

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

Používání:

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

string xml = foo.Serialize();

Stačí odkazovat na jmenný prostor, který drží vaši metodu rozšíření v souboru, který chcete použít, a bude fungovat (v mém příkladu by to bylo: using MyProj.Extensions;)

Pokud chcete, aby byla metoda rozšíření specifická pouze pro určitou třídu (např. Foo), můžete argument T nahradit v metodě rozšíření, např. 

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

28
Aleksandr Albert

Chcete-li serializovat objekt, postupujte takto:

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

Také si pamatujte, že pro XmlSerializer pro práci, potřebujete parametr bez konstruktoru.

17
Rox

Začnu s kopií odpovědi Ben Gripky:

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

Použil jsem tento kód dříve. Ale realita ukázala, že toto řešení je trochu problematické. Obvykle většina programátorů pouze serializovat nastavení na uložení a deserialize nastavení na zatížení. To je optimistický scénář. Jakmile se serializace z nějakého důvodu nezdařila, soubor je částečně napsán, soubor XML není úplný a je neplatný. V důsledku toho deserializace XML nefunguje a aplikace může při startu selhat. Pokud soubor není obrovský, doporučuji nejprve serializovat objekt na MemoryStream a pak zapsat stream do souboru. Tento případ je zvláště důležitý, pokud existuje nějaká komplikovaná vlastní serializace. Nikdy nemůžete testovat všechny případy.

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

Deserializace v reálném scénáři by se měla počítat s poškozeným serializačním souborem, někdy se to stane. Funkce zátěže, kterou poskytuje Ben Gripka, je v pořádku.

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

A mohlo by to být zabaleno nějakým scénářem obnovy. Je vhodný pro soubory nastavení nebo jiné soubory, které lze v případě problémů odstranit.

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

Je to o něco složitější než volání metody ToString třídy, ale ne moc.

Zde je jednoduchá drop-in funkce, kterou můžete použít k serializaci jakéhokoliv typu objektu. Vrátí řetězec obsahující obsah serializovaného XML:

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

Zde je dobrý návod, jak to udělat

Chcete-li to provést, měli byste v podstatě použít třídu System.Xml.Serialization.XmlSerializer.

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

Výsledek můžete vytvořit a uložit jako soubor XML v požadovaném místě.

2
Dev Try

můj pracovní kód. Vrací utf8 xml povolit prázdný jmenný prostor.

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

Příklad vrátí odpověď Yandex api payment 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
dev-siberia

Mám jednoduchý způsob, jak serializovat objekt do XML pomocí C #, funguje to skvěle a je velmi opakovaně použitelný. Vím, že se jedná o starší vlákno, ale chtěl jsem to poslat, protože to může někdo pomoci.

Zde je návod, jak tuto metodu volám:

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

Zde je třída, která dělá práci:

Poznámka: Protože se jedná o metody rozšíření, musí být ve statické třídě.

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

Nebo můžete tuto metodu přidat do objektu:

    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

Všechny výše uvedené odpovědi jsou správné. Toto je nejjednodušší verze:

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