BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

XML
.NET 3.0+

Controlling Serialization of XML Elements

When serializing classes to XML, each public property and field value is transformed into an XML element. The name of the element matches the name of the property. The XmlElement attribute allows the names and formatting of XML tags to be modified.

Setting an XML Schema Definition Data Type

You can define the XML schema data type for each XML element using the DataType parameter. This changes the schema for the element but does not change the format of the outputted XML. You may use any valid W3C data type for XML schemas.

[XmlElement(DataType = "string")]

Specifying Derived Types

The default settings for XML serialization can fail when working with inheritance hierarchies. If a property is declared using a base type but the property contains an object of a subclass when serialized, an exception will be thrown. We can demonstrate this by modifying our sample code. We will add a new class for employees and a subclass that represents team leaders. We will then incorporate an employee and their subordinates into the Department class.

To begin, ensure that the following using directive is present:

using System.Collections;

We can now modify the Department class and add the Employee and TeamLeader classes. Replace the existing Department class with the following:

public class Department
{
    public string Name { get; set; }
        
    public decimal Budget { get; set; }

    public Employee Contact { get; set; }
}


public class Employee
{
    public string Name { get; set; }
}


public class TeamLeader : Employee
{
    public ArrayList Subordinates { get; set; }
}

To initialise a department with an employee, replace the original data setup code with the following:

Employee bob = new Employee();
bob.Name = "Bob";

Department dept = new Department();
dept.Name = "IT";
dept.Budget = 250000M;
dept.Contact = bob;

Run the program to create the XML file. It should be similar to the following. Note that the employee object has been serialized into the Contact element.

<Department>
    <Name>IT</Name> 
    <Budget>250000</Budget> 
    <Contact>
        <Name>Bob</Name> 
    </Contact>
</Department>

The serialization works because Bob is defined as an Employee. Let's change his object so that he is a team leader. Modify the declaration of the bob variable as follows:

Employee bob = new TeamLeader();

When you run the program again an exception is thrown. If you look into the InnerException you will find that the serializer did not expect a TeamLeader object. It expected an Employee, as this is the declared type for the Contact property.

We can resolve this problem by using the XmlElement attribute's Type parameter to specify the expected types for a property. For each possible type, we can add one attribute. The class below has been modified to expect either an Employee or a TeamLeader in the Contact property:

public class Department
{
    public string Name { get; set; }
        
    public decimal Budget { get; set; }

    [XmlElement(Type = typeof(Employee))]
    [XmlElement(Type = typeof(TeamLeader))]
    public Employee Contact { get; set; }
}

When the updated class is used, the XML is as follows. Note that the Contact element is now named "TeamLeader". This gives the serializer the information needed to convert the XML into an object during deserialization.

<Department>
    <Name>IT</Name> 
    <Budget>250000</Budget> 
    <TeamLeader>
        <Name>Bob</Name> 
    </TeamLeader>
</Department>

Try resetting the bob variable to an Employee again:

Employee bob = new Employee();

Now when the object is serialized, the element name changes to "Employee".

<Department>
    <Name>IT</Name> 
    <Budget>250000</Budget> 
    <Employee>
        <Name>Bob</Name> 
    </Employee>
</Department>
25 January 2011