How to Bind Nested XML to a Repeater Control with Container.DataItem

Introduction

The container.DataItem is an easy-to-use method to bind XML to a control. You can use a repeater, list control, or any other control to bind the XML. If you have have worked with XML and a repeater control, you know what I am talking about. In this short "how to," I will show you how you can bind a nested XML element to a repeater control. But, first of all, let's see an example where we bind a simple XML to a repeater control.

Simple Data Binding

This is a very famous and simple method to retrive data with container.DataItem.

XML file

<?xml version="1.0" encoding="utf-8"?>
<CategoryList>
   <Category>
      <MainCategory>XML</MainCategory>
      <SubCategory>Basic</SubCategory>
      <Description>List of XML articles.</Description>
      <Active>Yes</Active>
   </Category>
</CategoryList>

Code

DataSet ds = new DataSet();
ds.ReadXml(MapPath("myfile.xml"));
rpMyRepeater.DataSource=ds;
rpMyRepeater.DataBind();

Now, let me show you how to use ASP.NET to retrieve the data from XML.

<asp:repeater id="rpMyRepeater" runat="server">
<HeaderTemplate>
   <Table border="0">
</HeaderTemplate>
   <ItemTemplate>
   <tr style="background-color:FFECD8">
      <td>
         <%# DataBinder.Eval(Container.DataItem, "MainCategory") %>
         <%# DataBinder.Eval(Container.DataItem, "Description") %>
      </td>
   </tr>
   </ItemTemplate>
   <FooterTemplate>
      </Table>
   </FooterTemplate>
</asp:repeater>

As you can see, you don't need much code to bind the XML. Unfortunately, this method works only if you have am XML structure such as the one shown above. So, how do you use the Container.DataItem to retrieve attributes? Let us change our XML file a little bit.

New XML file

<?xml version="1.0" encoding="utf-8"?>
<CategoryList>
   <Category>
      <MainCategory ID="1">XML</MainCategory>
      <SubCategory>Basic</SubCategory>
      <Description>List of XML articles.</Description>
      <Active>Yes</Active>
   </Category>
</CategoryList>

When you run the above code with the new XML file, you will see that this time it throws the following exception:

System.Web.HttpException: DataBinding: 'System.Data.DataRowView'
does not contain a property with the name 'MainCategory'.

The problem is that you now are using an attribute in the XML file; therefore, you can not use the above code. Now, let us try to retrieve the ID and the MainCategory element's value. For that purpose, you will need to change a little bit of the code. Your new code should look like this:

XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("dbase/categories.xml"));
XmlNodeList nodes =
   doc.SelectNodes("CategoryList/Category/MainCategory");
rpMyRepeater.DataSource = nodes;
rpMyRepeater.DataBind();

This time, we are not using a dataset to load the XML file. Instead, we will have to load the XML file into a XmlDocument and use the SelectNodes method to retrieve the nodes. The nodes then are passed to the repeater control. And, here is the trick to get the XML data with Container.DataItem.

<asp:repeater id="rpMyRepeater" runat="server">
<HeaderTemplate>
   <Table border="0">
</HeaderTemplate>
   <ItemTemplate>
   <tr style="background-color:FFECD8">
      <td>
         <%#((System.Xml.XmlNode)Container.DataItem).
             Attributes["ID"].Value %>
         <%#((System.Xml.XmlNode)Container.DataItem).InnerText%>
      </td>
   </tr>
   </ItemTemplate>
   <FooterTemplate>
      </Table>
   </FooterTemplate>
</asp:repeater>

I would like to thank Kirk Allen Evan for this great tip. See his blog entry about that: http://blogs.msdn.com/kaevans/archive/2003/07/04/9713.aspx.



About the Author

Sonu Kapoor

Sonu Kapoor is an ASP.NET MVP and MCAD. He is the owner of the popular .net website http://dotnetslackers.com. DotNetSlackers publishs the latest .net news and articles - it contains forums and blogs as well. His blog can be seen at: http://dotnetslackers.com/community/blogs/sonukapoor/