Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  Data Programming  »  XML  »  Searching an XML Document Using a DataSet and DataView
 »  Home  »  Web Development  »  Searching an XML Document Using a DataSet and DataView
Searching an XML Document Using a DataSet and DataView
by Chris Scott | Published  10/23/2002 | XML Web Development | Rating:
Chris Scott

Chris Scott is the founder of Host Orlando (www.hostorlando.com) a Web hosting and development company in Orlando, FL specializing in Microsoft technologies. Whether he was providing technical support for end users, managing networks, or working as a consultant, Chris has always been writing code and scripts to get his job done.

A self-taught programmer, Chris started getting serious about coding three years ago and learned ASP, T-SQL, and JavaScript to supplement his experience with Visual Basic, databases, and shell scripting. He is now focusing on writing Web applications in ASP.NET and is currently working on finishing a transition of his company's customer management system from classic ASP to ASP.NET.

 

View all articles by Chris Scott...
Searching an XML Document Using a DataSet and DataView

Sometimes you need the basic features of a database but don't want the hassle, and possibly cost, of creating one for a small application. With the .NET DataSet object and a simple XML document we can emulate the basic features of a database. In this example, we use an XML document which stores our product information. We want to look up a product by SKU and return the price and description to a Web page.

We have three products in our list. The following is a basic XML document, productlist.xml, containing our data:

<?xml version="1.0" encoding="utf-8" ?>
<ProductList>
<Products>
    <SKU>1</SKU>
    <Price>100.00</Price>
    <Description>Widget #1</Description>
</Products>
<Products>
    <SKU>2</SKU>
    <Price>10.00</Price>
    <Description>Widget #2</Description>
</Products>
<Products>
    <SKU>3</SKU>
    <Price>30.00</Price>
    <Description>Widget #3</Description>
</Products>
</ProductList>

If you think of this document in terms of a database, the data within the ProductList tags are our database. The data within the Products tags are a table in the database. SKU, Price, and Descriptions are columns in the Products table. Just like a database, we want to return a row of values, given a column value.

First, we need to read our XML document into something that .NET can use. This is very easy to do with the DataSet object's ReadXml method. By using a DataSet, we can treat our data like a database. Also, compared to using the .NET XML objects, the DataSet results in less code and complexity.

All we need to do is create a new DataSet and tell it to read our XML document into it:

DataSet dsProducts = new DataSet();
dsProducts.ReadXml(Server.MapPath("productlist.xml"));

The ReadXml method is passed the file name of the XML file to read. This example assumes that the file is named productlist.xml and is located in the same directory as the page using it.

Now that we have our data in a DataSet, we need to be able to query it for an SKU and return the Price and Description for the corresponding product. To do this, we will use a DataView object:

DataView dvProducts = new DataView(dsProducts.Tables["Products"]);
dvProducts.Sort = "SKU";

The DataView is created by passing the constructor a DataTable, "Products", in our DataSet. After we create the DataView, we need to sort it. Since we are using the SKU as the lookup value, we need to sort on it. This is similar to an index or primary key in a database. If we don't sort the DataView, we will get a runtime error when we try to use it's Find method.

With our DataView sorted, use the Find method to return only the row(s) which match the SKU we give it. In this example, we want to return the Price and Description for a product with a SKU equal to 1:

int rowIndex = dvProducts.Find("1");
string Price, Description;

if (rowIndex == -1)
{
    // The SKU was not found in our data
    Response.Write("SKU not found");
}
else
{
    Price = dvProducts[rowIndex]["Price"].ToString();
    Response.Write("Price: " + Price + "<br>";
    // Price: 100.00

    Description = dvProducts[rowIndex]["Description"].ToString();
    Response.Write("Description: " + Description);
    // Description: Widget #1
}

The Find method of a DataView returns and int which is the index of the row in the DataView containing the sort key value passed to it. If there is no match, it returns -1.

That's all there is to it. For simple uses, this method of storing and retrieving information may be much easier than using a database, however, there are a few things you should keep in mind. First, our simple XML document stores all data as text strings. This isn't too much of a problem since we can use the .NET data types to parse our string data to other types like integer and datetime, but remember when you pass the key value to the Find method that it needs to be a string. Second, if we only want one "row" of data returned for a lookup key, we need to ensure that we don't duplicate the key in our XML document--in a database we could easily enforce this by setting the column to be an identity column.

If you are using this method in a busy ASP.NET application where you have a relatively small amount of data and your data doesn't change too often, you may want to store the DataSet object in cache so the XML document doesn't need to be read and parsed for each request. Use a CacheDependency on the XML file to ensure that the cache is expired when the document is updated.

Download the following for complete code in a console application:

using System;
using System.Data;

namespace productsxml
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class main
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            //
            // TODO: Add code to start application here
            //

            DataSet dsProducts = new DataSet();
            dsProducts.ReadXml("productlist.xml");

            DataView dvProducts = new
            DataView(dsProducts.Tables["Products"]);
            dvProducts.Sort = "SKU";

            int rowIndex = dvProducts.Find("1");
            string Price, Description;

            if (rowIndex == -1)
            {
                // The SKU was not found in our data
                Console.WriteLine("Product Not found");
            }
            else
            {
                Price = dvProducts[rowIndex]["Price"].ToString();
                Console.WriteLine("Price: " + Price);
                // Price: 100.00

                Description = dvProducts[rowIndex]
                ["Description"].ToString();
                Console.WriteLine("Description: " + Description);
                // Description: Widget #1
            }
        }
    }
}
How would you rate the quality of this article?
1 2 3 4 5
Poor Excellent
Tell us why you rated this way (optional):

