BizTalk Utilities CV ,   Jobs ,   Code library  
 
Home Page
XmlSerializer
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 :4332

 

Serializing Arrays

Until now we only considered scalar members, but what about arrays and collection types? The

XmlSerializer will process them just fine, as long as it created type mappings for the types inside the collection or the array. In section 9.4 we learned how to declare additional types for scalar fields. The next sections will show us how to declare additional types for arrays and collections. We will also read about attributes to customize XML mappings for arrays and collections.

Serializing arrays works just like serializing scalar objects. Everything we’ve learned so far about declaring types and customizing type mappings applies just the same. We can pass an array type to the

XmlSerializer constructor, call Serialize() or Deserialize() and the XmlSerializer will process an array just like it would process a scalar object:

XmlSerializer xs = new XmlSerializer(typeof(Vehicle[]));

Vehicle[] vehicles = new Vehicles[2];

// …

Serializer.Serialize( writer, vehicles );

A Vehicle array with the classes from the previous section serialized to XML would result in a structure like this:

<ArrayOfVehicle>

  <Vehicle xsi:type="Car">…</Vehicle>

  <Vehicle xsi:type="Motorcycle">…</Vehicle>

</ArrayOfVehicle>

The serializer added a parent node around all the elements to group all array elements, otherwise the output would not be well-formed XML. The objects inside the array were serialized just like they were in section 9.4.2, because the declared type of the array items was Vehicle, but in this case the items were of type Car and Motorcycle. If a class defines a field of an array type this parent node is not created automatically.

Customizing the XML layout for arrays

There are a number of options to customize how the XmlSerializer maps array types to XML types. Annotating a field of an array type with a plain XmlElement attribute, without a type or element name specification, causes the array elements to be serialized as direct children of the class root. No additional parent node is inserted around the items in the array. Just like we did with scalar members, we can also specify as many instances of the XmlElement attribute if we are mapping to a choice model group instead of a simple sequence.

The next listing shows a ParkingLot class with an array for two Vehicles and the XML structure of a serialized instance. Again, just like we did for a scalar Vehicle field in 9.4.3 we attach an XmlElement attribute for each type derived from Vehicle. The XML layout for this ParkingLot class is also described by a <choice> model group. In contrast to the schema in listing 9.5 the maxOccurs attribute for the group would be greater than 1.

public class ParkingLot

{

  public ParkingLot ()

  {

    Vehicles = new Vehicle[2];

  }

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

  [XmlElement(

    ElementName="ParkedMotorcycle",

    Type=typeof(Motorcycle))]

  public Vehicle[] Vehicles;

}

<ParkingLot …>

<!-- no extra element here -->

  <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>

</ParkingLot>

OK, now we know how to omit a parent element around array items and how to customize the array items themselves. But what if we want to customize element names and still want that intermediate node around the array items?

That’s what the XmlArray attribute and the XmlArrayItem attributes are for. The former creates a parent node around the array items and optionally specifies the node’s name, the latter is similar to the XmlElement attribute, but provides additional functionality specific to arrays. One use of the XmlArray attribute is mapping a field to an element like ParkedVehicles in the following schema, which can contain zero or more Vehicle elements.

<xs:complexType name="AnotherParkingLot">

  <xs:sequence>

    <xs:element minOccurs="0" maxOccurs="1" name="ParkedVehicles"

      type="ArrayOfVehicle" />

  </xs:sequence>

</xs:complexType>

<xs:complexType name="ArrayOfVehicle">

  <xs:sequence>

    <xs:element minOccurs="0" maxOccurs="unbounded" name="Vehicle"

      nillable="true" type="Vehicle" />

  </xs:sequence>

</xs:complexType>

The XmlArray attribute in combination with the XmlArrayItem attribute allows us to control the element names of the array items. The XmlArrayItem attribute also allows us to write classes mapping to more complex XSD constructs like a choice model group which can occur more than once. With a schema definition like the one below the ParkedVehicles element can contain any number of ParkedCar and ParkedMotorcycle elements in any order.

<xs:element name="BigParkingLot" nillable="true" type="BigParkingLot" />

<xs:complexType name="BigParkingLot">

  <xs:sequence>

    <xs:element minOccurs="0" maxOccurs="1" name="ParkedVehicles"

      type=" ArrayOfMixedVehicles " />

  </xs:sequence>

</xs:complexType>

<xs:complexType name="ArrayOfMixedVehicles">

  <xs:choice minOccurs="0" maxOccurs="unbounded">

    <xs:element minOccurs="1" maxOccurs="1" name="ParkedMotorcycle"

      nillable="true" type="Motorcycle" />

    <xs:element minOccurs="1" maxOccurs="1" name="ParkedCar"

      nillable="true" type="Car" />

  </xs:choice>

</xs:complexType>

The following code listing shows a class, which maps to the schema above. The

XmlArray attribute on the Vehicles field changes the name of the array’s parent node from the default Vehicles to “ParkedVehicles” as required by the schema. Since XmlElement and XmlArray attributes are mutually exclusive we have to resort to the XmlArrayItem attribute to declare the different choice particles to the XmlSerializer. We have to describe each choice particle with an XmlArrayItem attribute.

1           Listing 9.6: An application of theXmlArray attribute and the XmlArrayItem attribute

public class ParkingLot

{

  public ParkingLot ()

  {

   ParkedVehicles = new Vehicle[2];

  }

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

  [XmlArrayItem (

    ElementName="ParkedMotorcycle",

    Type=typeof(Motorcycle))]

  [XmlArray(

    ElementName="ParkedVehicles")]

  public Vehicle[] Vehicles;

}

<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>

Providing type information for array elements

The XmlSerializer needs to know about the type of all items inside an array to correctly map them to XML. If an array contains an element of a type that was not specified either by an

XmlInclude attribute or an XmlElement attribute the serializer will throw an exception. In addition to these two attributes we can declare additional types by attaching XmlArrayItem attributes with the Type property set.


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)



Information Online

swimming pool builder
chicago web site design
conference call for CA
Domain Names
it outsourcing
Emporio armani 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