PROWAREtech
.NET: XmlSerializer Example
Serialize and deserialize objects to XML strings using C#.
XML Serialization
Serialization is the process of persisting an object to permanent storage, like disk. It converts an object into an XML string which can then be written to disk, for example. Once serialized, it can be deserialized by another application.
Example Code
using System;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;
namespace XmlSerializationExample
{
[Serializable]
public class VehiclesExample // make sure classes are public
{
// can also use System.Collections.ObjectModel.ObservableCollection
List<Vehicle> vehicles = new List<Vehicle>();
public List<Vehicle> Vehicles
{
get
{
return vehicles;
}
set
{
if (value == vehicles)
return;
vehicles = value;
}
}
public int NumberOfWheels { get; set; }
[XmlAttribute] // serializer will make this an attribute
public string Name { get; set; }
[XmlIgnore] // serializer will ignore this property
public string Dummy { get; set; }
}
public class Vehicle
{
public Vehicle()
{
}
public Vehicle(string Maker, string Model)
{
this.Maker = Maker;
this.Model = Model;
}
public string Maker { get; set; }
public string Model { get; set; }
}
class Program
{
static string Serialize(VehiclesExample obj)
{
XmlSerializer xmlSerial = new XmlSerializer(typeof(VehiclesExample));
using (StringWriter strWriter = new StringWriter())
{
xmlSerial.Serialize(strWriter, obj);
return strWriter.GetStringBuilder().ToString();
}
}
static void Main()
{
VehiclesExample obj = new VehiclesExample();
obj.Name = "NAME HERE";
obj.Dummy = "DUMMY HERE";
obj.NumberOfWheels = 4;
obj.Vehicles.Add(new Vehicle("Honda", "Civic"));
obj.Vehicles.Add(new Vehicle("Honda", "Ridgeline"));
obj.Vehicles.Add(new Vehicle("Honda", "Accord"));
obj.Vehicles.Add(new Vehicle("Subaru", "WRX"));
obj.Vehicles.Add(new Vehicle("Honda", "Element"));
obj.Vehicles.Add(new Vehicle("Honda", "Pilot"));
obj.Vehicles.Add(new Vehicle("Porsche", "911"));
obj.Vehicles.Add(new Vehicle("Acura", "MDX"));
obj.Vehicles.Add(new Vehicle("Honda", "CR-V"));
string xml = Serialize(obj);
Console.Write(xml);
FileStream stream = new FileStream("vehices.xml", FileMode.Create);
StreamWriter writer = new StreamWriter(stream); // this could be any type of stream
writer.Write(xml);
writer.Close();
stream.Close();
}
}
}
The XML source produced by the serialization:
<?xml version="1.0" encoding="utf-16"?>
<VehiclesExample xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Name="NAME HERE">
<Vehicles>
<Vehicle>
<Maker>Honda</Maker>
<Model>Civic</Model>
</Vehicle>
<Vehicle>
<Maker>Honda</Maker>
<Model>Ridgeline</Model>
</Vehicle>
<Vehicle>
<Maker>Honda</Maker>
<Model>Accord</Model>
</Vehicle>
<Vehicle>
<Maker>Subaru</Maker>
<Model>WRX</Model>
</Vehicle>
<Vehicle>
<Maker>Honda</Maker>
<Model>Element</Model>
</Vehicle>
<Vehicle>
<Maker>Honda</Maker>
<Model>Pilot</Model>
</Vehicle>
<Vehicle>
<Maker>Porsche</Maker>
<Model>911</Model>
</Vehicle>
<Vehicle>
<Maker>Acura</Maker>
<Model>MDX</Model>
</Vehicle>
<Vehicle>
<Maker>Honda</Maker>
<Model>CR-V</Model>
</Vehicle>
</Vehicles>
<NumberOfWheels>4</NumberOfWheels>
</VehiclesExample>
XML Deserialization
Deserialization is the reverse process of serialization. XML deserialization is the process of turning an XML file or string into an object.
Example Code
using System;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;
namespace XmlSerializationExample
{
[Serializable]
public class VehiclesExample
{
// can also be System.Collections.ObjectModel.ObservableCollection
List<Vehicle> vehicles = new List<Vehicle>();
public List<Vehicle> Vehicles
{
get
{
return vehicles;
}
set
{
if (value == vehicles)
return;
vehicles = value;
}
}
public int NumberOfWheels { get; set; }
[XmlAttribute] // serializer will make this an attribute
public string Name { get; set; }
[XmlIgnore] // serializer will ignore this property
public string Dummy { get; set; }
}
public class Vehicle
{
public Vehicle()
{
}
public Vehicle(string Maker, string Model)
{
this.Maker = Maker;
this.Model = Model;
}
public string Maker { get; set; }
public string Model { get; set; }
}
class Program
{
public static VehiclesExample Deserialize(string xmlString)
{
XmlSerializer xmlSerial = new XmlSerializer(typeof(VehiclesExample));
using (StringReader strReader = new StringReader(xmlString))
{
return (VehiclesExample)xmlSerial.Deserialize(strReader);
}
}
public static VehiclesExample Deserialize(StreamReader xmlStream)
{
XmlSerializer xmlSerial = new XmlSerializer(typeof(VehiclesExample));
return (VehiclesExample)xmlSerial.Deserialize(xmlStream);
}
static void Main()
{
FileStream stream = new FileStream("vehices.xml", FileMode.Open);
StreamReader reader = new StreamReader(stream); // this could be any type of stream
VehiclesExample obj;
if (true != false) // deserialize directly from the stream, this is more efficient
{
obj = Deserialize(reader);
}
else // or if needing to deserialize a string
{
string xml = reader.ReadToEnd();
obj = Deserialize(xml);
}
reader.Close();
stream.Close();
Console.WriteLine(obj.Name);
Console.WriteLine(obj.NumberOfWheels);
foreach(Vehicle v in obj.Vehicles)
{
Console.WriteLine(v.Maker + " " + v.Model);
}
}
}
}
Program output:
NAME HERE 4 Honda Civic Honda Ridgeline Honda Accord Subaru WRX Honda Element Honda Pilot Porsche 911 Acura MDX Honda CR-V
A More Complex Example
<?xml version="1.0" encoding="UTF-8"?>
<shoppingTheWeb xmlns="http://www.searchwebsiteshoppingexample.com/api/search/v1">
<version>1.0</version>
<timestamp>2017-01-01T12:00:00.000Z</timestamp>
<searchItems count="3">
<item>
<itemId>8765678987654323443234567878987</itemId>
<title>item #1 title</title>
<category>
<catId>1011</catId>
<catName>Stuff</catName>
</category>
<status>
<available>true</available>
<price priceId="USD">123.45</price>
<quantity>2343</quantity>
</status>
</item>
<item>
<itemId>1234567899874532345678987987351</itemId>
<title>item #2 title</title>
<category>
<catId>1022</catId>
<catName>Junk</catName>
</category>
<status>
<available>true</available>
<price priceId="USD">45.67</price> <!-- must access the attribute and element -->
<quantity>45</quantity>
</status>
</item>
<item>
<itemId>9856928734621987689731628934465</itemId>
<title>item #3 title</title>
</item>
</searchItems>
</shoppingTheWeb>
Now, deserialize the above XML file named "example.xml" and save the results to a flat text file named "data.txt"
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApp1
{
[XmlRoot("shoppingTheWeb", Namespace = "http://www.searchwebsiteshoppingexample.com/api/search/v1")]
public class ShoppingResults
{
public double version { get; set; }
public DateTime timestamp { get; set; }
public SearchItems searchItems { get; set; }
public static ShoppingResults Deserialize(string xml)
{
XmlSerializer xmlSerial = new XmlSerializer(typeof(ShoppingResults));
using (StringReader strReader = new StringReader(xml))
{
return (ShoppingResults)xmlSerial.Deserialize(strReader);
}
}
public static ShoppingResults Deserialize(StreamReader xmlStream)
{
XmlSerializer xmlSerial = new XmlSerializer(typeof(ShoppingResults));
return (ShoppingResults)xmlSerial.Deserialize(xmlStream);
}
}
public class SearchItems
{
[XmlAttribute("count")]
public int count { get; set; }
[XmlElement("item")] // this tells the deserializer that the item tag is used
public List<Item> items { get; set; }
}
public class Item
{
public string itemId { get; set; }
public string title { get; set; }
public Category category { get; set; }
public Status status { get; set; }
}
public class Category
{
public int catId { get; set; }
public string catName { get; set; }
}
public class Status
{
public bool available { get; set; }
public Price price { get; set; }
public int quantity { get; set; }
}
public class Price
{
[XmlAttribute]
public string priceId { get; set; }
[XmlText] // this is new to this tutorial and it allows for access to the price's inner text/value
public double InnerText { get; set; }
}
class Program
{
static void Main(string[] args)
{
using (TextWriter txt = new StreamWriter("data.txt", false))
{
ShoppingResults shopping;
using (StreamReader reader = new StreamReader("example.xml"))
{
shopping = ShoppingResults.Deserialize(reader);
}
txt.WriteLine(shopping.timestamp + "\r\nITEMID\tTITLE\tCATID\tCATNAME\tAVAILABLE\tPRICE\tPRICEID\tQUANTITY\r\n");
foreach(Item item in shopping.searchItems.items)
txt.WriteLine(item.itemId + '\t' + item.title + '\t' + item.category?.catId + '\t' + item.category?.catName + '\t' + item.status?.available + '\t' + item.status?.price?.InnerText + '\t' + item.status?.price?.priceId + '\t' + item.status?.quantity + "\r\n");
}
}
}
}
The tab seperated output from the following code will look like this:
1/1/2017 12:00:00 PM ITEMID TITLE CATID CATNAME AVAILABLE PRICE PRICEID QUANTITY 8765678987654323443234567878987 item #1 title 1011 Stuff True 123.45 USD 2343 1234567899874532345678987987351 item #2 title 1022 Junk True 45.67 USD 45 9856928734621987689731628934465 item #3 title
Comment