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:

image

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:

image

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!

Filed under: , , , , , , ,

Comments

# Anonymous Types: An Introduction

Tuesday, October 20, 2009 11:56 PM by Deborah's Developer MindScape

The last several posts have provided examples of using anonymous types. This post backs up a little and

# re: Populating a DataGridView from Xml Data

Sunday, October 25, 2009 5:20 PM by Ciro

Hi Deborah!

This post help me a lot.

Thank you!

# re: Populating a DataGridView from Xml Data

Monday, November 09, 2009 12:50 PM by Kathy Carson

Thanks so much for this post!!  

It really helped me with a quick prototype I had to whip up.

Kathy

# re: Populating a DataGridView from Xml Data

Tuesday, November 17, 2009 3:40 AM by Bunzo

Hi Deborah,

Exactly what I am looking for!

Merci beaucoup pour ce post

# re: Populating a DataGridView from Xml Data

Thursday, November 19, 2009 2:29 PM by Ilber

Hi Deborah,

I have this situation:

<Root>

   <Date Value="20091118">

     <MM Title="MyTitle" Note="MyTitle1" />

   </Date>

   <Date Value="20091119">

     <MM Title="Title2"Note="Title2" />

     <MM Title="Title3" Note="Titl3" />

   </Date>

   <Date Value="2009113">

     <MM Title="Tit4" Note="Tit4" />

   </Date>

 </Root>

When in child nodes i have only one child everything goes well when i read it, but if there are more then one note my query read only the first child.

This is my query:

Dim query = From st In inXLM...<Date> _

                           Select New With { _

                           .Data = st.Attribute("Value").Value, _

                           .MM = st.<MM>.@Title, _

                           .Note = st.<MM>.@Note}

Can you help me plese.

Thanks in advance,

Ilber

Leave a Comment

(required) 
(required) 
(optional)
(required)