Article Rating
The average rating is: No-one else has rated this article yet.

Article rating:4.31428571428569 out of 5
 35 people have rated this page
Article Score24255
Comments    Submit Comment

Comment #1  (Posted by Leonardo Garraza on 10/05/2004)

Great article!! thanks
 
Comment #2  (Posted by bobo on 02/07/2005)

Can you include attributes in this example
 
Comment #3  (Posted by an unknown user on 02/23/2005)
Rating
the article is very clear written and and fullfill my queary.
 
Comment #4  (Posted by an unknown user on 02/28/2005)
Rating
that was excellent
 
Comment #5  (Posted by an unknown user on 04/20/2005)
Rating
I would recommend changing your database analogy for the tags as such.

ProductList = table
Products = record
SKU, Price & Description = fields
 
Comment #6  (Posted by an unknown user on 05/01/2005)
Rating
clear, simple - GREAT
 
Comment #7  (Posted by an unknown user on 05/23/2005)
Rating
This article is excellent. It is exactly what I was looking for.
 
Comment #8  (Posted by an unknown user on 06/23/2005)
Rating
Very simple and exactly what I was looking for.
 
Comment #9  (Posted by an unknown user on 08/22/2005)
Rating
very clean and nice article
 
Comment #10  (Posted by an unknown user on 08/23/2005)
Rating
GREAT!!!!
Although its write as Javascript but it still help me alot...
it's not much work for me to change it to asp.net version
 
Comment #11  (Posted by an unknown user on 10/25/2005)
Rating

 
Comment #12  (Posted by an unknown user on 10/28/2005)
Rating
Thanks a lot@#$%&^&*()
 
Comment #13  (Posted by an unknown user on 03/21/2006)
Rating
Flawless!!
 
Comment #14  (Posted by an unknown user on 05/30/2006)
Rating
simple and useful! Cheers!
 
Comment #15  (Posted by an unknown user on 06/15/2006)
Rating
Hmm. I am running this (trying to) in a c# windows app. It will not work. I am getting and unhandled exception at: int rowIndex = dvProducts.Find("1"); It says DataTable must be set prior to using DataView. Any ideas?
 
Comment #16  (Posted by an unknown user on 06/15/2006)
Rating
Hmm. I am running this (trying to) in a c# windows app. It will not work. I am getting and unhandled exception at: int rowIndex = dvProducts.Find("1"); It says DataTable must be set prior to using DataView. Any ideas?
 
Comment #17  (Posted by an unknown user on 09/29/2006)
Rating
Simple and straight-forward. Thanks!
 
Comment #18  (Posted by an unknown user on 10/06/2006)
Rating
Clear & concise! Excellent
 
Comment #19  (Posted by an unknown user on 11/28/2006)
Rating
"DataTable must be set prior to using DataView" Means the datatable does not exist. i.e. DataView dvProducts = new DataView(dsProducts.Tables["Products"]);

Should read as:
DataView dvProducts = new DataView(dsProducts.Tables[0]);

 
Comment #20  (Posted by an unknown user on 04/13/2007)
Rating
First rate article, exactly what I wanted.
 
Comment #21  (Posted by an unknown user on 11/25/2007)
Rating
You hammered right to the Marrow!!!
 
Comment #22  (Posted by an unknown user on 12/03/2007)
Rating
excellent article !!!
 
Comment #23  (Posted by an unknown user on 01/17/2008)
Rating
Instead of this:









maybe I will change the format of my XML, it could be easier to use!?
 
Comment #24  (Posted by an unknown user on 01/17/2008)
Rating
Instead of this:
< Productlist>
< Product>
< Item SKU="1" Price="100" Description="Widget1" />
< /Product>
< Product>
< Item SKU="2" Price="110" Description="Widget2" />
< /Product>
< /Productlist>

maybe I will change the format of my XML, it could be easier to use!?
 
Comment #25  (Posted by an unknown user on 03/02/2008)
Rating
very usefull article. thanks dude
 
Comment #26  (Posted by an unknown user on 06/27/2008)
Rating
Thanks for a easy to understand practical article
 
Comment #27  (Posted by an unknown user on 08/22/2008)
Rating
Hi this is Naresh. this article is very use full for me.
 
Sponsored Links