Search This Site With Live Search

Welcome to MSDN Blogs Sign in | Join | Help

Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

As I mentioned in my previous blog post about binding, any object that supports IEnumerable can be used as the DataSource for data binding in ASP.NET.  If you are processing XML, the XmlDocument class does not support IEnumerable (after all, it is a tree, not a list).  You can, however, bind to a set of nodes within an XML document, and use ASP.NET data binding to navigate through the rest of the document.

Suppose we have the XML document:

<Projects iProjectID ="13" vProjectName ="Plumber's Project" >
<Packages iPackageID ="36" vPackageName ="Bowser" >
<Modules iModuleID ="76" vModuleName ="Bob-omb Module" />
</Packages>
<Packages iPackageID ="40" vPackageName ="Princess" >
<Modules/>
</Packages>
</Projects>

We can select a set of nodes (called a node list) using XPath statements and the SelectNodes method of the XmlNode class. XmlNode.SelectNodes returns an object called an XmlNodeList, and this object is a collection that supports IEnumerable.  XmlNodeList, then, can be used as the DataSource for an ASP.NET data bound control.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace ExampleWeb
{
  public class DataBindtoNodeSet : System.Web.UI.Page
  {
    protected System.Web.UI.WebControls.DataList DataList1;
  
    private void Page_Load(object sender, System.EventArgs e)
    {
      XmlDocument doc = new XmlDocument();
      doc.Load(Server.MapPath("data/xmlfile1.xml"));
      XmlNodeList nodes = doc.SelectNodes("Projects/Packages");
      
      DataList1.DataSource = nodes;
      DataList1.DataBind();
    }

    #region Web Form Designer generated code

    override protected void OnInit(EventArgs e)
    {
      InitializeComponent();
      base.OnInit(e);
    }
    
    private void InitializeComponent()
    {
      this.Load += new System.EventHandler(this.Page_Load);

    }
    #endregion

  }
}

You can see that the code-behind is really simply, the work is done in the Page_Load event.  We use the SelectNodes method to retrieve an XmlNodeList, and use that as the DataSource for our ASP.NET DataList control.

Here is the .aspx view of the code.

<%@ Page language="c#" Codebehind="DataBindtoNodeSet.aspx.cs" AutoEventWireup="false" Inherits="ExampleWeb.DataBindtoNodeSet" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>DataBindtoNodeSet</title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name="vs_defaultClientScript" content="JavaScript">
    <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
  </HEAD>
  <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
      <asp:DataList id="DataList1" style="Z-INDEX: 101; LEFT: 256px; POSITION: absolute; TOP: 144px"
        runat="server">
        <ItemTemplate>
          <h1><%# ((System.Xml.XmlNode)Container.DataItem).Attributes["iPackageID"].Value %></h1>
        </ItemTemplate>
        </asp:DataList>
    </form>
  </body>
</HTML>

