Convertir une chaîne de caractères XML en objet

je reçois des chaînes XML sur une socket, et je voudrais les convertir en objets C#.

les messages sont de la forme:

<msg>
   <id>1</id>
   <action>stop</action>
</msg>

je suis nouveau à .Net, et ne suis pas sûr de la meilleure pratique pour effectuer ceci. J'ai déjà utilisé JAXB pour Java, et je n'étais pas sûr qu'il y ait quelque chose de similaire, ou que ce soit géré d'une manière différente.

128
demandé sur S.L. Barth 2010-07-06 19:04:49

11 réponses

vous devez utiliser l'outil xsd.exe qui est installé avec le SDK de Windows dans un répertoire quelque chose de similaire à:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin

et sur les ordinateurs 64 bits:

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin

et sur les ordinateurs Windows 10:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin

à la première exécution, vous utilisez xsd.exe et vous convertissez votre exemple XML en un fichier XSD (fichier de schéma XML):

xsd yourfile.xml

cela vous donne yourfile.xsd , que dans une deuxième étape, vous pouvez convertir à nouveau en utilisant xsd.exe dans une Classe C#:

xsd yourfile.xsd /c

cela devrait vous donner un fichier yourfile.cs qui contiendra une Classe C# que vous pouvez utiliser pour desérialiser le fichier XML que vous obtenez - quelque chose comme:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
msg resultingMessage = (msg)serializer.Deserialize(new XmlTextReader("yourfile.xml"));

Devrait fonctionner assez bien pour la plupart des cas.

mise à jour: le sérialiseur XML prendra n'importe quel flux comme son entrée - soit un fichier ou un flux de mémoire sera très bien:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
msg resultingMessage = (msg)serializer.Deserialize(memStream);

ou utiliser un lecteur de chaîne de caractères:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
StringReader rdr = new StringReader(inputString);
msg resultingMessage = (msg)serializer.Deserialize(rdr);
224
répondu marc_s 2016-01-24 17:16:58

Vous avez deux possibilités.

Méthode 1. XSD tool


Supposons que vous ayez votre fichier XML à cet endroit C:\path\to\xml\file.xml
  1. Ouvrir Développeur Invite De Commande

    Vous pouvez le trouver dans Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools Ou si vous avez Windows 8 peut juste commencer à taper invite de commande de développeur dans écran de Démarrage
  2. changez l'emplacement de votre répertoire de fichiers XML en tapant cd /D "C:\path\to\xml"
  3. créer fichier XSD à partir de votre fichier xml en tapant xsd file.xml
  4. créer C # classes en tapant xsd /c file.xsd

et c'est tout! Vous avez généré des classes C# à partir du fichier xml dans C:\path\to\xml\file.cs

Méthode 2-Pâte spéciale


Requis Visual Studio 2012+ avec .net Framework > = 4.5 comme cible du projet
  1. copier le contenu de votre fichier XML dans le presse-papiers
  2. ajouter à votre solution un nouveau fichier de classe vide ( Maj + Alt + C )
  3. ouvrir ce fichier et dans le menu cliquer Edit > Paste special > Paste XML As Classes

    enter image description here

et c'est tout!

Utilisation


L'Usage est très simple avec cette classe d'aide:

using System;
using System.IO;
using System.Web.Script.Serialization; // Add reference: System.Web.Extensions
using System.Xml;
using System.Xml.Serialization;

namespace Helpers
{
    internal static class ParseHelpers
    {
        private static JavaScriptSerializer json;
        private static JavaScriptSerializer JSON { get { return json ?? (json = new JavaScriptSerializer()); } }

        public static Stream ToStream(this string @this)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(@this);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }


        public static T ParseXML<T>(this string @this) where T : class
        {
            var reader = XmlReader.Create(@this.Trim().ToStream(), new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
            return new XmlSerializer(typeof(T)).Deserialize(reader) as T;
        }

        public static T ParseJSON<T>(this string @this) where T : class
        {
            return JSON.Deserialize<T>(@this.Trim());
        }
    }
}

Tout ce que vous avez à faire maintenant, c'est:

    public class JSONRoot
    {
        public catalog catalog { get; set; }
    }
    // ...

    string xml = File.ReadAllText(@"D:\file.xml");
    var catalog1 = xml.ParseXML<catalog>();

    string json = File.ReadAllText(@"D:\file.json");
    var catalog2 = json.ParseJSON<JSONRoot>();
172
répondu Damian Drygiel 2014-03-12 17:32:23

essayez cette méthode pour convertir Xml en objet. Il est fait pour exactement ce que vous faites:

