Controlling serialization with the help of attributes

The main reason we want to have control over the XML serialization is when we need to conform to certain standard and our XML generated from the class does not match requirements of the standard. In this case we’ll have to control how our XML file is created with the help of attributes.

AttributeSpecifies
XmlAnyAttribute Fills XmlAttribute objects
XmlAnyElement Fills with XmlElement objects
XmlArrays Generates XML Array
XmlArrayItem The derived types that can be inserted into an array
XmlAttribute The member will be serialized
XmlChoiceIdentifier The member can be further disambiguated
XmlElement The field or property will be serialized
XmlEnum Name of an enumeration member
XmlIgnore The property or field should be ignored
XmlInclude The class should be included
XmlRoot Sets XML serialization of the attribute target
XmlText The property or field should be serialized
XmlType The name and namespace

By applying these attributes to our class we can better control how end result XML will be displayed.
[XmlRoot ("CartItem")]
public class MyShoppingCartItem
{
    [XmlAttribute] public Int32 myProductId;
    public decimal myPrice;
    public Int32 myQuantity;
    [XmlIgnore] public decimal myTotal;

    public MyShoppingCartItem()
    {
    }
}

This would result in the following XML file, which meets the specified requirements:
<?xml version="1.0" ?>
<CartItem productId="100">
    <price>10.25</price>
    <quantity>2</quantity>
</CartItem>

We can go one step further by employingIXmlSerializable interface.

Many times you will not have to write your own attributes for the class, but rather create classes from the schema which is document created to standardize the way end result XML is being rendered. In order to produce set of class off the XML schema we’ll be using XML schema definition tool Xsd.exe resulted classes will be strongly typed to the schema with proper attributes and etc… In order to create such set of classes all we need is to run this line of code from .NET command line:

xsd C:\schema\library.xsd /classes /language:CS

Important to remember that then we get unknown node in our XML stream, we should use UnknownNode event. List of events are

  • UnknownAttribute Event
  • UnknownElement Event
  • UnknownNode Event
  • UnreferencedObject Event

Besides classes we can serialize DataSets, Arrays, Collection and Instances. We can simply do it with the methods like the DataSet.WriteXml, DataSet.ReadXML, and DataSet.GetXml
private void MySerializeDataSet(string myfilename)
{
    XmlSerializer ser = new XmlSerializer(typeof(DataSet));

    // Creates a DataSet; adds a table, column, and ten rows.
    DataSet myDS = new DataSet("myDataSet");
    DataTable myT = new DataTable("table1");
    DataColumn c = new DataColumn("thing");
    myT.Columns.Add(c);
    myDS.Tables.Add(myT);
    DataRow r;
    for(int i = 0; i<10;i++){
        r = myT.NewRow();
        r[0] = "Thing " + i;
        myT.Rows.Add(r);
    }
    TextWriter myWriter = new StreamWriter(myfilename);
    ser.Serialize(myWriter, myDS);
    myWriter.Close();
}