BizTalk Utilities CV ,   Jobs ,   Code library  
 
Home Page
XmlSerializer
Serializing Arrays
XmlElement Attribute Type
XmlIncludeAttribute
XmlSerializer
Serialization Attributes
Serializable Classes
Deserializing an object
Serializing an object
Serialize Class
Metadata Attributes
<< XML DOM
XQuery >>

By :Mark Wilson
I am the creator of TopXML. I am available for international and local (Australia) contracts. I am a Solution Architect/Business Analyst. I have worked in IT in several countries (NZ, Australia, South Africa, UK) building and training teams for government and very large non-governmental organizations. I am ex-Microsoft Consulting Services. I wrote the first book on Microsoft XML published in 2000 called XML Programming with VB and ASP. Most recently I have been building tools for the SEO industry. Ask me for a 37 point SEO health-checkup for your website.
First posted :03/24/2008
Times viewed :5900

 

Serializing Collection Classes

The previous section showed us how to annotate source files with metadata attributes to customize how arrays are mapped to XML. Now we will see if our knowledge transfers to collection classes. These classes are very similar to arrays but don’t require a fixed size, can hold unrelated types and are optimized for different usage scenarios. The .NET Framework provides a number of collection classes ready to use in the System.Collections namespace, for example an ArrayList, a Dictionary or a Hashtable just to name a few.

The XmlSerializer can process all collections that implement one of the .NET framework’s collection interfaces: IEnumerable or ICollection. All collections provided by the .NET framework implement these interfaces, so we can serialize or deserialize these collections without much additional work. All of the framework’s collections are weakly typed, so we have to declare the types stored inside a collection before the XmlSerializer can correctly process it. Declaring types inside a collection works just like declaring types inside an array, which we learned in section 9.5.1.

Customizing the XML layout for a collection

Customizing how a collection is mapped to XML is very much like customizing an array. Attaching the XmlArray attribute and the XmlArrayItem attribute to a collection class has the same effect as attaching them to arrays. Let’s confirm this and replace the Vehicle array in the ParkingLot class from the previous example with the more flexible System.Collections.ArrayList.

2           Listing 9.7 Use of XmlArray attributes with a collection class

public class ParkingLot

{

  public ParkingLot ()

  {

   ParkedVehicles = new

    ArrayList();

  }

  [XmlArrayItem(
    ElementName="ParkedCar",
    Type=typeof(Car))]

  [XmlArrayItem(

    ElementName="ParkedMotorcycle",

    Type=typeof(Motorcycle))]

  [XmlArray(

    ElementName="ParkedVehicles")]

  public ArrayList ParkedVehicles;

}

<ParkingLot …>

  <ParkedVehicles>
    <ParkedCar>
      <Make>Ford</Make>

      <Model>Explorer</Model>

      <Year>1997</Year>

      <VIN>1234</VIN>

    </ParkedCar>

    <ParkedMotorcycle>

      <Make>Aprilla</Make>

      <Model>Mille R</Model>

      <Year>2000</Year>

    </ParkedMotorcycle>

  </ParkedVehicles>

</ParkingLot>

Even though we are now using an ArrayList instead of an array the XML representation of the new ParkingLot class has not changed.

This may seem odd to those of us already familiar with the ArrayList collection. The ArrayList exposes seven public properties; none of these properties is serialized.  The public properties are considered as auxiliary information only, so whenever the Serialize() method detects an object that implements ICollection or IEnumerable it will ignore the object’s public properties. Instead it uses the interfaces to serialize all the items inside the collections. This again reminds us that the intended use of the XmlSerializer is in data-driven environments where the data and its XML representation are the primary focus, not a 100% accurate snapshot of an object.

Developing custom collections

In many cases we might like to extend the collection classes provided by the framework. Maybe we need to ensure that only objects of certain types are stored in the collection or we need a different sorting algorithm. Either way, custom collection classes will de-/serialize properly as long as they implement IEnumerable or ICollection and, of course, we supply enough information about the types stored inside the collection. Keep in mind that only the items that can be accessed through the interfaces are serialized, public properties and fields are not, unless they return a class that itself implements ICollection.

There is another caveat when you implement your own container classes: The implementation of the XmlSerializer requires the collection to have a default accessor, even though ICollection does not require it. In VB.Net a default accessor is implemented as an Item property with a single parameter of type Integer. In C# it is implemented as an indexer. The syntax for an indexer resembles a read-only property, but it uses the square brackets around the parameter.  Listing 9.8 gives an example for a strongly-typed collection based on an ArrayList with a default accessor:

3           Listing 9.8 Custom collection with a default indexer.

public class CarArray : ICollection

{

  public CarArray() { Cars = new ArrayList(); }

  // ICollection public properties

  public int Count { get { return Cars.Count; } }

  public bool IsSynchronized { get { return Cars.IsSynchronized; } }

  public object SyncRoot { get { return Cars.SyncRoot; } }

  // ICollection public method

  public void CopyTo( Array a, int i ){ Cars.CopyTo( a, i ); }

  // IEnumerable

  public IEnumerator GetEnumerator()

  {

    return Cars.GetEnumerator();

  }

  // the default indexer

  public Car this[int i]               |#1

  {                                    |

    get                                |

      {                                |

        return (Car) Cars[i];          |

      }                                |

  }                                    |

  private ArrayList Cars;             |#2

  // only add Cars and derived classes to the arraylist

  public void Add( Car c ){ Cars.Add( c ); }

}

(annotation) <#1 The default indexer is used to enumerate through the elements of an array or collection. The square brackets denote an indexer in C#.>

(annotation) <#2 The field to store the collection data has to be private. Because the ArrayList implements ICollection. >

NOTE: No metadata attributes were attached to the ArrayList member in the example above. The XmlSerializer can process objects of the type returned by the default accessor without attaching any additional attributes. Any other types need to be declared through an XmlInclude, an XmlElement or an XmlArrayItem attribute


Rate this article on a scale of 1 to 10

Your vote :  


 

Recent Jobs

Integration Specialist Needed - Wor
Virtualization Server Infrastructur
A great opportunity to Digital Vide
here is a greate opportunity as a S
A great opportunity as a Network En

View all Jobs (Add yours)
View all CV (Add yours)




swimming pool contractor
chicago web site design
desktop fax online
Domain Names
unlimited conferencing
Dolce&gabbana sunglasses
answering service


    Email TopXML  

Front Page Daily Stuff TopXML Forum XML blogs XML Newsgroups BizTalk Biztalk Utilities Biztalk Utilities Tutorial B2B SAP XML Microsoft .NET Dotnet System XML Soapformatter SQLXML XMLserializer XQuery PHP PHP SimpleXML PHP XML Dom PHP XML RPC PHP XSLT Java Java Java XML Xalan Microsoft ASP ASP Schemas XML SQL Server XML XMLDom XSL XSL Tutorial XSLT Stylesheets General Javascript CSS XHTML WAP