XmlSerialization in .NET part 3 (arrays & lists)

Well, it’s been a while, but here we are again, in our third episode of our adventures in Xml Serialization in .NET.

Today, I’m gonna be dealing with how to serialize nested object trees, in arrays & lists. I’m gonna be using the last example, where we deserialized / serialized a class of type ClassDescriptor, and add onto that.

First things first. I’m declaring a member variable of type string[], called m_ChildArray. In the class constructor, I’m gonna be filling it up with some dummy strings, just to illustrate Serializing the array.

private string[] m_ChildArray = new string[15];

public ClassDescriptor()
{
// ok, initialize the string array with dummy values ...
for(int i=0; i<15; i++){
m_ChildArray[i] = i.ToString();
}
}

[XmlArray("child-prim-array")]
public string[] ChildArray {
get {
return m_ChildArray;
}
set {
m_ChildArray = (value==null)? new string[0] : value;
}
}

As you can plainly see, I’ve also added a property for my array, and included the XmlArray attribute in the property declaration. That will create a element in my resulting Xml, and fill it up with xxx elements, representing the values contained within the array.

The resulting Xml extract looks something like this:

<child-prim-array>
<string>0</string>
<string>1</string>
<string>2</string>
<string>3</string>
<string>4</string>
<string>5</string>
<string>6</string>
</child-prim-array>

As you can see, the process is actually very simple, and will work with any type of primitive, or serializable class. No need to modify the rest of the code, that does the actual (de) serialization.

Now, you might point out that it’s quite useless to have the enclosing element there, it just bloats the resulting Xml. Perhaps you’d like to have those strings appear in the Xml on their own, directly under the root element. Easy as pie …

Just replace the XmlArray attribute in the code, with an XmlElement attribute:

[XmlElement("child-string")]
public string[] ChildArray {
get {
return m_ChildArray;
}
set {
m_ChildArray = (value==null)? new string[0] : value;
}
}

I’ve modified the code in main just a little bit, to set the array to a string array containing 3 elements. Run the example again, and see the resulting Xml now:


<?xml version="1.0" encoding="utf-8"?>
<class xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" class-name="System.Int32" assembly-name="System">
<child-string>1</child-string>
<child-string>angel</child-string>
<child-string>microsoft</child-string>
</class>

Let’s see what happens with a List now. I’m gonna add another “string array” member, this time with an ArrayList:

private IList m_ChildList = new ArrayList();
private string[] m_ChildArray = new string[0];

public ClassDescriptor()
{
// ok, initialize the string array with dummy values ...
for(int i=0; i<15; i++){
m_ChildList.Add(i.ToString());
}
}

[XmlElement("child-array-string")]
public string[] ChildArray {
get {
return m_ChildArray;
}
set {
m_ChildArray = (value==null)? new string[0] : value;
}
}

[XmlElement("child-list-string")]
public IList ChildList {
get {
return m_ChildList;
}
set {
m_ChildList = (value==null)? new ArrayList() : value;
}
}

And in main, I’m gonna modify a couple of lines to add 3 strings to the list, and to the string array properties of my class … I run the project, and see the resulting Xml.

You’ll see that both the string array and the IList have been serialized, but with different element names. Actually, you’ll see that in the case of the IList, the resulting xml contains XSD type info ;) … that’s because when the system is deserializing, it needs to have concrete data about te type it’s instantiating - remember that the IList will give you back Object references, it doesn’t know explicitly what sort of objects it contains. (Actually, I’m wondering how this will work with .NET 2.0, where I can define an IList using Generics … oh well, we’ll see I guess ;) … )

Well, I think that’s a good chunk of knowledge for the time being. With a little experimentation you’ll get far with Xml Serialization in .NET.

For the next installment, I’m planning to go through the process of eliminating the Xml Serialization attributes inside my class code, and provide the mappings dynamically at runtime ;)

It’ll be interesting to see the level of flexibility attained with this approach, contrasted with [any] performance degradation that might result from this approach.

Till then, may the streams be with you ;) You can find the sample project, here.

O:]

Comments are closed.