C# Tutorial - XML Serialization

Skill

C# Tutorial - XML Serialization

Posted in:

A long while ago we posted a tutorial on how to serialize objects to a binary file. While this is very useful, unfortunately the resulting file is not very human readable. In this tutorial, I'm going to demonstrate how to serialize your own objects to and from an XML file.

Since .NET can use reflection to get property names, basic serialization is unbelievably simple. It only gets slightly difficult when you want to name your XML tags differently than your property names (but still not very hard). If you've ever used an XML serialization package in C++ like boost, tinyXML, or libXML2, you'll see how comparatively easy C# is to use.

Let's start with a basic example. Below is an object that stores some information about a movie.

public class Movie
{
  public string Title
  { get; set; }

  public int Rating
  { get; set; }

  public DateTime ReleaseDate
  { get; set; }
}

All right, now that we have an object, let's write a function that will save it to XML.

static public void SerializeToXML(Movie movie)
{
  XmlSerializer serializer = new XmlSerializer(typeof(Movie));
  TextWriter textWriter = new StreamWriter(@"C:\movie.xml");
  serializer.Serialize(textWriter, movie);
  textWriter.Close();
}

The first thing I do is create an XMLSerializer (located in the System.Xml.Serialization namespace) that will serialize objects of type Movie. The XMLSerializer will serialize objects to a stream, so we'll have to create one of those next. In this case, I want to serialize it to a file, so I create a TextWriter. I then simply call Serialize on the XMLSerializer passing in the stream (textWriter) and the object (movie). Lastly I close the TextWriter because you should always close opened files. That's it! Let's create a movie object and see how this is used.

static void Main(string[] args)
{
  Movie movie = new Movie();
  movie.Title = "Starship Troopers";
  movie.ReleaseDate = DateTime.Parse("11/7/1997");
  movie.Rating = 6.9f;

  SerializeToXML(movie);
}

static public void SerializeToXML(Movie movie)
{
  XmlSerializer serializer = new XmlSerializer(typeof(Movie));
  TextWriter textWriter = new StreamWriter(@"C:\movie.xml");
  serializer.Serialize(textWriter, movie);
  textWriter.Close();
}

After this code executes, we'll have an XML file with the contents of our movie object.

<?xml version="1.0" encoding="utf-8"?>
<Movie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Title>Starship Troopers</Title>
  <Rating>6.9</Rating>
  <ReleaseDate>1997-11-07T00:00:00</ReleaseDate>
</Movie>

If you noticed, all of the XML tag names are the same as the property names. If we want to change those, we can simply add an attribute above each property that sets the tag name.

public class Movie
{
  [XmlElement("MovieName")]
  public string Title
  { get; set; }

  [XmlElement("MovieRating")]
  public float Rating
  { get; set; }

  [XmlElement("MovieReleaseDate")]
  public DateTime ReleaseDate
  { get; set; }
}

Now when the same code is executed again, we get our custom tag names.

<?xml version="1.0" encoding="utf-8"?>
<Movie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <MovieName>Starship Troopers</MovieName>
  <MovieRating>6.9</MovieRating>
  <MovieReleaseDate>1997-11-07T00:00:00</MovieReleaseDate>
</Movie>

Sometimes, in XML, you want information stored as an attribute of another tag instead of a tag by itself. This can be easily accomplished with another property attribute.

public class Movie
{
  [XmlAttribute("MovieName")]
  public string Title
  { get; set; }

  [XmlElement("MovieRating")]
  public float Rating
  { get; set; }

  [XmlElement("MovieReleaseDate")]
  public DateTime ReleaseDate
  { get; set; }
}

With this code, MovieName will now be an attribute on the Movie tag.

<?xml version="1.0" encoding="utf-8"?>
<Movie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   MovieName="Starship Troopers">
  <MovieRating>6.9</MovieRating>
  <MovieReleaseDate>1997-11-07T00:00:00</MovieReleaseDate>
</Movie>

Let's move on to something a little more interesting. Let's create another movie and serialize a List of them to our XML file. Here's the modified code to do just that:

static void Main(string[] args)
{
  Movie movie = new Movie();
  movie.Title = "Starship Troopers";
  movie.ReleaseDate = DateTime.Parse("11/7/1997");
  movie.Rating = 6.9f;

  Movie movie2 = new Movie();
  movie2.Title = "Ace Ventura: When Nature Calls";
  movie2.ReleaseDate = DateTime.Parse("11/10/1995");
  movie2.Rating = 5.4f;

  List<Movie> movies = new List<Movie>() { movie, movie2 };

  SerializeToXML(movies);
}

