web-dev-qa-db-fra.com

Convertir une chaîne XML en objet

Je reçois des chaînes XML sur un socket et souhaite les convertir en objets C #.

Les messages sont de la forme:

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

Je suis nouveau sur .Net et je ne suis pas sûr de la meilleure pratique pour le faire. J'ai déjà utilisé JAXB pour Java auparavant, et je ne savais pas s'il y avait quelque chose de similaire ou si cela serait traité différemment.

139
Steve

Vous devez utiliser l'outil xsd.exe qui est installé avec le SDK Windows dans un répertoire similaire à celui-ci: 

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

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

xsd yourfile.xml

Cela vous donne yourfile.xsd, que vous pouvez à nouveau convertir à l'aide de 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 désé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 dans la plupart des cas.

Mise à jour: le sérialiseur XML prendra n'importe quel flux en tant qu'entrée - un fichier ou un flux de mémoire suffira:

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

ou utilisez un StringReader:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
StringReader rdr = new StringReader(inputString);
msg resultingMessage = (msg)serializer.Deserialize(rdr);
238
marc_s

Essayez cette méthode pour convertir XML en un 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 ;        
}

Appelez-le en utilisant ce code:

YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);
41
RJ.

Exécutez simplement votre Visual Studio 2013 en tant qu'administrateur .... Copiez le contenu de votre fichier XML ...__ Accédez à Visual Studio 2013> Édition> Collage spécial> Coller XML en tant que classes C # Il créera votre c # classes en fonction du contenu de votre fichier XML. 

8
user2667652

Juste au cas où quelqu'un trouverait 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
Razzer

Vous pouvez générer une classe comme décrit ci-dessus ou l'écrire manuellement:

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

Ensuite, vous pouvez utiliser ExtendedXmlSerializer pour sérialiser et désérialiser.

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:

  • Désérialisation XML à partir de XMLSerializer standard
  • Classe de sérialisation, struct, classe générique, type primitif, liste générique et dictionnaire, tableau, enum
  • Classe de sérialisation avec interface de propriété
  • Référence circulaire et identifiant de référence
  • Désérialisation de l'ancienne version de XML
  • Cryptage de propriété
  • Sérialiseur personnalisé
  • Prise en charge de XmlElementAttribute et XmlRootAttribute
  • POCO - toutes les configurations (migrations, sérialiseur personnalisé ...) sont en dehors de la classe

ExtendedXmlSerializer prend en charge .NET 4.5 ou supérieur et .NET Core. Vous pouvez l'intégrer à WebApi et AspCore. 

2
Wojtpl2

Vous pouvez utiliser xsd.exe pour créer des classes liées au schéma 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
DaveShaw

Si vous avez le xsd du message xml, vous pouvez générer des classes c # à l'aide de l'outil .Net xsd.exe.

Ces classes .Net peuvent ensuite être utilisées pour générer le XML.

0
Amitabh

Je sais que cette question est ancienne, mais je suis tombé dessus et j'ai une réponse différente de celle de tout le monde :-)

La manière habituelle (comme le mentionnent les commentateurs ci-dessus) est de générer une classe et de désérialiser votre fichier XML.

Mais ( avertissement: auto-promotion sans vergogne ici ) Je viens de publier un paquet de pépites, ici , avec lequel vous ne le faites pas devoir. Vous venez juste d'aller:

string xml = System.IO.File.ReadAllText(@"C:\test\books.xml");
var book = Dandraka.XmlUtilities.XmlSlurper.ParseText(xml);

C'est littéralement ça, rien d'autre n'est nécessaire. Et surtout, si votre xml change, votre objet change aussi automatiquement.

Si vous préférez télécharger la dll directement, la page github est ici .

0
Jim Andrakakis

En plus des autres réponses ici, vous pouvez naturellement utiliser le XmlDocument class, pour une lecture semblable à celle du DOM XML, ou le XmlReader , lecteur rapide uniquement, pour le faire "à la main".

0
Skurmedel

Simplifier l'excellente 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
Sam Jazz

Une autre façon avec une génération avancée de classes xsd to c # Tools: xsd2code.com. Cet outil est très pratique et puissant. Il a beaucoup plus de personnalisation que l'outil xsd.exe de Visual Studio. Xsd2Code ++ peut être personnalisé pour utiliser des listes ou des tableaux et prend en charge les grands schémas avec de nombreuses instructions d'importation.

Note de certaines fonctionnalités,

  • Génère des objets métier à partir de schéma XSD ou de fichier XML en code flexible C # Ou Visual Basic.
  • Support Framework 2.0 à 4.x
  • Soutenir la collection typée forte (List, ObservableCollection, MyCustomCollection).
  • Soutenir les propriétés automatiques.
  • Générer des méthodes de lecture et d'écriture XML (sérialisation/désérialisation).
  • Prise en charge de la liaison de données (WPF, Xamarin).
  • WCF (attribut DataMember).
  • Prise en charge du codage XML (UTF-8/32, ASCII, Unicode, Custom).
  • Affaire Camel/Prise en charge de Pascal.
  • support de restriction ([StringLengthAttribute = true/false], [RegularExpressionAttribute = true/false], [RangeAttribute = true/false]).
  • Supporte les fichiers XSD volumineux et complexes.
  • Prise en charge de DotNet Core et standard
0
Haas Franck