Populating a DataGridView from Xml Data
Posted
Tue, Oct 20 2009 21:49
by
Deborah Kurata
If you are using XML in a WinForms application you may find the need to display the XML data in a DataGridView.
Let's take this XML:
<states>
<state name="California">
<abbreviation>CA</abbreviation>
<year>1850</year>
<governor>Schwarzenegger</governor>
</state>
<state name="Wisconsin">
<abbreviation>WI</abbreviation>
<year>1848</year>
<governor>Doyle</governor>
</state>
</states>
Displaying XML in a DataGridView sounds easy, but if you just set the DataGridView DataSource to the XML data, you will get something like this:
Notice how it has lots of yuck in it: attribute details, node properties, and so on for every node in the XML. So how do you get something more like this:
The trick is to use anonymous types.
The code is provided here in VB and C# and then described in detail below.
NOTE: Be sure to set a reference to System.Core and System.Xml.Linq
In C#:
XElement statesXml = XElement.Parse("<states>" +
"<state name='California'>" +
"<abbreviation>CA</abbreviation>" +
"<year>1850</year>" +
"<governor>Schwarzenegger</governor>" +
"</state>" +
"<state name='Wisconsin'>" +
"<abbreviation>WI</abbreviation>" +
"<year>1848</year>" +
"<governor>Doyle</governor>" +
"</state>" +
"</states>");
var query = from st in statesXml.Descendants("state")
select new
{
Name = st.Attribute("name").Value,
Abbrev = st.Element("abbreviation").Value,
Year = st.Element("year").Value,
Governor = st.Element("governor").Value
};
DataGridView1.DataSource = query.ToList();
In VB:
Dim statesXml As XElement = _
<states>
<state name="California">
<abbreviation>CA</abbreviation>
<year>1850</year>
<governor>Schwarzenegger</governor>
</state>
<state name="Wisconsin">
<abbreviation>WI</abbreviation>
<year>1848</year>
<governor>Doyle</governor>
</state>
</states>
Dim query = From st In statesXml...<state> _
Select New With { _
.Name = st.@name, _
.Abbrev = st.<abbreviation>.Value, _
.Year = st.<year>.Value, _
.Governor = st.<governor>.Value}
DataGridView1.DataSource = query.ToList
The first part of this code builds the XML. The C# code uses the XElement.Parse function to build the XML; VB uses XML literals. This part of the code is not necessary if you are reading the XML from another source, such as a file.
The second part of the code leverages Linq to XML to process the set of state XML elements. For each element, it uses the Select New syntax to create an anonymous type. The syntax defines an unnamed (anonymous) type with properties Name, Abbrev, Year, and Governor.
[To view an overview of anonymous types, start here.]
The last line converts the results of the query to a generic list and assigns it to the DataSource property of the DataGridView. Visual Studio uses the anonymous type property names as the text for the column titles and populates the rows with each state element.
Use this technique any time you have XML that you want to display in a DataGridView.
Enjoy!