Click here to Skip to main content
15,881,938 members
Articles / Programming Languages / XML
Tip/Trick

Serialize/Deserialize any object to an XML file

Rate me:
Please Sign up or sign in to vote.
4.88/5 (11 votes)
28 May 2013CPOL1 min read 76K   3.2K   38   13
Code to serialize/deserialize any object to an XML file.
Added support for 'DontSerialize' attribute 

Introduction  

Most of us know the C# .NET Xml Serializer, and it has the ability to serialize objects to XML files, but there are a lot of limitations in it such as,

  1. It supports only objects that marked as Serializable.
  2. When two or more properties share the same reference then it serializes each property to a separated node. That causes an error when trying to deserialize the object because each property will have a different reference. 
  3. Assume the object contains a property that references to it, such as:
    • ArrayList list=new ArrayList();
    • list.Add(list);

    In this case, the C# .NET serializer will fail.

  4. Assume the object is an array and it has more than 1000 items, these items share the same values, then the C# .NET serializer will repeat the shared values for each item. 
  5. C# .NET serializer is very slow compared with my serializer.

So, the new serializer class will pass all the above limitations.

Using the Code

The main class for this project is XmlObjectSerializer.cs. Here is the Serialize function:

C#
public XmlDocument Serialize(object obj)
{
    xmlDoc = new XmlDocument();
    xmlDoc.AppendChild(xmlDoc.CreateElement("XmlObjectSerializer"));
    xmlDoc.DocumentElement.Attributes.Append(
       xmlDoc.CreateAttribute("ObjectType")).Value = 
       Utility.GetTypeFullName(obj.GetType());
    SerializeProperty(obj, xmlDoc.DocumentElement);
    return xmlDoc;
}

Here is the Deserialize function:

C#
public object Deserialize(string xmlText)
{
    xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xmlText);
    Type objectType = 
      Type.GetType(xmlDoc.DocumentElement.Attributes["ObjectType"].Value);
    var childs = GetChild(xmlDoc.DocumentElement);
    if (childs[0].Name == "Array")//Array found
        return DeserializeIEnumerable(childs[0], objectType);
    else
    {
        object obj = Utility.CreateInstance(objectType);
        DeserializeProperty(xmlDoc.DocumentElement, obj);
        return obj;
    }
}

As you can see, the code is very simple and easy to use, all you have to do is call these above functions.

Here is a sample test class, 

C#
public class Human
{
    public List<Human> Sons { get; set; }
    public Human Parent { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }
    public int Id { get; set; }
    public Human()
    {
        this.Sons = new List<Human>();
    }
}

static void Main()
{
    Human father = new Human() 
    { FirstName = "Kamal", LastName = "Qassas",BirthDate=new DateTime(1967,4,1) };
    father.Sons.Add(new Human() 
    { FirstName = "Ashraf", LastName = "Qassas",
                  BirthDate = new DateTime(1984, 5, 2), Parent = father });
    father.Sons.Add(new Human() 
    { FirstName = "Ayman", LastName = "Qassas", 
                  BirthDate = new DateTime(1985, 6, 3), Parent = father });
    string xml = new XmlObjectSerializer().Serialize(father).OuterXml;
    Human father1 = (Human)new XmlObjectSerializer().Deserialize(xml);
}

Finally, here is the generated XML for the above example:

XML
<XmlObjectSerializer ObjectType="XmlSerializer.Human">
  <Property PropertyName="Sons">
    <Array>
      <ItemDefaults>
        <Property PropertyName="Parent" ReferenceNode="/XmlObjectSerializer[1]" />
        <Property PropertyName="LastName">Qassas</Property>
      </ItemDefaults>
      <Item>
        <Property PropertyName="FirstName">Ashraf</Property>
        <Property PropertyName="BirthDate">5/2/1984</Property>
      </Item>
      <Item>
        <Property PropertyName="FirstName">Ayman</Property>
        <Property PropertyName="BirthDate">6/3/1985</Property>
      </Item>
    </Array>
  </Property>
  <Property PropertyName="FirstName">Kamal</Property>
  <Property PropertyName="LastName">Qassas</Property>
  <Property PropertyName="BirthDate">4/1/1967</Property>
</XmlObjectSerializer>

Points of Interest 

XML is used these days in most programming languages, so you can use the new serializer to interact with different programming languages.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Desktop Team
Palestinian Territory (Occupied) Palestinian Territory (Occupied)
I have advanced skills in desktop apps development, i have built many apps for many corporations.

