This is a very useful approach when you don't want to create the XML files using XmlWriter
Have you ever wondered how to write an XML file easily? And what about reading the XML file and mapping into an object? There are cases we need to generate XML in order to send information here and there. Or even to use as a kind of database. And the most used approach (by my friends, at least) is to create the XML manually, defining every single node. Pro: More control of the output. Con: Time consuming.
And that brings us to the situation we had in the office.
We have access to a SQL database. But due the amount of security layers we end up taking a huge amount of time to develop against the database. Besides, we wanted to make something flexible and easy to be edited by anyone with more than 2 brain cells. That's why we decided that it would be much more flexible if we would use XML files for the data.
All we need is a well structured class, which could be a Model for those using MVC:
public class DummyClass { public string Id { get; set; } public string Name { get; set; } }
And the following code:
public class XmlSerializerHelper<T> where T : class { public static string Serialize(T obj) { var stringBuilder = new StringBuilder(); try { var xmlWriterSettings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }; var ns = new XmlSerializerNamespaces(); ns.Add("", ""); var xs = new XmlSerializer(typeof(T), ""); using (var writer = XmlWriter.Create(stringBuilder, xmlWriterSettings)) { xs.Serialize(writer, obj, ns); } } catch { throw; } return stringBuilder.ToString(); } public static T Deserialize(string xmlString) { var reader = new StringReader(xmlString); var serializer = new XmlSerializer(typeof(T)); var instance = (T)serializer.Deserialize(reader); return instance; } }
If you want to serialize a class to XML:
xDoc.Add(XElement.Parse(XmlSerializerHelper<DummyClass>.Serialize(dummy)));
And if you want to deserialize:
var dummyObj = XmlSerializerHelper<DummyClass>.Deserialize(xDoc.ToString());
Please note a couple of things:
- This code will generate a very simple XML file, without namespaces or declarations;
- The "type of T" is there to give you flexibility when using the serialization/deserialization methods;
- The way the XML will be generated depends entirely on the way the class is created.
I know this code is not perfect (no try/catch on Deserialize, etc) it should give you a good head start. ;-)
If you start to implement this code you might have noticed one thing: Everything what is in the class will be serialized into the XML with the names you defined there. We can solve this and I will show you how.
Renaming the XML elements
It might happen that you have a class with a name which wouldn't make sense after generating a XML file. In that case it would be much better if we would have the XML elements in a way that anyone can understand. After all, it's much better to read <Person> than <PrsnClass>, right?
One easy way to do it is using Annotations over the name of the class and its properties. Here some that might be very useful:
XmlRoot
[XmlRoot("Person")]
XmlRoot will work in 2 ways: First by defining the root of your XML file; Second by defining its name. Recommended to be used to rename the class itself.
XmlAttribute
[XmlAttribute("Id")]
By default every property is serialized as XML element. By XmlAttribute you will tell the serializer that your property should be used as an attribute in the root element.
XmlElement
[XmlElement("Name")]
Use XmlElement in case you have a property you wish to rename. Very useful in the case you have a property called PersonName and you want to serialize it as Name.
XmlIgnore
[XmlIgnore]
You can use XmlIgnore when you don't want a property to be serialized.
XmlArrayItem
[XmlArrayItem("Children")]
XmlArrayItem is used to create sub elements. You can also use it to rename your properties which contains List<T>, for example.
Of course there are more. But create a kind of ultimate xml serialization guide was never my idea. Maybe one day I will write a book about it. But while it doesn't happen I hope this article will be able to help some people around the interwebs.