Converteer XML-tekenreeks naar object

Ik ontvang XML-strings via een socket en wil deze graag converteren naar C#-objecten.

De berichten hebben de volgende vorm:

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

Ik ben nieuw bij .Net en weet niet wat de beste manier is om dit uit te voeren. Ik heb eerder JAXB voor Java gebruikt en wist niet zeker of er iets soortgelijks is, of dat dit op een andere manier zou worden afgehandeld.


Antwoord 1, autoriteit 100%

U moet de tool xsd.exegebruiken die samen met de Windows SDK wordt geïnstalleerd in een map die lijkt op:

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

En op 64-bits computers:

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

En op Windows 10-computers:

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

Bij de eerste run gebruikt u xsd.exeen converteert u uw voorbeeld-XML naar een XSD-bestand (XML-schemabestand):

xsd yourfile.xml

Dit geeft u yourfile.xsd, dat u in een tweede stap opnieuw kunt converteren met xsd.exenaar een C#-klasse:

xsd yourfile.xsd /c

Dit zou je een bestand yourfile.csmoeten geven dat een C#-klasse zal bevatten die je kunt gebruiken om het XML-bestand dat je krijgt te deserialiseren – zoiets als:

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

Zou in de meeste gevallen redelijk goed moeten werken.

Update:de XML-serializer neemt elke stream als invoer – een bestand of een geheugenstream is prima:

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

of gebruik een StringReader:

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

Antwoord 2, autoriteit 84%

Je hebt twee mogelijkheden.

Methode 1. XSD-tool


Stel dat u uw XML-bestand op deze locatie heeft C:\path\to\xml\file.xml

  1. Open Opdrachtprompt voor ontwikkelaars
    Je vindt het in Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools
    Of als je Windows 8 hebt, kun je gewoon beginnen met het typen van Opdrachtprompt voor ontwikkelaarsin Startscherm
  2. Wijzig de locatie in uw XML-bestandsdirectory door cd /D "C:\path\to\xml"
  3. te typen

  4. Maak XSD-bestandvan uw xml-bestand door xsd file.xml
  5. te typen

  6. Maak C#-klassendoor xsd /c file.xsd
  7. te typen

En dat is het! U hebt C#-klassen gegenereerd uit het xml-bestand in C:\path\to\xml\file.cs

Methode 2 – Plakken speciaal


Vereist Visual Studio 2012+ met .Net Framework >= 4.5 als projectdoel en afzonderlijk onderdeel ‘Windows Communication Foundation’ geïnstalleerd

  1. Kopieer de inhoud van uw XML-bestand naar het klembord
  2. Voeg een nieuw, leeg klassenbestand toe aan uw oplossing (Shift+Alt+C)
  3. Open dat bestand en klik in het menu op Edit > Paste special > Paste XML As Classes
    voer hier de afbeeldingsbeschrijving in

En dat is het!

Gebruik


Het gebruik is heel eenvoudig met deze hulpklasse:

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

Het enige dat u nu hoeft te doen, is:

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

Antwoord 3, autoriteit 18%

Probeer deze methode om XML naar een object te converteren. Het is gemaakt voor precies wat je doet:

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

Noem het met deze code:

YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);

Antwoord 4, autoriteit 4%

Voer uw Visual Studio 2013 gewoon uit als beheer …
Kopieer de inhoud van uw XML-bestand..
Ga naar Visual Studio 2013 > Bewerken > Plakken speciaal > Xml plakken als C#-klassen
Het zal uw c#-klassen maken volgens de inhoud van uw XML-bestand.


Antwoord 5, autoriteit 3%

Voor het geval iemand dit nuttig zou kunnen vinden:

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

Je kunt het oproepen met:

MyCustomObject myObject = new MyCustomObject();
string xmlString = XmlConvert.SerializeObject(myObject)
myObject = XmlConvert.DeserializeObject<MyCustomObject>(xmlString);

Antwoord 6, autoriteit 3%

U kunt klasse genereren zoals hierboven beschreven, of ze handmatig schrijven:

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

Vervolgens kun je ExtendedXmlSerializergebruiken om te serialiseren en deserialiseren.

Installatie
U kunt ExtendedXmlSerializer installeren vanaf nugetof de volgende opdracht uitvoeren:

Install-Package ExtendedXmlSerializer

Serialisatie:

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

Deserialisatie

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

Deze serializer-ondersteuning:

  • Deserialisatie xml van standaard XMLSerializer
  • Serialisatieklasse, struct, generieke klasse, primitief type, generieke lijst en woordenboek, array, enum
  • Serialisatieklasse met eigenschappeninterface
  • Serialisatie circulaire referentie en referentie-ID
  • Deserialisatie van oude versie van xml
  • Eigenschapsversleuteling
  • Aangepaste serializer
  • Ondersteuning van XmlElementAttribute en XmlRootAttribute
  • POCO – alle configuraties (migraties, aangepaste serializer…) vallen buiten de klasse

ExtendedXmlSerializer ondersteunt .NET 4.5of hoger en .NET Core. U kunt het integreren met WebApi en AspCore.


Antwoord 7

U kunt xsd.exe gebruiken om schemagebonden klassen te maken in .Net en vervolgens XmlSerializer om de tekenreeks te deserialiseren: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx


Antwoord 8

Het geweldige antwoord van Damian vereenvoudigen,

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

9

Als u de XSD van het XML-bericht hebt, kunt u C # -klassen genereren met behulp van de .NET XSD.EXE-tool.

Deze .NET-klassen kunnen vervolgens worden gebruikt om de XML te genereren.


10

In aanvulling op de andere antwoorden hier kunt u natuurlijk de XMLDocument klasse, voor XML Dom-like lezen, of de XMLReader , snelle voorwaartse lezer, om het te doen” met de hand “.


Antwoord 11

public string Serialize<T>(T settings)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    StringWriter outStream = new StringWriter();
    serializer.Serialize(outStream, settings);
    return outStream.ToString();
}

Other episodes