static public void SerializeToXML(List<Movie> movies)
{
  XmlSerializer serializer = new XmlSerializer(typeof(List<Movie>));
  TextWriter textWriter = new StreamWriter(@"C:\movie.xml");
  serializer.Serialize(textWriter, movies);
  textWriter.Close();
}

Now we have XML that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMovie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Movie MovieName="Starship Troopers">
    <MovieRating>6.9</MovieRating>
    <MovieReleaseDate>1997-11-07T00:00:00</MovieReleaseDate>
  </Movie>
  <Movie MovieName="Ace Ventura: When Nature Calls">
    <MovieRating>5.4</MovieRating>
    <MovieReleaseDate>1995-11-10T00:00:00</MovieReleaseDate>
  </Movie>
</ArrayOfMovie>

Ok, so you can see how easy it is to get your objects into an XML document. Let's now look at how to read an XML document back into our objects - deserialization. The process of deserializing is very similar to what we did for serialization.

static List<Movie> DeserializeFromXML()
{
   XmlSerializer deserializer = new XmlSerializer(typeof(List<Movie>));
   TextReader textReader = new StreamReader(@"C:\movie.xml");
   List<Movie> movies;
   movies = (List<Movie>)deserializer.Deserialize(textReader);
   textReader.Close();

   return movies;
}

Just like before, we first create an XmlSerializer that can deserialize objects of type List<Movie>. The XmlSerializer also deserializes from a stream, so we create a file stream from our XML file. We then simply call Deserialize on the stream and cast the output to our desired type. Now the movies List is populated with objects that we previously serialized to the XML file.

The deserializer is very good at handling missing pieces of information in your XML file. Let's say the second movie didn't have the MovieName attribute on the Movie tag. When the XML file is deserialized, it simply populates that field with null. If MovieRating wasn't there, you'd receive 0. Since a DateTime object can't be null, if MovieReleaseDate was missing, you'd receive DateTime.MinValue (1/1/0001 12:00:00AM).

If the XML document contains invalid syntax, like say the first opening Movie tag was missing, the Deserialize call will fail with an InvalidOperationException. It will also be kind enough to specify the location in the file where it encountered the error (line number, column number).

One thing to remember is that the basic XML serialization won't maintain references. Let's say I populated my movies list with the same movie reference multiple times:

Movie movie = new Movie();
movie.Title = "Starship Troopers";
movie.ReleaseDate = DateTime.Parse("11/7/1997");
movie.Rating = 6.9f;

List<Movie> movies = new List<Movie>() { movie, movie };

Now I have a list containing two of the exact same movie reference. When I serialize and deserialize this list, it will be converted to two separate instances of the movie object - they would just have the same information. Along this same line, the XMLSerializer also doesn't support circular references. If you need this kind of flexibility, you should consider binary serialization.

There's still a lot to cover when it comes to XML serialization, but I think this tutorial covers enough of the basics to get things rolling. If you've got questions or anything else to say, leave us a comment.

John Wang
06/22/2008 - 07:59

Thank you very much!
Very clear.

reply

Bill Sorensen
06/22/2008 - 20:01

TextWriter implements IDisposable; this code would be safer if it used the using statement.

reply

The Reddest
06/23/2008 - 15:00

You're absolutely right. I'll modify the code examples to use the 'using' statement. That also would eliminate the need for the Close() call since the TextWriter closes itself when it's disposed.

reply

Yudy
06/23/2008 - 03:39

I am doubt that it is possible deserilize the XML file without doing the serilize object? That means if I have a XML file created manually and then I just want to get the object information in the project(read only), is it possible? And how?

reply

The Reddest
06/23/2008 - 15:05

The deserializer does not need XML that was created by the serializer. You can use any manually created XML document, just as long as the elements have matching property names.

reply

Yudy
06/24/2008 - 00:52

Thank you very much.
As you said if the elements match the property names, I can deserialize the XML document. So this means I cannot use the deserializer in .NET like XmlSerializer.Deserializer()? Can you give me an example to clarify it?

reply

The Reddest
06/24/2008 - 09:07

Let's say I have a hand written XML document like this:

<?xml version="1.0"?>
<MyObject>
  <MyPropertyA>10</MyPropertyA>
  <MyPropertyB>20</MyPropertyB>
</MyObject>

And I have a C# object like this:

public class MyObject
{
  public int MyPropertyA {get; set;}
  public int MyPropertyB {get; set;}
}

I can deserialize that XML document into my object using the following code:

XmlSerializer deserializer =
  new XmlSerializer(typeof(MyObject));
TextReader textReader = new StreamReader(@"C:\myXMLDoc.xml");
MyObject myObj =
  (MyObject)deserializer.Deserialize(textReader);
textReader.Close();

Since the XML document has the correct root node and has tags that match property names of my object, everything will work fine. If I changed the root node of my XML document to something like this:

<?xml version="1.0"?>
<SomeOtherObject>
  <MyPropertyA>10</MyPropertyA>
  <MyPropertyB>20</MyPropertyB>
</SomeOtherObject>

the deserialization won't work, because it will expect the root node to be named "MyObject". However, you can still make this work by modifying the object to include what the root node is supposed to be named:

[XmlRoot("SomeOtherObject")]
public class MyObject
{
  public int MyPropertyA {get; set;}
  public int MyPropertyB {get; set;}
}

Now we're saying that even though the object is named "MyObject", it will be called "SomeOtherObject" inside the XML document. And again, everything will work.

Hope this clears stuff up.

reply

Tony
07/14/2008 - 04:53

Well..
And if i want

6,9
07-11-1997

??
(Custom DateTime and Flot number format)..

reply

Anise
07/16/2008 - 09:00

This explanation has been very helpful and is nice and clear, thanks!

However, a complete code listing at the bottom with all the usings included, and where the code blocks should be placed in either a single file or in Visual Studio, would be even more helpful to us newbies.

reply

K03123
07/18/2008 - 01:42

thanks for the great article.

in your example above, if i want to set attribute for element name lets say Rating, how can i do that? or do i have to create Rating as Class and apply attribute there? i think i can do that way but creating new class just to fulfill that doesn't seem quite right.

any suggestion?

cheers

reply

Ramki
07/30/2008 - 12:04

Can I do deserialize and deserialize specific node not entrie XML doc?
for example I want to deserialzie only data in below xml file. Can it be done?

20

20

reply

The Reddest
07/30/2008 - 16:57

Sorry Ramki, but the comment system strips < and >. Refer to this post on how to put xml and other code in the comments.

reply

Syed Farabi
09/04/2008 - 22:42

This is a great tutorial I found.

Thanks a lot to provide this kind of clear tutorial.

reply

Anonymous
09/08/2008 - 00:08

dear sir
Request you to solve my issue.i.e. Let me know how to use jquery inside a xml file.if iam using so its giving err0r as
1.$ is not defined
2.script is not defined

reply

Andrew
09/16/2008 - 03:45

Is there any way to serialize an object that has private or internal set accessors, e.g:

public propertyname {private set; get; }

I can't seem to get it to work.

reply

Anonymous
07/21/2009 - 12:20

Strangley, serializing a VB class that has readonly properties works if you impliment ISerializable and use reflection to skip over your readonly properties, but it doesn't seem to play ball in c#.

reply

Hagit
11/30/2008 - 03:51

Thank for the important article.
i'm trying to do serilization with files that are writing to an isolate storage - without success. do you have an idea why??

reply

Brandon
12/08/2008 - 14:34

Extremely helpful, Reddest. Always love your blog for the best and most useful information - keep up the good work!

reply

Jon
12/11/2008 - 16:51

Excellent tutorial! I look forward to reading more.

reply

Kazi Sabbir Ibna Ataur
12/13/2008 - 02:09

Saved lot of my time.Easy to follow. Keep this great works coming.

reply

Rotem or
12/16/2008 - 03:19

im trying to do almost the same thing eccapt from that i want to store the stream in a string on a hidden field on the page
but it seems that the deserialization dosnt work if i put it on a string
(if ichange the source to a file it works like charm)
any idieas ?

reply

Deo
01/01/2009 - 00:29

Thanks a lot. good article to beign with. tried the examples and really good.

reply

Adnene
03/05/2009 - 11:05

Thanks a lot for the example
I want to ask you how to serialize a complex object, I mean an object with some generic list property type. I have always an invalid operation exception or error when creating the xml document or a reflection error.

structure sample:

object1
prop1 string
prop2 int
prop3 List

object2
prop1 string
prop2 string
prop3 List

reply

The Reddest
03/05/2009 - 11:33

Lists have XML serialization support built right in. The XML serializer doesn't support circular references, so if the List in object1::prop3 contains a reference to object1, you'll get an error. That's all I've got for now. If you post some example code, I can probably help more.