protected T FromXml<T>(String xml)
{
    T returnedXmlClass = default(T);

    try
    {
        using (TextReader reader = new StringReader(xml))
        {
            try
            {
                returnedXmlClass = 
                    (T)new XmlSerializer(typeof(T)).Deserialize(reader);
            }
            catch (InvalidOperationException)
            {
                // String passed is not XML, simply return defaultXmlClass
            }
        }
    }
    catch (Exception ex)
    {
    }

    return returnedXmlClass ;        
}

L'appeler en utilisant ce code:

YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);
38
répondu RJ. 2014-05-27 16:20:08

exécutez simplement votre studio visuel 2013 en tant qu'Administration ... Copiez le contenu de votre fichier Xml.. Aller à Visual Studio 2013 > Édition > collage Spécial > Coller Xml en tant que Classes C# Il créera vos classes c# Selon le contenu de votre fichier Xml.

8
répondu user2667652 2014-06-12 12:21:01

Juste au cas où quelqu'un pourrait trouver cela utile:

public static class XmlConvert
{
    public static string SerializeObject<T>(T dataObject)
    {
        if (dataObject == null)
        {
            return string.Empty;
        }
        try
        {
            using (StringWriter stringWriter = new System.IO.StringWriter())
            {
                var serializer = new XmlSerializer(typeof(T));
                serializer.Serialize(stringWriter, dataObject);
                return stringWriter.ToString();
            }
        }
        catch (Exception ex)
        {
            return string.Empty;
        }
    }

    public static T DeserializeObject<T>(string xml)
         where T : new()
    {
        if (string.IsNullOrEmpty(xml))
        {
            return new T();
        }
        try
        {
            using (var stringReader = new StringReader(xml))
            {
                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(stringReader);
            }
        }
        catch (Exception ex)
        {
            return new T();
        }
    }
}

vous pouvez l'appeler en utilisant:

MyCustomObject myObject = new MyCustomObject();
string xmlString = XmlConvert.SerializeObject(myObject)
myObject = XmlConvert.DeserializeObject<MyCustomObject>(xmlString);
5
répondu Razzer 2018-07-20 12:23:28

vous pouvez utiliser xsd.exe pour créer des classes liées à schema dans .Net puis XmlSerializer pour désérialiser la chaîne: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx

2
répondu DaveShaw 2010-07-06 15:14:42

vous pouvez générer la classe comme décrit ci-dessus, ou les écrire manuellement:

[XmlRoot("msg")]
public class Message
{
    [XmlElement("id")]
    public string Id { get; set; }
    [XmlElement("action")]
    public string Action { get; set; }
}

alors vous pouvez utiliser ExtendedXmlSerializer pour sérialiser et deserialiser.

Instalation Vous pouvez installer ExtendedXmlSerializer à partir de nuget ou exécuter la commande suivante:

Install-Package ExtendedXmlSerializer

Sérialisation:

var serializer = new ConfigurationContainer().Create();
var obj = new Message();
var xml = serializer.Serialize(obj);

désérialisation

var obj2 = serializer.Deserialize<Message>(xml);

ce support de sérialiseur:

  • la Désérialisation xml de la norme XMLSerializer
  • Sérialisation de la classe, struct, classe générique, type primitif, liste générique et dictionnaire, tableau, enum
  • Sérialisation de la classe avec la propriété de l'interface
  • Serialization référence circulaire et référence Id
  • Deserialisation de l'ancienne version de xml
  • "1519290920 de la Propriété" cryptage
  • Personnalisé sérialiseur
  • Soutien XmlElementAttribute et attribut xmlrootattribute
  • POCO - toutes les configurations (migrations, sérialiseur personnalisé...) ne relèvent pas de la classe

ExtendedXmlSerializer support .NET 4.5 or higher et .NET Core . Vous pouvez l'intégrer avec WebApi et AspCore.

2
répondu Wojtpl2 2018-07-21 11:16:31

si vous avez le xsd du message xml, vous pouvez générer des classes c# en utilisant le .Net xsd.exe outil.

cette classe .Net peut alors être utilisée pour générer le xml.

0
répondu Amitabh 2010-07-06 15:09:17

en plus des autres réponses ici, vous pouvez naturellement utiliser la classe XmlDocument , pour la lecture de type DOM XML , ou le XmlReader , lecteur forward-only rapide, pour le faire"à la main".

0
répondu Skurmedel 2010-07-06 15:18:37

simplifiant la grande réponse de Damian,

public static T ParseXml<T>(this string value) where T : class
{
    var xmlSerializer = new XmlSerializer(typeof(T));
    using (var textReader = new StringReader(value))
    {
        return (T) xmlSerializer.Deserialize(textReader);
    }
}
0
répondu Sam Jazz 2018-08-08 13:43:53
public string Serialize<T>(T settings)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    StringWriter outStream = new StringWriter();
    serializer.Serialize(outStream, settings);
    return outStream.ToString();
}
-4
répondu Mandoleen 2014-10-27 22:17:43