The real work here is done in the ItemTemplate, specifically where we use the special binding syntax (<%# ... %>) for ASP.NET.  The Container.DataItem property is pointing at the current thing in the IEnumerable object being bound to.  XmlNodeList is a collection of XmlNode references, so Container.DataItem will point to a single XmlNode object reference.  So, we cast Container.DataItem to an XmlNode type, after which we can access the DOM methods of the XmlNode object.  In this example, we use the Attributes collection.

Published Friday, July 04, 2003 4:21 PM by kaevans

Comments

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Friday, July 04, 2003 9:06 PM by Datagrid Girl
Great tip!!

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Monday, July 07, 2003 1:10 PM by Phil
cool! Is anyone working on an advanced ASP.NET tips & tricks?

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Monday, July 07, 2003 1:45 PM by Kirk Allen Evans
I am working on a series of articles for the ASPAlliance that will explain a lot of the innards of ASP.NET. What types of information would you like to see?

You might want to check out the ASP.NET Developer's Cookbook by Steven Smith, Rob Howard, and assorted folks from the ASPAlliance.

http://www.amazon.com/exec/obidos/tg/detail/-/0672325241

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Thursday, October 30, 2003 12:01 PM by Zinx
In the above example how to access the iModuleID ?

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Thursday, October 30, 2003 8:11 PM by Kirk Allen Evans
Since you are positioned on an XmlNode named "Packages", you could use an XPath statement to retrieve it.

<%# ((System.Xml.XmlNode)Container.DataItem.SelectSingleNode("Modules/@iModuleID").Value %>

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Tuesday, November 18, 2003 3:55 PM by Keith
How would you do this part in vb.net, specifically for an element?

<%# ((System.Xml.XmlNode)Container.DataItem).Attributes["iPackageID"].Value %>

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Tuesday, November 18, 2003 4:24 PM by Keith
Nevermind, got it:

<%#(Ctype(Container.DataItem, System.Xml.XmlNode))("ElementName").InnerText %>

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Wednesday, January 28, 2004 9:48 AM by Aleksandar Naumovic
What about DropDownList and other controls derived from ListControl? Could you bind IEnumerable data source to them?

# Binding External XML to a Dropdown List

Thursday, January 29, 2004 12:47 PM by Kirk Allen Evans' XML Blog

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Sunday, February 08, 2004 4:50 PM by Ronson X
I get this
'XmlNode' is a type in 'Xml' and cannot be used as an expression

help

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Sunday, February 08, 2004 5:00 PM by Kirk Allen Evans
You most likely forgot to access a property of the node, like ".Value" or ".Name". The code posted above, verbatim, works.

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Sunday, February 08, 2004 7:41 PM by Ronson X
I made a mistake too embarrasing to admit here, in public. It would be a grave dishonor to my family name.

Well, ok, I forgot to specify c# as the page language. apparently the default is vb.

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Sunday, February 08, 2004 9:00 PM by David Mangol
In this example, what is the best way to retrieve childnodes of the path:

doc.SelectNodes("Projects/Packages");

would you call methods of XmlNode within the aspx, or call selectNodes(...) with a path to the childnodes, and then bind it to another DataList?

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Sunday, February 08, 2004 9:51 PM by Kirk Allen Evans
I would use the latter, for simplicity. I think it would be possible to construct an elaborate binding expression for a child binding, but I think the complexity would be difficult to effectively maintain.

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Tuesday, February 17, 2004 12:35 PM by Martin Beed
Great article... just what I was looking for! However, if you're using XMLElements rather than attributes for the Modules data, you may find the following useful:

<%# ((System.Xml.XmlNode)Container.DataItem)["iModuleID"].InnerText %>

<%# ((System.Xml.XmlNode)Container.DataItem)["vModuleName"].InnerText %>

Which will work with the following XML:

<Projects iProjectID ="13" vProjectName ="Plumber's Project" >
<Packages iPackageID ="36" vPackageName ="Bowser" >
<Modules>
<iModuleID>76</iModuleID>
<vModuleName>Bob-omb Module</vModuleName>
</Modules>
</Packages>
<Packages iPackageID ="40" vPackageName ="Princess" >
<Modules>
<iModuleID></iModuleID>
<vModuleName></vModuleName>
</Modules>
</Packages>
</Projects>

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Thursday, February 26, 2004 1:58 PM by mk
Thanks for the tip , very useful

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Tuesday, March 09, 2004 2:48 PM by chacha
nice.

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Tuesday, March 09, 2004 4:19 PM by chacha
chacha,

FYI,

YOUR example works great, but I found some problems using xmlnamespaces with M$'s xmlnamespacemanager class. No errors, just no matches when I used a predicate. I got rid of the namespace prefixes in my xml and ditched the xmlnamespacemanager object and it worked great.

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Tuesday, March 09, 2004 4:39 PM by Kirk Allen Evans
chacha,
Care to post what the problem could have been? I have never had a problem using the XmlNamespaceManager class, and have used it many times. Instead of altering the source XML document, you might also consider using XPath statements such as:

/*[local-name()='foo']/*[local-name()='bar]

This would find the "bar" element in the following document:

<foo xmlns="urn:xmladvice.com:examples">
<bar>Here is your value</bar>
</foo>

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Sunday, April 04, 2004 5:13 PM by Mark Dicken
Kirk,

In VB.NET I've managed to sucessfully create a 3 tier catagory system. Everything works great when your dealing with data at the same XML Node Level.

ALTHOUGH ... HOW can I reference a 'Parent Node' Attribute (e.g. Level 2 Data) whilst within (e.g. Level 3 Data)

Please can you help me fill in the missing blank ('*** ???CountryName??? ***') on line 17

1 Sample with line numbers the other sample without line numbers

START
01) <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="hdb_vb.WebForm1"%>
02) <%@ Import Namespace="System.Xml" %>
03) <HTML>
04) <body>
05) <form runat="server" ID="Form1">
06) <h2>Hierarchical databinding test with XmlNode</h2>
07) <asp:Repeater id="_rep1" runat="server">
08) <itemTemplate>
09) AAA:<%# (Ctype(Container.DataItem, System.Xml.XmlNode)).Attributes("WorldRegionName").Value %><br>
10) <asp:Repeater runat="server" DataSource='<%# Container.DataItem %>' ID="Repeater1">
11) <itemTemplate>
12) &nbsp;&nbsp;Author:
13) <%# (Ctype(Container.DataItem, System.Xml.XmlNode)).Attributes("CountryName").Value %>
14) <br />
15) <asp:Repeater runat="server" DataSource='<%# Container.DataItem %>' ID="Repeater2">
16) <itemTemplate>
17) &nbsp;&nbsp;&nbsp;&nbsp;<i><a href='<%# *** ???CountryName??? *** %>'><%# (Ctype(Container.DataItem, System.Xml.XmlNode)).Attributes("CountryMajorCityName").Value %></a></i><br />
18) </itemTemplate>
19) </asp:Repeater>
20) </itemTemplate>
21) </asp:Repeater>
22) <hr />
23) </itemTemplate>
24) </asp:Repeater>
25) </form>
26) </body>
27)</HTML>
FINISH

The same above except no line numbers ...


<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="hdb_vb.WebForm1"%>
<%@ Import Namespace="System.Xml" %>
<HTML>
<body>
<form runat="server" ID="Form1">
<h2>Hierarchical databinding test with XmlNode</h2>
<asp:Repeater id="_rep1" runat="server">
<itemTemplate>
AAA:<%# (Ctype(Container.DataItem, System.Xml.XmlNode)).Attributes("WorldRegionName").Value %><br>
<asp:Repeater runat="server" DataSource='<%# Container.DataItem %>' ID="Repeater1">
<itemTemplate>
&nbsp;&nbsp;Author:
<%# (Ctype(Container.DataItem, System.Xml.XmlNode)).Attributes("CountryName").Value %>
<br />
<asp:Repeater runat="server" DataSource='<%# Container.DataItem %>' ID="Repeater2">
<itemTemplate>
&nbsp;&nbsp;&nbsp;&nbsp;<i><a href='<%# *** ???CountryName??? *** %>'><%# (Ctype(Container.DataItem, System.Xml.XmlNode)).Attributes("CountryMajorCityName").Value %></a></i><br />
</itemTemplate>
</asp:Repeater>
</itemTemplate>
</asp:Repeater>
<hr />
</itemTemplate>
</asp:Repeater>
</form>
</body>
</HTML>


Many Thanks In Advance...

Regards

Mark Dicken

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Tuesday, April 13, 2004 6:24 PM by Hugo
Hi, Iam trying to do this with a Repeater control but it does'nt work, the next error is returned to me
System.NullReferenceException: Object reference not set to an instance of an object.
I dont't know wy Visual Studio Return this error, i put all the necesary references but it does'nt work.
Can you help me please

# Bind a Nested Xml to a Repeater Control with Container.DataItem

Monday, May 10, 2004 1:56 PM by Sonu Kapoor's WebLog

# Bind a Nested Xml to a Repeater Control with Container.DataItem

Tuesday, May 11, 2004 1:37 PM by Sonu Kapoor's WebLog

# Not Being Rude, But...

Wednesday, May 19, 2004 6:57 PM by Kirk Allen Evans' Blog

# How to bind a nested xml to a repeater control with Container.DataItem?

Wednesday, May 19, 2004 7:06 PM by Sonu Kapoor's WebLog

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

Wednesday, May 19, 2004 7:20 PM by Sonu Kapoor's WebLog

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Friday, June 25, 2004 9:22 AM by Melih Gümüşçay
Great Tip this i was looking for hours thank you

# re: Use ASP.NET Data Binding to Bind Directly to XML (sans DataSet)

Friday, July 16, 2004 7:43 AM by Mark
Hi,
Like Hugo, I can't get the VB to work in my app:
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:


Line 23: <ItemTemplate>
Line 24: <TR>
Line 25: <TD><%# (CType(Container.DataItem, System.Xml.XmlNode))("tab").InnerText %></TD>
Line 26: </TR>
Line 27: </ItemTemplate>


If I use CType(Container.DataItem, System.Xml.XmlNode)) the code compiles by my repeater is (understandably) empty.

Can anyone help?

Thanks

Mark

# OK and now with a Drop Down Listbox??

Monday, July 19, 2004 7:39 AM by M. de Groot
Thanks for al the information. But I want to bind to a DropDownListbox. This seems to be very different, because a DropDownListbox doesn't have a DataItem to convert from...
Does anyone have a clue (in VB perhaps...)

Thank you!

# Kirk Allen Evans&#8217;s Blog : Use ASP.NET Data Binding to Bind Directly to &#8230; at Restaurants

New Comments to this post are disabled
 
Page view tracker