reply

Ben
01/21/2010 - 06:18

Maybe xml serialization doesn't work on mixed type lists. I think it may only work on typed lists, like List.

reply

Janak
03/16/2009 - 01:42

Nice article. But i'm stuck on one issue where i want to write comment in between the node. How can i achieve that using serialization?

For e.g. I want the output like:

<?xml version="1.0"?>
<SomeOtherObject>
   <!-- #if (condition) -->
  <MyPropertyA>10</MyPropertyA>
  <!-- #endif -->
  <MyPropertyB>20</MyPropertyB>
</SomeOtherObject>

reply

Sal
03/27/2009 - 13:39

This was fantastic information, thank you. Now I have another question. What if what the document I want to read from XML has the following structure in one of its subtrees? how should I create the object?

<NameValuePairs>
    <Name>Alpha</Name>
    <Value>1.7</Value>
    <Name>Beta</Name>
    <Value>0.3</Value>
    <Name>OtherName</Name>
    <Value>OtherValue</Value>
    <Name>ManyOtherNamesCouldFollow</Name>
    <Value>WithTheirRespectiveValues</Value>
</NameValuePairs>

Would using a list or even a Dictionary work?

Thanks in advance.

reply

geo_c
08/04/2009 - 04:34

that xml does not conform to a relational model and is not recommended for serialization.
in your xml, the name & value elements are required to have a particular order of existence, otherise the value of one may get mixed up with some other name.

in xml standards, design like this creates ambiguity and hard to use for programming APIs.

reply

Anonymous
11/03/2009 - 12:14

Good information, thank you for commenting. I've had a similar instance where I wanted to added different elements, but definitely wanted to remove the ambiguity. As it turns out, I modified my XML to use attributes to absorb the names/values.

And thanks for the suggestion about the XmlArray. I'm looking to utilize that suggestion in a project.

reply

Anonymous
06/25/2009 - 08:36

How would you serialize and deserialize this?

<PropertyNames>
  <Name># Plate</Name>                                     
  <Name>G Plate</Name>                                 
  <Name>C Plate</Name>                                 
  <Name>1 Head</Name>                                  
  <Name>2 Heads</Name>                                 
  <Name>3 Heads</Name>         
</PropertyNames>

reply

The Reddest
06/25/2009 - 11:34

I don't think deserialization can handle this case by default. You can override the XML serializer for an object, however I don't know the syntax off the top of my head.

reply

vszmey
07/03/2011 - 13:54

try the following:
public item[] foods = new item[3];
foods[0] = new item();
foods[1] = new item();
foods[2] = new item();
XmlSerializer serializer = new XmlSerializer(typeof(item[]));

But in that case I have XML like this:
<?xml version="1.0" encoding="utf-8"?>

Does anyone knows how can I rename ?

reply

vszmey
07/03/2011 - 13:58

Sorry, there is xml:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfItem>
  <item>  </item>
  <item>  </item>
  <item>  </item>
</ArrayOfItem>

reply

geo_c
08/04/2009 - 04:35

XmlArray attribute could be utilized.

reply

sweeny
10/29/2009 - 07:10

Thanks for the simple explanation of serialization

reply

Z.K.
12/28/2009 - 01:08

Nice article, but I have one question.

I understand everything up to the point where you write the List to the xml file. I understand how to create a List and how to add elements to the List and even how to write the List to the xml file. Your example though shows a root element of ArrayOfMovie and then Movie elements inside that. I cannot see how you create the ArrayOfMovie. When I do it, I get a bunch of Movie elements and an error about more than one root element. I have looked over the code several times, but I do not see how you did that. Could you explain in more detail or provide a file that I could download to look at?

reply

stanbeard
02/01/2010 - 01:58

Great article!

If I have:

public class Movie {
    string Name;
    Actor LeadActor;
}

public class Actor {
    string Name;
    DateTime DOB;
}

And I want to serialize the Movie like this:

<Movie>
    <Name>Casino Royale</Name>
    <LeadActor>Daniel Craig</LeadActor>
</Movie>

How do I do that? That is, how do I tell the Movie class to only serialize the Name property of the LeadActor member instead of the whole object?

Thanks!

reply

Osiris
03/23/2010 - 08:21

