Avoid Serialization of Empty ArrayList or Collection

XML serialization of objects can be helpful in situations when persistence of objects as files is needed, but objects with empty ArrayLists and Collections can render XML that is not easy to serialize back as objects. Below is an example of serialization of an object as XML. It’s a Library with a Name and a collection of Books.

 1 using System.Xml.Serialization;
 2 
 3 [XmlRoot]
 4 public class Library
 5 {
 6     private Books libraryBooks = new Books();
 7     private string libraryName = string.Empty;
 8     public Library(string name)
 9     {
10         this.libraryName = name;
11     }
12     [XmlElement]
13     public string Name
14     {
15         get { return this.libraryName; }
16     }
17     [XmlArrayItem(typeof(Book))]
18     public Books Books
19     {
20         get { return this.libraryBooks; }
21     }
22 }

If the Books collection was empty, it would be serialized as:

1 <?xml version="1.0" encoding="utf-8"?>
2 <Library xmlns:xs="http://www.w3.org/2001/XMLSchema">
3     <Name>Goodyear City Library</Name>
4     <Books />
5 </Library>

There might be some issues reading this XML back as an object because of that unnecessary <Books />, especially if the XML is validated against a schema. Whenever <Books> is present, the serializer is expecting it to contain items. The easiest way to prevent any problems is to tell the XmlSerializer to exclude empty ArrayLists and Collections when generating the XML. This must be done to all the ArrayLists and Collections.

An extra property must be specified, in this case, with the name BooksSpecified that returns a bool. In the modified code below (lines 22-26), I wrote it to return false if libraryBooks is empty, and I also added [XmlIgnore] so it doesn’t get serialized. Now, whenever Books is empty, BooksSpecified is false telling the XmlSerializer to exclude Books from the generated XML.

So this also tells us that the “Specified” suffix has a special meaning for the XmlSerializer, and this in itself can be a cause of headaches for the unaware.

 1 using System.Xml.Serialization;
 2 
 3 [XmlRoot]
 4 public class Library
 5 {
 6     private Books libraryBooks = new Books();
 7     private string libraryName = string.Empty;
 8     public Library(string name) 
 9     {
10         this.libraryName = name;
11     }
12     [XmlElement]
13     public string Name
14     {
15         get { return this.libraryName; }
16     }
17     [XmlArrayItem(typeof(Book))]
18     public Books Books
19     {
20         get { return this.libraryBooks; }
21     }
22     [XmlIgnore]
23     public bool BooksSpecified
24     {
25         get { return (this.libraryBooks.Count > 0); }
26     }
27 }

The resulting XML should look like the following, a library with no books :). It will only serialize Books if it has items, and this allows serializing this XML back as a Library object less of a pain.

1 <?xml version="1.0" encoding="utf-8"?>
2 <Library xmlns:xs="http://www.w3.org/2001/XMLSchema">
3      <Name>Goodyear City Library</Name>
4 </Library>

Tags: .NET, C#, Code, How To, Persistence, Programming, Serialization, XML

Bookmark and Share

Comments