How to Deserialize XML document
How about you just save the xml to a file, and use xsd to generate C# classes?
- Write the file to disk (I named it foo.xml)
- Generate the xsd:
xsd foo.xml
- 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
- Open Developer Command Prompt
You can find it inStart 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 - Change location to your XML file directory by typing
cd /D "C:\path\to\xml"
- Create XSD file from your xml file by typing
xsd file.xml
- 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+
- Copy content of your XML file to clipboard
- Add to your solution new, empty class file (Shift+Alt+C)
- Open that file and in menu click
Edit > Paste special > Paste XML As Classes
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>();