How to Deserialize XML document How to Deserialize XML document xml xml

How to Deserialize XML document


How about you just save the xml to a file, and use xsd to generate C# classes?

  1. Write the file to disk (I named it foo.xml)
  2. Generate the xsd: xsd foo.xml
  3. Generate the C#: xsd foo.xsd /classes

Et voila - and C# code file that should be able to read the data via XmlSerializer:

    XmlSerializer ser = new XmlSerializer(typeof(Cars));    Cars cars;    using (XmlReader reader = XmlReader.Create(path))    {        cars = (Cars) ser.Deserialize(reader);    }

(include the generated foo.cs in the project)


Here's a working version. I changed the XmlElementAttribute labels to XmlElement because in the xml the StockNumber, Make and Model values are elements, not attributes. Also I removed the reader.ReadToEnd(); (that function reads the whole stream and returns a string, so the Deserialize() function couldn't use the reader anymore...the position was at the end of the stream). I also took a few liberties with the naming :).

Here are the classes:

[Serializable()]public class Car{    [System.Xml.Serialization.XmlElement("StockNumber")]    public string StockNumber { get; set; }    [System.Xml.Serialization.XmlElement("Make")]    public string Make { get; set; }    [System.Xml.Serialization.XmlElement("Model")]    public string Model { get; set; }}[Serializable()][System.Xml.Serialization.XmlRoot("CarCollection")]public class CarCollection{    [XmlArray("Cars")]    [XmlArrayItem("Car", typeof(Car))]    public Car[] Car { get; set; }}

The Deserialize function:

CarCollection cars = null;string path = "cars.xml";XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));StreamReader reader = new StreamReader(path);cars = (CarCollection)serializer.Deserialize(reader);reader.Close();

And the slightly tweaked xml (I needed to add a new element to wrap <Cars>...Net is picky about deserializing arrays):

<?xml version="1.0" encoding="utf-8"?><CarCollection><Cars>  <Car>    <StockNumber>1020</StockNumber>    <Make>Nissan</Make>    <Model>Sentra</Model>  </Car>  <Car>    <StockNumber>1010</StockNumber>    <Make>Toyota</Make>    <Model>Corolla</Model>  </Car>  <Car>    <StockNumber>1111</StockNumber>    <Make>Honda</Make>    <Model>Accord</Model>  </Car></Cars></CarCollection>


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+

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