Database Driven XmlDataSource

C01H0047 I saw a question on Twitter a couple of days ago asking for an easy-to-use Menu control for ASP.NET.  I responded by asking what was wrong with the one that is built into ASP.NET 2.0 and above.

I never got a satisfactory answer.

The only real problem I’ve had with either the Menu control or the Tree control in .NET is that both of them expect an XMLDataSource.  But what if you want to generate the information from data in a database?

Obviously, you need to do some sort of translation.  And with the help of the XML DOM classes available in .NET, this is easy to do.

I’ll be discussing the Menu controls in this post, but the process is similar when using the Tree control.

The first thing you’ll want to do is to create a table in your database to hold the menu information.  You’ll need the following fields at a minimum:

  • ID
    Autoincrementing integer field
  • ParentID
    Points back to the record that is the parent node of this record.  If this is the top level Menu item (or Tree item) then this would be zero.
  • Label
    String representing the text to display to the user
  • URL
    String representing the URL that clicking this item will lead to.

You may also want to add:

  • Selectable
    Boolean value indicating if this item can be clicked or not
  • Target
    URL target (ie, _new, _top, or other…)
  • Sort
    Numeric Field that controls the sort order

A simple menu structure might look like:

ID ParentID Label URL
1 0 Menu One http://…
2 0 Menu Two http://…
3 1 One A http://…
4 1 One B http://…
5 1 One C http://…

Once you have the table, you’ll need an entry method to pull the data and turn it into an XMLDataSource.  Actually, you’ll need two, but the first one will look like this:

public static XmlDataSource GetNav()
    XmlDataSource returnItems = new XmlDataSource();
    returnItems.EnableCaching = false;
    returnItems.Data = "<siteMap></siteMap>";
    XmlDocument document = returnItems.GetXmlDocument();
    XmlElement sitemap = document.DocumentElement;
    FillSiteMapNode(sitemap, 0);
    returnItems.XPath = "/*/*";
    return returnItems;

Most of what this does is create the XmlDataSource object and fill it with data so that we can retrieve the XmlElement that we will need to fill with the information from our database.

The FillSiteMapNode() method is a recursive method that takes an XmlElement object and the parentId for all the child nodes.  To retrieve  the top-level menu items, we pass in zero.

Here is the actual method from one of my projects:

private static void FillSiteMapNode(
    XmlElement parentNode, int parentID)
    DataRowCollection rows =
    foreach (MainNavRow row
        in rows)
        XmlElement siteMapNode =
        // url attribute
        XmlAttribute url =
        url.Value = row.URL;
        // title attribute
        XmlAttribute title =
        title.Value = row.DisplayName;
        XmlAttribute target =
        target.Value = row.Target;
        XmlAttribute selectable =
        selectable.Value = row.Selectable.ToString();


There is a lot of code here but it is basically the same stuff repeated about five times.  All we are doing is

  1. creating a new XmlElement for each record we retrieved from the database
  2. attaching attributes to it that our Menu control is expecting
  3. adding the new XmlElement to the XmlElement that was passed into the method
  4. calling the FillSiteMapNode() again to retrieve any child nodes from the database.

You can use this same basic pattern with any code that requires an XmlDataSource.

Most Commented Post

Leave a Reply

Comment Policy:

  • You must verify your comment by responding to the automated email that is sent to your email address. Unverified comments will never show.Leave a good comment that adds to the conversation and I'll leave your link in.
  • Leave me pure spam and I'll delete it.
  • Leave a general comment and I'll remove the link but keep the comment.

Notify me of followup comments via e-mail