i'm using the follow languages in my work:
1- C# Language.
2- VB6 Language.
3- Asp.net using C#.
4- Crystal Reports.

i have more than 7 experience years in coding and programming.

Systems and apps Developed by Us:
1-E-Archive System (VB6,Supports multi DataBase Engins).
2-SMS System (Multi languages such VB6,C#,Asp.Net and Gizmox).
3-Multi Camera Monitor System-Motion Detection and record(C#).
4-Administrative Evaluation System (Asp.net).
5-E-Clinic System (C#-using my business layer generator,Supports multi DataBase Engines).
6-Data Access Layer Generator Framework(C#).
7-Sip Provider -VOIP- Softphone (C#- for Italian company).
8-Training course Manager System(C#-for UCAS).
9-Computer Exam System (VB6,Oracle DataBase).
10-Dialer System (VB6).
11-Implement Google API using C# (Translation and web Search).
12-Print Management Enterprise(C#)
13-Elections System (C#- using my business layer generator).
14-Advanced English competition (VB6).
15-Remote USB Sharing (C/C++,VB6).
16-Watch Attendance (C/C++,VB6).
17-Tube Spy (C#).
18-AdminYourTube (C#)
19- Transport Reservation System (C#,Asp.net,Ajax,Jquery)

Please visit my elance URL http://ashrafnet.elance.com

Comments and Discussions

 
QuestionComplex objects Pin
Johnny J.16-Feb-17 3:12
professionalJohnny J.16-Feb-17 3:12 
QuestionLists with elements of simple type are not serialized Pin
Member 918176712-May-15 3:21
Member 918176712-May-15 3:21 
QuestionSome small changes Pin
Bewilderbeeste16-Nov-14 14:39
Bewilderbeeste16-Nov-14 14:39 
A most useful utility class, thanks very much!

It seems wasteful to have to load the xml text to deserialize an object. In most cases, you would load the xml into an XmlDocument. So consider adding Deserialize(XmlDocument):
public object Deserialize(XmlDocument doc, bool ThrowOnError = false)
{
var objectType = Utility.GetType(doc.DocumentElement.Attributes["ObjectType"].Value);
var childs = GetChild(doc.DocumentElement);
if (Utility.IsSimpleType(objectType))
{
return doc.DocumentElement.InnerText.ConvertTo(objectType);
}
else
{
if (childs.Count > 0 && childs[0].Name == "Array")
{
return DeserializeIEnumerable(childs[0], objectType, null, ThrowOnError);
}
else
{
var obj = Utility.CreateInstance(objectType);
DeserializeNode(doc.DocumentElement, obj, ThrowOnError);
return obj;
}
}
}

/// <summary>
/// Deserialize this txt to object
/// </summary>
/// <param name="xmlText"></param>
/// <returns></returns>
public object Deserialize(string xmlText, bool ThrowOnError = false)
{
xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlText);
return Deserialize(xmlDoc, ThrowOnError);

}

Also, the 'Simple Types' don't recognize GUIDs, so change Utility.IsSimpleType

public static bool IsSimpleType(Type propertyType)
{
if (propertyType.Name == "Guid") return true;
...
}
Questionbyte[] doesn't work Pin
GMG Underground9-Sep-14 22:16
GMG Underground9-Sep-14 22:16 
AnswerRe: byte[] doesn't work Pin
akramKamal9-Sep-14 22:24
akramKamal9-Sep-14 22:24 
QuestionDoes it support DataTable and DataSet ? Pin
Member 43373767-Feb-14 13:38
Member 43373767-Feb-14 13:38 
GeneralMy vote of 5 Pin
GiangySan6-Jun-13 2:10
GiangySan6-Jun-13 2:10 
GeneralMy vote of 5 Pin
Prasad Khandekar28-May-13 23:08
professionalPrasad Khandekar28-May-13 23:08 
QuestionMaybe could be helpfull Pin
Mancio197627-May-13 8:12
Mancio197627-May-13 8:12 
AnswerRe: Maybe could be helpfull Pin
akramKamal28-May-13 10:05
akramKamal28-May-13 10:05 
GeneralMy vote of 5 Pin
ashrafnet4u10-Sep-12 20:28
ashrafnet4u10-Sep-12 20:28 
GeneralThoughts Pin
PIEBALDconsult10-Sep-12 5:59
mvePIEBALDconsult10-Sep-12 5:59 
GeneralRe: Thoughts Pin
akramKamal10-Sep-12 6:51
akramKamal10-Sep-12 6:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.