Well first your class fields have to be public (But I'm sure you already knew that)

Then use these Xml Attributes on your Actor class:

    public class Actor {
        [XmlText]
        public string Name;
        [XmlIgnore]
        public DateTime DOB;
    }

And you are good to go!

reply

Saad B.
03/19/2010 - 05:53

Well stanbeard, that's the question i've been looking for the answer all day long.

reply

Osiris
03/23/2010 - 08:21

See my response to Stanbeards question

reply

Anonymous
06/08/2010 - 22:40

DeSerialize does not work can anybody help.I have very little knowledge about this

public string SerializeObject(Object objToSerialize)
        {
               XmlSerializer ser = new XmlSerializer  (objToSerialize.GetType());
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.IO.StringWriter writer = new System.IO.StringWriter(sb);
           
            ser.Serialize(writer, objToSerialize);
            return writer.ToString();
        }
        public object DeSerializeAnObject(string xmlOfAnObject)
        {
            Object obj = new Object();
            System.IO.StringReader read = new StringReader(xmlOfAnObject);
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
            System.Xml.XmlReader reader = new XmlTextReader(read);
            try
            {
                obj = (object)serializer.Deserialize(reader);
                return obj;
            }
            catch { throw; }
            finally { reader.Close(); read.Close(); read.Dispose(); }
        }

reply

The Reddest
06/09/2010 - 08:27

What doesn't work? Are you getting an exception? Is your file empty? Details please.

reply

Anonymous1
06/09/2010 - 23:13

No Its not empty..
I get an Exception.

Invalid Operation Exception "There is an error in XML document (2, 2)."

Inner Exception caught is {" was not expected."}

reply

Anonymous1
06/09/2010 - 23:30

No Its not empty..
I get an Exception.

Invalid Operation Exception "There is an error in XML document (2, 2)."

Inner Exception caught is TaskListDO xmlns='' was not expected."

I am Trying to Serialize an object in my Web application(Serializing works) and when i try to Deserialize the same string in WebServices it gives the exception..and
one more Doubt is in reference.cs the class which has to be serialized has to be autogenerated is it..
if yes its not generated in my reference.cs file

reply

Anonymous1
06/10/2010 - 07:42

Hello,

I dint make any changes but I am getting the class which has to be serialized in reference.cs I mean it is autogenerated...
But now my problem is after deserializing the XML string I am not able to get the values passed from my application...

Please Help

reply

Roberto
09/27/2010 - 09:34

Doesn't look too difficult.

In your deserializer function you try to use an object of type Object. In this case the serializer doesnt have a clue of which type of object you really want to deserialize. Since Object doesnt have any public properties it's likely that it breaks.
You need to pass in the real Type of the object you want to deserialize: XmlSerializer(MyType)

reply

Lolitha
07/15/2010 - 16:05

Thank you very..... much for an excellent article. This is very clear. I read lots of stuff related to xmlserializer but nothing else was this clear. Keep up the good work.

reply

Sjari
08/05/2010 - 08:59

Hi, Thanks allot, that was extremely wonderful :-)

but the code does not run for me!

using System;
using System.IO;
using System.Xml.Serialization;

namespace XML007
{
    class Class1
    {
        public class Movie
        {
            public string Title
            { get; set; }

            public int Rating
            { get; set; }

            public DateTime ReleaseDate
            { get; set; }
        }

        static void Main(string[] args)
        {
            Movie movie = new Movie();
            movie.Title = "Starship Troopers";
            movie.ReleaseDate = DateTime.Parse("11/7/1997");
            movie.Rating = 6;

            SerializeToXML(movie);
        }

        static public void SerializeToXML(Movie movie)
        {
// I get erro in the line below, the class must be public, which it is !!!            
XmlSerializer serializer = new XmlSerializer(typeof(Movie));
            TextWriter textWriter = new StreamWriter(@"C:\movie.xml");
            serializer.Serialize(textWriter, movie);
            textWriter.Close();
        }
    }
}

reply

Sjari
08/05/2010 - 09:01

Ah I found out that "class Class1" must be "public class Class1"

reply

Sjari
08/06/2010 - 00:31

how to de-serialize it ?

reply

vihrao
09/14/2010 - 13:36

I have problems in serializing a list.
Here is my class:

public partial class ProblemType
{
        private List<DateTimeType> dateTimeField;
        public ProblemType()
        {
            this.dateTimeField = new List<DateTimeType>();
        }
        public List<DateTimeType> DateTime
        {
            get
            {
                return this.dateTimeField;
            }
            set
            {
                this.dateTimeField = value;
            }
        }
 }
