Logging Experiences

How to serialize DataTable and DataSet objects with YAXLib

Posted in C#, Programming, YAXLib by Sina Iravanian on October 24, 2012

YAXLib 2.x does not support serializing DataSet and DataTable objects by default. Since they have public properties of their own type, one will receive a YAXCannotSerializeSelfReferentialTypes exception. But it is quite possible to serialize them with custom serializers. Below is defined a custom serializer for DataSet:

public class DataSetCustomSerializer : ICustomSerializer<DataSet>
{
    public DataSet DeserializeFromElement(System.Xml.Linq.XElement element)
    {
        var child = element.Elements().FirstOrDefault();
        if(child == null)
            return null;
        using (var xr = child.CreateReader())
        {
            DataSet ds = new DataSet();
            var readMode = ds.ReadXml(xr);
            return ds;
        }
    }

    public void SerializeToElement(DataSet objectToSerialize, System.Xml.Linq.XElement elemToFill)
    {
        using (var xw = elemToFill.CreateWriter())
        {
            objectToSerialize.WriteXml(xw);
        }
    }

    public DataSet DeserializeFromAttribute(System.Xml.Linq.XAttribute attrib)
    {
        throw new NotImplementedException();
    }

    public DataSet DeserializeFromValue(string value)
    {
        throw new NotImplementedException();
    }

    public void SerializeToAttribute(DataSet objectToSerialize, System.Xml.Linq.XAttribute attrToFill)
    {
        throw new NotImplementedException();
    }

    public string SerializeToValue(DataSet objectToSerialize)
    {
        throw new NotImplementedException();
    }
}

And this is a custom serializer for DataTable:

public class DataTableCustomSerializer : ICustomSerializer<DataTable>
{
    public DataTable DeserializeFromElement(System.Xml.Linq.XElement element)
    {
        var dsElem = element.Elements().Where(x => x.Name.LocalName == "NewDataSet").FirstOrDefault();
        if (dsElem == null)
            return null;

        using (var xr = dsElem.CreateReader())
        {
            DataSet ds = new DataSet();
            var readMode = ds.ReadXml(xr);
            if(ds.Tables.Count > 0)
                return ds.Tables[0].Copy();
            return null;
        }
    }

    public void SerializeToElement(DataTable objectToSerialize, System.Xml.Linq.XElement elemToFill)
    {
        using (var xw = elemToFill.CreateWriter())
        {
            DataSet ds = new DataSet();
            ds.Tables.Add(objectToSerialize.Copy());
            ds.WriteXml(xw);
        }
    }

    public DataTable DeserializeFromAttribute(System.Xml.Linq.XAttribute attrib)
    {
        throw new NotImplementedException();
    }

    public DataTable DeserializeFromValue(string value)
    {
        throw new NotImplementedException();
    }

    public void SerializeToAttribute(DataTable objectToSerialize, System.Xml.Linq.XAttribute attrToFill)
    {
        throw new NotImplementedException();
    }

    public string SerializeToValue(DataTable objectToSerialize)
    {
        throw new NotImplementedException();
    }
}

Having the above custom serializers at hand, one can decorate the DataSet and DataTable properties (or fields) with the YAXCustomSerializer attribute fed with the appropriate custom serializer type, as demonstrated below:

public class DataSerializationDemo
{
    [YAXCustomSerializer(typeof(DataTableCustomSerializer))]
    public DataTable TheDataTable { get; set; }

    [YAXCustomSerializer(typeof(DataSetCustomSerializer))]
    public DataSet TheDataSet { get; set; }
}

The following provides a sample instantiation for the above class:

public static DataSerializationDemo GetSampleInstance()
{
    var dataTable = new DataTable("TableName", "http://tableNs/");
    dataTable.Columns.Add(new DataColumn("Col1", typeof(string)));
    dataTable.Columns.Add(new DataColumn("Col2", typeof(int)));
    dataTable.Columns.Add(new DataColumn("Col3", typeof(string)));

    dataTable.Rows.Add("1", 2, "3");
    dataTable.Rows.Add("y", 4, "n");

    var dataTable1 = new DataTable("Table1");
    dataTable1.Columns.Add(new DataColumn("Cl1", typeof(string)));
    dataTable1.Columns.Add(new DataColumn("Cl2", typeof(int)));

    dataTable1.Rows.Add("num1", 34);
    dataTable1.Rows.Add("num2", 54);

    var dataTable2 = new DataTable("Table2");
    dataTable2.Columns.Add(new DataColumn("C1", typeof(string)));
    dataTable2.Columns.Add(new DataColumn("C2", typeof(int)));
    dataTable2.Columns.Add(new DataColumn("C3", typeof(double)));

    dataTable2.Rows.Add("one", 1, 1.5);
    dataTable2.Rows.Add("two", 2, 2.5);

    var dataSet = new DataSet("MyDataSet");
    dataSet.Tables.AddRange(new[] { dataTable1, dataTable2 });

    return new DataSerializationDemo
    {
        TheDataTable = dataTable,
        TheDataSet = dataSet
    };
}

And the following is the XML result for serializing the above object:

<DataSerializationDemo>
  <TheDataTable>
    <NewDataSet>
      <TableName xmlns="http://tableNs/">
        <Col1>1</Col1>
        <Col2>2</Col2>
        <Col3>3</Col3>
      </TableName>
      <TableName xmlns="http://tableNs/">
        <Col1>y</Col1>
        <Col2>4</Col2>
        <Col3>n</Col3>
      </TableName>
    </NewDataSet>
  </TheDataTable>
  <TheDataSet>
    <MyDataSet>
      <Table1>
        <Cl1>num1</Cl1>
        <Cl2>34</Cl2>
      </Table1>
      <Table1>
        <Cl1>num2</Cl1>
        <Cl2>54</Cl2>
      </Table1>
      <Table2>
        <C1>one</C1>
        <C2>1</C2>
        <C3>1.5</C3>
      </Table2>
      <Table2>
        <C1>two</C1>
        <C2>2</C2>
        <C3>2.5</C3>
      </Table2>
    </MyDataSet>
  </TheDataSet>
</DataSerializationDemo>

Please note that all the above steps are provided for YAXLib 2.x, which may require slight modifications in future versions of the library.

About these ads

2 Responses

Subscribe to comments with RSS.

  1. sales techniques said, on May 31, 2013 at 3:57 pm

    Incredible! This blog looks just like my old one!
    It’s on a completely different subject but it has pretty much the same layout and design. Wonderful choice of colors!

  2. Anwar Barbouti said, on October 1, 2014 at 4:00 am

    Hey, I think your website might be having browser compatibility issues.
    When I look at your blog in Safari, it looks fine but
    when opening in Internet Explorer, it has some overlapping.

    I just wanted to give you a quick heads up!
    Other then that, excellent blog!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 53 other followers

%d bloggers like this: