How to save information about DataSet into the XML when serializing it with WriteXML()
I got a question the other day. How do I serialize my dataset with some descriptive information about the meta data included?
Well, ideally we could have a property on the dataset called, for example, Description that would also be serialized. Unfortunately there isn’t.
So I came up with this simple solution.
Basically, since we are serializing to XML, why not use the XmlWriter and add, for example, our information in a XML comment?
Create a new C# console application and add the following code:
class Program
{
static void Main(string[] args)
{
// Create our demodataset.
DataSet ds = CreateDataSet();
// Need to set this if you want the retain then the XML indentation, otherwise it will be a single line.
// So it is not needed if you are not reading it 'manually'. Your call.
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
// Do the actual writing using an XmlWriter.
String xmlFile = @"C:\Temp\xmlOut.xml";
using (XmlWriter writer = XmlWriter.Create(xmlFile, settings))
{
writer.WriteComment(String.Format("\n{0}\n", GetDataSetInfo(ds)));
ds.WriteXml(writer);
}
}
private static string GetDataSetInfo(DataSet ds)
{
// Just get some informational data about the dataset, should be self explanatory.
IEnumerable<DataTable> tbls = ds.Tables.Cast<DataTable>();
int totalRows = tbls.Sum(x => x.Rows.Count);
StringBuilder sb = new StringBuilder();
sb.AppendLine(String.Format("Info for {0}", ds.DataSetName));
sb.AppendLine(String.Format("Dataset contains {0} rows in {1} tables.", totalRows, ds.Tables.Count));
sb.AppendLine("Tables:");
foreach (DataTable dt in ds.Tables)
{
sb.AppendLine(String.Format("\t{0, -10} ({1} row(s))", dt.TableName, dt.Rows.Count));
}
return sb.ToString();
}
private static DataSet CreateDataSet()
{
// Create tables
DataTable dtCustomer = new DataTable("Customer");
dtCustomer.Columns.Add(new DataColumn("CustomerId", typeof(int)));
dtCustomer.Columns.Add(new DataColumn("CustomerName", typeof(string)));
DataTable dtOrder = new DataTable("Order");
dtOrder.Columns.Add(new DataColumn("OrderId", typeof(int)));
dtOrder.Columns.Add(new DataColumn("CustomerId", typeof(int)));
dtOrder.Columns.Add(new DataColumn("CustomerName", typeof(string)));
// Add some data
dtCustomer.Rows.Add(new object[] { 1, "Mikes company" });
dtCustomer.Rows.Add(new object[] { 2, "Petes company" });
dtOrder.Rows.Add(new object[] { 1, 1, "Something of this." });
dtOrder.Rows.Add(new object[] { 2, 2, "Something of that." });
dtOrder.Rows.Add(new object[] { 3, 1, "12 of these." });
dtOrder.Rows.Add(new object[] { 4, 2, "6 of those." });
dtOrder.Rows.Add(new object[] { 5, 1, "More of this." });
DataSet ds = new DataSet("CustomerOrderDataSet");
ds.Tables.Add(dtCustomer);
ds.Tables.Add(dtOrder);
return ds;
}
}
You could remove the CreateDataSet and the GetDataSetInfo if you wish; they are only there for demonstrational purposes.
You could simply use the XmlWriter like this if all you want is to have the time and date for when the DataSet was serialized.
writer.WriteComment(String.Format("\n{0}\n", DateTime.Now.ToShortDateString()));
Anyways, if running the code above, you will have an XML file with the following content:
<?xml version="1.0" encoding="utf-8"?>
<!--
Info for CustomerOrderDataSet
Dataset contains 7 rows in 2 tables.
Tables:
Customer (2 row(s))
Order (5 row(s))
-->
<CustomerOrderDataSet>
<Customer>
<CustomerId>1</CustomerId>
<CustomerName>Mikes company</CustomerName>
</Customer>
<Customer>
<CustomerId>2</CustomerId>
<CustomerName>Petes company</CustomerName>
</Customer>
<Order>
<OrderId>1</OrderId>
<CustomerId>1</CustomerId>
<CustomerName>Something of this.</CustomerName>
</Order>
<Order>
<OrderId>2</OrderId>
<CustomerId>2</CustomerId>
<CustomerName>Something of that.</CustomerName>
</Order>
<Order>
<OrderId>3</OrderId>
<CustomerId>1</CustomerId>
<CustomerName>12 of these.</CustomerName>
</Order>
<Order>
<OrderId>4</OrderId>
<CustomerId>2</CustomerId>
<CustomerName>6 of those.</CustomerName>
</Order>
<Order>
<OrderId>5</OrderId>
<CustomerId>1</CustomerId>
<CustomerName>More of this.</CustomerName>
</Order>
</CustomerOrderDataSet>
As simple as that.
There may better ways for your needs, but this is a quick and dirty solution to get meta information into the serialized XML if this is what you wish to do.