public partial class DateTimeType
    {
        private CodedDescriptionType2 typeField;
        private string exactDateTimeField;
        public DateTimeType()
        {
            this.typeField = new CodedDescriptionType2();
        }
        public CodedDescriptionType2 Type
        {
            get
            {
                return this.typeField;
            }
            set
            {
                this.typeField = value;
            }
        }
        public string ExactDateTime
        {
            get
            {
                return this.exactDateTimeField;
            }
            set
            {
                this.exactDateTimeField = value;
            }
        }
    }

Here is how I call the code:
ProblemType pt =  new ProblemType();
pt.DateTime = GetDateTimeRange();

public List<DateTimeType> GetDateTimeRange()
{
        List< DateTimeType> dttList = new List< DateTimeType>();
        DateTimeType dtt1 = new CCRG.DateTimeType();
DateTimeType dtt2 = new CCRG.DateTimeType();
                dtt1.Type = GetType1();
                dtt1.ExactDateTime = GetExactdateTime1();
                dttList.Add(dtt1);
 dtt2.Type = GetType2();
                dtt2.ExactDateTime = GetExactdateTime2();
                dttList.Add(dtt2);
            return dttList;
}

When I run the code I get serialized XML like this:
<ProblemType>
 <DateTime>
   <DateTimeType>
      <Type><Text>Episode Begin Datetime</Text></Type>
     <ExactDateTime>04/01/2010</ExactDateTime>
  </DateTimeType>
  <DateTimeType>
      <Type><Text>Episode End Datetime</Text></Type>
      <ExactDateTime>04/02/2010</ExactDateTime>
  </DateTimeType>
 </DateTime>
</ProblemType>
[/langauge]
There is slight problem. I have to rid of the tag <DateTimeType> because the receiving program does not validate the tag.
IMy sericalzed XMl should look like this:
[language]<ProblemType>
 <DateTime>
<Type><Text>Episode Begin Datetime</Text></Type>
  <ExactDateTime>04/01/2010</ExactDateTime>
  </DateTime>
<DateTime>
<Type><Text>Episode End Datetime</Text></Type>
  <ExactDateTime>04/02/2010</ExactDateTime>
 </DateTime>
</ProblemType>
[/langauge]
Can you tell me how to this problem solved?

reply

vihrao
09/14/2010 - 13:41

The later part of my posting got garbled. Sorry. I am repostng only that part.
The serialized output looks like this:

 
<ProblemType>
 <DateTime>
   <DateTimeType>
      <Type><Text>Episode Begin Datetime</Text></Type>
     <ExactDateTime>04/01/2010</ExactDateTime>
  </DateTimeType>
  <DateTimeType>
      <Type><Text>Episode End Datetime</Text></Type>
      <ExactDateTime>04/02/2010</ExactDateTime>
  </DateTimeType>
 </DateTime>
</ProblemType>

There is slight problem. I have to get rid of the tag because the receiving program does not validate the tag.
My sericalzed XML should look like this:

 ProblemType>
 <DateTime>
<Type><Text>Episode Begin Datetime</Text></Type>
  <ExactDateTime>04/01/2010</ExactDateTime>
  </DateTime>
<DateTime>
<Type><Text>Episode End Datetime</Text></Type>
  <ExactDateTime>04/02/2010</ExactDateTime>
 </DateTime>
</ProblemType>

Can you please tell me how to get this problem solved?

reply

stfz27
09/16/2010 - 14:02

hi
i m wondering if i have an xml file like this

<?xml version="1.0"?>
<MyObject>
  <MyPropertyA>attribute1 ="10"</MyPropertyA>
  <MyPropertyB>attribute2 ="20"</MyPropertyB>
</MyObject>

can i deserialaze it using the same method
thanks for your help

reply

Shailesh
01/09/2011 - 06:47

Hi,

This is truly very nice and easy article.
Thanx.
Keep up the good work.

reply

Alex M.
02/01/2011 - 12:02

Hi,

How will the code change for a more complicated XML like the following:

<resultset>
  <table>
    <name>Results</name>
    <data>
      <row>
        <field name="USER_ID" type="NUMBER">6201</field>
        <R name="LOGIN" type="VARCHAR2">nsawnan1</field>
        <field name="FIRST_NAME" type="VARCHAR2">Navin</field>
        <field name="LAST_NAME" type="VARCHAR2">Sawnani</field>
        <field name="DELETED" type="NUMBER">0</field>
        <field name="IS_ADMIN" type="NUMBER">0</field>
      </row>
    </data>
  </table>
</resultset>

