Sérialisation xml

De Banane Atomic
Version datée du 19 mai 2017 à 23:03 par Nicolas (discussion | contributions) (→‎Sérialiser dans un fichier)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigationAller à la recherche

À savoir

  • XmlSerializer ne permet pas de sérialiser les Dictionary.
  • Seules les propriétés public avec un get et un set sont (dé)sérialisées

Sérialiser

Csharp.svg
var serializer = new XmlSerializer(objectToSerialize.GetType());

using (TextWriter writer = new StreamWriter("/path/to/file.xml"))  // dans un fichier
using (var writer = new StringWriter())                            // dans un string
{
    serializer.Serialize(writer, objectToSerialize);
    // dans un string
    var dataString = writer.ToString();
}

Désérialiser

Csharp.svg
MyClass myObject;
var serializer = new XmlSerializer(typeof(MyClass));

using (var s = new FileStream("/path/to/file.xml", FileMode.Open))  // depuis un fichier
using (var s = new StringReader(myString))                          // depuis un string
{
    XmlReader reader = XmlReader.Create(s);
    myObject = serializer.Deserialize(reader) as MyClass;
}

Implementer IXmlSerializable

Csharp.svg
public class ClasseSerialisable : IXmlSerializable
{
    public XmlSchema GetSchema()
    {
        // GetSchema() shall ALWAYS return null.
        return null;
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteAttributeString("MonAttribut", "ValeurA");
        writer.WriteValue("ValeurB");
        writer.WriteElementString("SousBalise", "ValeurC");
        // <ClasseSerialisable MonAttribut="ValeurA">
        //     ValeurB
        //     <SousBalise>ValeurC</SousBalise>
        // </ClasseSerialisable>
    }

    public void ReadXml(XmlReader reader)
    {
        reader.MoveToContent();
	var attributValue = reader.GetAttribute("MonAttribut"); // ValeurA
	reader.ReadStartElement();
	if (!reader.IsEmptyElement)
	{
            var content = reader.ReadContentAsString(); // ValeurB
            var sousBaliseValue = reader.ReadElementString("SousBalise"); // ValeurC
            reader.ReadEndElement();
	}
    }
}

var objetSérialisable = new ClasseSerialisable();
string objetSérialisé = null;

var ns = new XmlSerializerNamespaces();
ns.Add("xsd", "http://www.w3.org/2001/XMLSchema"); // xmlns="xsd:http://www.w3.org/2001/XMLSchema"
ns.Add("", "http://site/file.txt"); // xmlns="http://site/file.txt"
ns.Add("", ""); // pas d'ajout de xmlns supplémentaire

// Sérialisation
using (var stringWriter = new StringWriter())
{
    var serializer = new XmlSerializer(objetSérialisable.GetType());
    serializer.Serialize(stringWriter, objetSérialisable, ns); // ns est optionel
    objetSérialisé = stringWriter.ToString();
}

// Désérialisation
using (var stringReader = new StringReader(objetSérialisé))
{
    var serializer = new XmlSerializer(typeof(ClasseSerialisable));
    var xmlReader = XmlReader.Create(stringReader);
    var i = serializer.Deserialize(xmlReader);
}
Utiliser XmlTextWriter pour sérialiser directement dans un fichier.

Personnaliser la sérialisation

Csharp.svg
// Changer le nom de la balise
[XmlRoot("Root")]
public class MaClasse
{
    // Ne pas prendre en compte lors de la sérialisation
    [XmlIgnore]
    public object MaPropriété1 { get; set; }

    // Changer le nom de la balise
    [XmlElement(ElementName="SuperPropriété")]
    public object MaPropriété2 { get; set; }

    // La valeur de MaPropriété3 deviendra la valeur de l'attribut MonAttribut dans la balise de la classe contenante → Root
    [XmlAttribute("MonAttribut")]
    public object MaPropriété3 { get; set; }

    [XmlAttribute("noNamespaceSchemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public object MaPropriété33 { get; set; }

    [XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public string xsiSchemaLocation = "urn:xxx File.xsd";

    // La valeur de MaPropriété4 deviendra le contenu de la balise de la classe contenante → Root
    [XmlText]
    public object MaPropriété4 { get; set; }

    // Changer le nom de la balise contenant la collection + le nom des balises des éléments
    [XmlArray("MaCollection")]
    [XmlArrayItem("MonÉlément")]
    public List<string> MaPropriété5 { get; set; }
Xml.svg
<Root MonAttribut="" xsi:noNamespaceSchemaLocation=""
                     xsi:schemaLocation="urn:xxx File.xsd"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SuperPropriété></SuperPropriété>
  <MaCollection>
    <MonÉlément>...</MonÉlément>
    <MonÉlément>...</MonÉlément>
</Root>

Personnaliser la sérialisation d'une propriété

Csharp.svg
[XmlIgnore]
public object PropriétéANePasSérialiser { get; set; }
 
[XmlElement(ElementName="PropriétéANePasSérialiser")]
public string PropriétéDeSubstitution
{
    get
    {
        return PropriétéANePasSérialiser.ToString();
    }
    set
    {
        PropriétéANePasSérialiser = new PropriétéANePasSérialiser(value);
    }
}

Attribut encoding

utf-16 par défaut
Csharp.svg
var objetSérialisable = new ClasseSerialisable();
string objetSérialisé = null;

using (var stringWriter = new Utf8StringWriter())
{
    var serializer = new XmlSerializer(objetSérialisable.GetType());
    serializer.Serialize(stringWriter, objetSérialisable);
    objetSérialisé = stringWriter.ToString();
}

// forcer à utf-8
public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding
    {
        // UTF8Encoding(false) instead of Encoding.UTF8 to get utf-8 without BOM
        get { return new UTF8Encoding(false); }
    }
}

Sérialisation manuelle

Csharp.svg
Datetime dt = XmlConvert.ToDateTime("2015-07-07", XmlDateTimeSerializationMode.Utc);