Introduction
Just recently, I had the need to save the contents of a DataRow
as XML data for further processing. I looked at all the properties and methods that could be used, but nothing worked.
I couldn't find any really good solution for my problem in the different coding forums either, so I came up with my own solution.
Hopefully, it can help someone else.
Note: When running the demo, make sure to select a row in the Parent
table by clicking on the row header.
Background
In this case, I have created a DataSet
with DataTables
named Parent
, Child
and GrandChild
. The parent
table is presented in three DataGridView
s where a user can select one table and then convert that DataTable
to XML.
Using the Code
I have an example DataSet
that looks like this:
Fill the dataset
with some sample data.
DataSetExample.ParentRow parent = null;
DataSetExample.ChildRow child = null;
parent = dataSetExample.Parent.AddParentRow("Object");
child = dataSetExample.Child.AddChildRow(parent, "XmlNode");
dataSetExample.GrandChild.AddGrandChildRow(child, "XmlLinkedNode");
dataSetExample.GrandChild.AddGrandChildRow(child, "XmlDocument");
child = dataSetExample.Child.AddChildRow(parent, "Encoding");
dataSetExample.GrandChild.AddGrandChildRow(child, "ASCIIEncoding");
dataSetExample.GrandChild.AddGrandChildRow(child, "UnicodeEncoding");
dataSetExample.GrandChild.AddGrandChildRow(child, "UTF32Encoding");
parent = dataSetExample.Parent.AddParentRow("XmlLinkedNode");
child = dataSetExample.Child.AddChildRow(parent, "XmlCharacterData");
dataSetExample.GrandChild.AddGrandChildRow(child, "XmlComment");
parent = dataSetExample.Parent.AddParentRow("LocalFileSettingsProvider");
child = dataSetExample.Child.AddChildRow(parent, "ClientSettingsProvider");
dataSetExample.GrandChild.AddGrandChildRow(child, "ProfileProvider");
The code below is inside a user triggered event.
In here, I want to get all XML data for a DataTable
with a specific name. In this case, I want it as a string
.
private void buttonGetXML_Click(object sender, EventArgs e)
{
if (dgParents.SelectedRows.Count == 1)
{
DataGridViewRow dgv = dgParents.SelectedRows[0];
DataRowView drv = (dgv.DataBoundItem as DataRowView);
if (drv != null)
{
DataSetExample.ParentRow parentRow = (drv.Row as DataSetExample.ParentRow);
if (parentRow != null)
{
string xmlData = "";
using (MemoryStream ms = new MemoryStream())
{
parentRow.Table.WriteXml(ms);
byte[] data = ms.ToArray();
xmlData = ASCIIEncoding.ASCII.GetString(data);
}
XDocument xdoc = XDocument.Parse(xmlData);
XName xnDataSet = XName.Get(parentRow.Table.DataSet.DataSetName, parentRow.Table.DataSet.Namespace);
XElement xeDataSet = xdoc.Element(xnDataSet);
XName xnParent = XName.Get("Parent", parentRow.Table.DataSet.Namespace);
XName xnParentName = XName.Get("ParentName", parentRow.Table.DataSet.Namespace);
XElement xeParent = xeDataSet.Elements(xnParent).
Where(x => x.Element(xnParentName).Value == parentRow.ParentName).
FirstOrDefault();
richTextBox.Text = xeParent.ToString();
}
}
}
}
Points of Interest
I am not entirely happy with my solution. There should be an easier way.
Maybe someone else out there has done something in this area worth posting.
History
- First release
- Simplified the code and updated with a complete demo