I need to be able to represent a user from this, with the attributes USER_ID, LOGIN, FIRST_NAME, LAST_NAME, DELETED and IS_ADMIN.

I have followed the steps detailed above and came up with the following class:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace CS.Dtm.SecurityData.Client
{
    [Serializable]
    [XmlRoot("resultset")]
    public class User: IUser
    {
        [XmlAttribute("USER_ID")]
        private int _userId;
        [XmlAttribute("LOGIN")]
        private string _login;
        [XmlAttribute("FIRST_NAME")]
        private string _firstName;
        [XmlAttribute("LAST_NAME")]
        private string _lastName;
        [XmlAttribute("DELETED")]
        private int _deleted;
        [XmlAttribute("IS_ADMIN")]
        private int _isAdmin;
       

        public User(){ }

        public int UserId { get { return this._userId; } set { _userId = value; } }
        public string Login { get { return this._login; } set { _login = value; } }
        public string FirstName { get { return this._firstName; } set { _firstName = value; } }
        public string LastName { get { return this._lastName; } set { _lastName = value; } }
        public int Deleted { get { return this._deleted; } set { _deleted = value; } }
        public int IsAdmin { get { return this._isAdmin; } set { _isAdmin = value; } }

        #region IUser Members

        #endregion
    }
}

But it will still not compile - it is complaining that " was not expected", with the message "There is an error in XML document(1,2)"

Can you please be kind and advise on this?

reply

noryac
11/13/2011 - 07:32

why do you have the "r" ? nsawnan1

If you are declaring XmlRoot= "resultset" the Reader will see the "table" XML Element, not "" XMLnode.

reply

Geoff
02/22/2011 - 16:56

When I serialize a bool array I get an output similar to:

<ArrayOfBoolean>
  <boolean>false</boolean>
  <boolean>false</boolean>
  <boolean>false</boolean>
</ArrayOfBoolean>

How do I get it to look like:

<ArrayOfBoolean>
  <boolean Index="0">false</boolean>
  <boolean Index="1">false</boolean>
  <boolean Index="2">false</boolean>
</ArrayOfBoolean>

I want to write an attribute and value at the same time.

Thanks,
Geoff

Apologies if this didn't post in xml format. I won't "crud" up the page again.

reply

Jason
04/09/2011 - 17:09

Freaking AWESOME example thanx!

reply

Sameer C Thiruthikad
04/30/2011 - 04:15

Very useful. Thanks.

reply

ALec
05/11/2011 - 23:57

Hi I can't seem to resolved this issue

System.InvalidOperationException was unhandled
Message=There is an error in XML document (1, 2).
Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(TextReader textReader)
at ConsoleApplication1.Program.DeserializeFromXML3(String xml) in C:\WPF in Two Weeks\ConsoleApplication1\ConsoleApplication1\Program.cs:line 138
at ConsoleApplication1.Program.Main(String[] args) in C:\WPF in Two Weeks\ConsoleApplication1\ConsoleApplication1\Program.cs:line 21
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.InvalidOperationException
Message= was not expected.
Source=wzmj2ehc
StackTrace:
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderList1.Read3_ArrayOfMovies()
InnerException:

[Serializable]
[XmlRoot("Movies")]
public class Movies
{
[XmlElement("ID")]
public int ID { get; set; }

[XmlElement("Title")]
public string Title { get; set; }

[XmlElement("ReleaseDate")]
public DateTime ReleaseDate { get; set; }

[XmlElement("Genre")]
public string Genre { get; set; }

[XmlElement("Price")]
public decimal Price { get; set; }

}

this is my xml fragment.

<AllMovies>
  <Movies>
    <ID>1</ID>
    <Title>When Harry Met Sally</Title>    
    <ReleaseDate>1989-01-14T00:00:00</ReleaseDate>
    <Genre>Comedy</Genre>
    <Price>6.95</Price>
  </Movies>
</AllMovies>

Thanks so much

reply

me
05/18/2011 - 15:25

Thanks a lot for this post - very clear and very helpful!

reply

Anonymous
06/01/2011 - 04:37

Hi!
I have a question:

Let's say, you have about one hundred entries(movies) in your collection, and you do not want to overwrite the file, every time you add an entry.

What would you do, if you wanted to just add another movie to your xml file?

Trying to deserialize a single movie into an existing file via xmldeserializer will result in an error message, as it is only made for writing a new xml file including version info etc.

Here is my code:

//load the document from stream
XDocument objDoc = XDocument.Load(objStream);

