[c#] Convert XML String to Object

I am receiving XML strings over a socket, and would like to convert these to C# objects.

The messages are of the form:

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

I am new to .Net, and am not sure the best practice for performing this. I've used JAXB for Java before, and wasn't sure if there is something similar, or if this would be handled a different way.

This question is related to c# xml xml-parsing xml-serialization

The answer is


Simply Run Your Visual Studio 2013 as Administration ... Copy the content of your Xml file.. Go to Visual Studio 2013 > Edit > Paste Special > Paste Xml as C# Classes It will create your c# classes according to your Xml file content.


Try this method to Convert Xml to an object. It is made for exactly what you are doing:

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

Call it using this code:

YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);

Just in case anyone might find this useful:

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

You can call it using:

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

I know this question is old, but I stumbled into it and I have a different answer than, well, everyone else :-)

The usual way (as the commenters above mention) is to generate a class and de-serialize your xml.

But (warning: shameless self-promotion here) I just published a nuget package, here, with which you don't have to. You just go:

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

That is literally it, nothing else needed. And, most importantly, if your xml changes, your object changes automagically as well.

If you prefer to download the dll directly, the github page is here.


You can use xsd.exe to create schema bound classes in .Net then XmlSerializer to Deserialize the string : http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx


Another way with an Advanced xsd to c# classes generation Tools : xsd2code.com. This tool is very handy and powerfull. It has a lot more customisation than the xsd.exe tool from Visual Studio. Xsd2Code++ can be customised to use Lists or Arrays and supports large schemas with a lot of Import statements.

Note of some features,

  • Generates business objects from XSD Schema or XML file to flexible C# or Visual Basic code.
  • Support Framework 2.0 to 4.x
  • Support strong typed collection (List, ObservableCollection, MyCustomCollection).
  • Support automatic properties.
  • Generate XML read and write methods (serialization/deserialization).
  • Databinding support (WPF, Xamarin).
  • WCF (DataMember attribute).
  • XML Encoding support (UTF-8/32, ASCII, Unicode, Custom).
  • Camel case / Pascal Case support.
  • restriction support ([StringLengthAttribute=true/false], [RegularExpressionAttribute=true/false], [RangeAttribute=true/false]).
  • Support large and complex XSD file.
  • Support of DotNet Core & standard

I have gone through all the answers as at this date (2020-07-24), and there has to be a simpler more familiar way to solve this problem, which is the following.

Two scenarios... One is if the XML string is well-formed, i.e. it begins with something like <?xml version="1.0" encoding="utf-16"?> or its likes, before encountering the root element, which is <msg> in the question. The other is if it is NOT well-formed, i.e. just the root element (e.g. <msg> in the question) and its child nodes only.

Firstly, just a simple class that contains the properties that match, in case-insensitive names, the child nodes of the root node in the XML. So, from the question, it would be something like...

public class TheModel
{
    public int Id { get; set; }
    public string Action { get; set; }
}

The following is the rest of the code...

// These are the key using statements to add.
using Newtonsoft.Json;
using System.Xml;

bool isWellFormed = false;
string xml =  = @"
<msg>
   <id>1</id>
   <action>stop</action>
</msg>
";

var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
if (isWellFormed)
{
    xmlDocument.RemoveChild(xmlDocument.FirstChild); 
    /* i.e. removing the first node, which is the declaration part. 
    Also, if there are other unwanted parts in the XML, 
    write another similar code to locate the nodes 
    and remove them to only leave the desired root node 
    (and its child nodes).*/
}

var serializedXmlNode = JsonConvert.SerializeXmlNode(
            xmlDocument, 
            Newtonsoft.Json.Formatting.Indented, 
            true
            );
var theDesiredObject = JsonConvert.DeserializeObject<TheModel>(serializedXmlNode);

You have two possibilities.

Method 1. XSD tool


Suppose that you have your XML file in this location C:\path\to\xml\file.xml

  1. Open Developer Command Prompt
    You can find it in Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools Or if you have Windows 8 can just start typing Developer Command Prompt in Start screen
  2. Change location to your XML file directory by typing cd /D "C:\path\to\xml"
  3. Create XSD file from your xml file by typing xsd file.xml
  4. Create C# classes by typing xsd /c file.xsd

And that's it! You have generated C# classes from xml file in C:\path\to\xml\file.cs

Method 2 - Paste special


Required Visual Studio 2012+ with .Net Framework >= 4.5 as project target and 'Windows Communication Foundation' individual component installed

  1. Copy content of your XML file to clipboard
  2. Add to your solution new, empty class file (Shift+Alt+C)
  3. Open that file and in menu click Edit > Paste special > Paste XML As Classes
    enter image description here

And that's it!

Usage


Usage is very simple with this helper class:

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

All you have to do now, 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>();

If you have the xsd of the xml message then you can generate c# classes using the .Net xsd.exe tool.

This .Net classes can then be used to generate the xml.


You can generate class as described above, or write them manually:

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

Then you can use ExtendedXmlSerializer to serialize and deserialize.

Instalation You can install ExtendedXmlSerializer from nuget or run the following command:

Install-Package ExtendedXmlSerializer

Serialization:

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

Deserialization

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

This serializer support:

  • Deserialization xml from standard XMLSerializer
  • Serialization class, struct, generic class, primitive type, generic list and dictionary, array, enum
  • Serialization class with property interface
  • Serialization circular reference and reference Id
  • Deserialization of old version of xml
  • Property encryption
  • Custom serializer
  • Support XmlElementAttribute and XmlRootAttribute
  • POCO - all configurations (migrations, custom serializer...) are outside the class

ExtendedXmlSerializer support .NET 4.5 or higher and .NET Core. You can integrate it with WebApi and AspCore.


In addition to the other answers here you can naturally use the XmlDocument class, for XML DOM-like reading, or the XmlReader, fast forward-only reader, to do it "by hand".


Simplifying Damian's great answer,

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

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

Create a DTO as CustomObject

Use below method to convert XML String to DTO using JAXB

private static CustomObject getCustomObject(final String ruleStr) {
    CustomObject customObject = null;
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(CustomObject.class);
        final StringReader reader = new StringReader(ruleStr);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        customObject = (CustomObject) jaxbUnmarshaller.unmarshal(reader);
    } catch (JAXBException e) {
        LOGGER.info("getCustomObject parse error: ", e);
    }
    return customObject;
}

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to xml

strange error in my Animation Drawable How do I POST XML data to a webservice with Postman? PHP XML Extension: Not installed How to add a Hint in spinner in XML Generating Request/Response XML from a WSDL Manifest Merger failed with multiple errors in Android Studio How to set menu to Toolbar in Android How to add colored border on cardview? Android: ScrollView vs NestedScrollView WARNING: Exception encountered during context initialization - cancelling refresh attempt

Examples related to xml-parsing

How to create XML file with specific structure in Java jQuery xml error ' No 'Access-Control-Allow-Origin' header is present on the requested resource.' SyntaxError of Non-ASCII character xml.LoadData - Data at the root level is invalid. Line 1, position 1 XML Error: Extra content at the end of the document How to use sed to extract substring How to fix Invalid byte 1 of 1-byte UTF-8 sequence The best node module for XML parsing Parsing XML with namespace in Python via 'ElementTree' oracle plsql: how to parse XML and insert into table

Examples related to xml-serialization

Serialize Property as Xml Attribute in Element Reading from memory stream to string There is an error in XML document (1, 41) Xml serialization - Hide null values Using DataContractSerializer to serialize, but can't deserialize back Serialize an object to XML Serializing an object as UTF-8 XML in .NET Convert XML String to Object Serialize an object to string Using StringWriter for XML Serialization