//get the collection node, that contains all elements //(movies) , and create a writer
XmlWriter objWriter = objDoc.Elements().First(objElement => objElement.Name == "Collection").CreateWriter();
                               
                                System.Xml.Serialization.XmlSerializer objSerializer =new System.Xml.Serialization.XmlSerializer(objItem.GetType());
objSerializer.Serialize(objWriter, objItem)

This is the error message I have been talking about:
{"WriteStartDocument cannot be called on writers created with ConformanceLevel.Fragment."}

Thank you very much

reply

The Reddest
06/01/2011 - 08:33

XML is not designed to be used for random access like this. Serializing and deserializing 100 movie objects will be trivially fast anyway. If you want to insert individual items without rewriting the file, you should start looking into databases.

reply

Zeeshan Umar
06/21/2011 - 04:54

Nice tutorial, it was really interesting. Also there a simple tutorial on XML :-

http://zeeshanumardotnet.blogspot.com/2011/05/xml-serilization-tutorial.html

reply

Kyle
07/07/2011 - 09:52

Hey,
Is there something special you have to do to get this code to work with service contracts?

Here's some example code:

    [ServiceContract]
    public partial class MovieService
    {
        [WebGet(UriTemplate = "Movie")]
        [OperationContract]
        Movie GetMovie()
        {
            return new Movie();
        }
    }

    public class Movie
    {
        [XmlAttribute("MovieName")]
        public string Title
        { get; set; }

        [XmlElement("MovieRating")]
        public float Rating
        { get; set; }

        [XmlElement("MovieReleaseDate")]
        public DateTime ReleaseDate
        { get; set; }
    }

This code serialized the xml but leaves ReleaseDate as ReleaseDate rather than MovieReleaseDate.

Thank you.

reply

Kyle
07/07/2011 - 12:27

I figured it out. For those who are interested, you just need to add an attribute to the "GetMovie" function called [XmlSerializerFormat].

This causes it to use the XML Serializer rather than the OperationalContract one.

reply

Bharath
07/19/2011 - 05:15

Excellent for a fresher to learn... Thank u.

reply

Testasekka
07/24/2011 - 04:19

Thank you for the clear explanation.

reply

Adeogun Adedamola
09/12/2011 - 05:11

This is a fantastic article. you have saved me a bunch. It's simple and complete. Thanks so much

reply

jv
09/16/2011 - 00:53

xyz
Male

can any one help me how could i update the name and gender after deserlization the xml.

reply

jv
09/16/2011 - 00:56

<DynamicObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <name>Location1</name>
  <backcolor>255,255,203,179</backcolor>
  <forecolor>255,0,0,0</forecolor>
  <status>Available</status>
  <locationX>0</locationX>
  <locationY>0</locationY>
  <width>592</width>
  <height>520</height>
  <noOfChilds>2</noOfChilds>
  <backgroundImageLayout>0</backgroundImageLayout>
</DynamicObject>

xyz
Male

can any one help me how could i update the name and gender after deserlization the xml.

reply

jv
09/16/2011 - 00:59

how could i update the satus with new status or any other. after deserlization the xml.

<DynamicObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <name>Location1</name>
  <backcolor>255,255,203,179</backcolor>
  <forecolor>255,0,0,0</forecolor>
  <status>Available</status>
  <locationX>0</locationX>
  <locationY>0</locationY>
  <width>592</width>
  <height>520</height>
  <noOfChilds>2</noOfChilds>
  <backgroundImageLayout>0</backgroundImageLayout>
</DynamicObject>

reply

Denys
10/04/2011 - 18:27

Thanks!

reply

Dinesh
10/13/2011 - 05:43

Thanks for the post

reply

Neal
11/04/2011 - 16:15

My XMl file has a namespace. How can I deserealize.
How can I deserealize with a namespace in my XML

Unhandled Exception: System.InvalidOperationException: There is an error in XML
document (5, 2). ---> System.InvalidOperationException: was not expected.

reply

Jason Belmonti
11/10/2011 - 10:25

Thanks for taking the time to put this up! So valuable!

reply

Adam
11/15/2011 - 15:47

Thanks for the post!

reply

Anonymous
12/16/2011 - 16:44

Nice

reply

kiran
12/22/2011 - 00:10

can i serialize object that is recursive ?

reply

kiran
12/22/2011 - 23:42

hello can any body say how to serialize object that contain self reference ?

reply

Ramu Ajay
01/25/2012 - 01:00

Thanks a lot. I have learned what exactly Serialization is.

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.