This tutorial shows an alternative to using a database - using LINQ to retrieve data from an XML file and also how to filter data from XML. C# version.
Download the Full Working Version of this Project written with Visual Studio.NET 2008 Here!
Looking for more .NET Database Tutorials? Click Here!
Microsoft's new LINQ implementation into the .NET Framework 3.5 makes you look at DataSources in a different way. Not only can you use LINQ to handle databases more easily, it also allows for you to communicate more easily with XML documents and even ASP.NET Controls. In this tutorial, we will look at using an XML document in place of a database. We will see how LINQ makes it easy for us to interact with an XML document, and not only retrieve the data it holds, but also filter the data to retrieve the data that we really want.
We can start off by opening a new project in Visual Studio .NET 2008. If you are using 2005, you can still take advantage of LINQ, but will need to installed the LINQ Preview, which is available from the Microsoft website free of charge.
The first thing we will do is add the namespaces we will be using. Our code-behind will look something like this:
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Xml;
|
The next thing we will do is add an XML file to our project, and create some sample data. If you have your own existing XML file, then great, but for this example, we are going to use the following XML:
<?xml version="1.0" encoding="utf-8" ?>
<Persons>
<Person>
<Name>Paxton</Name>
<City>Munich</City>
<Age>29</Age>
</Person>
<Person>
<Name>Mike</Name>
<City>Orlando</City>
<Age>33</Age>
</Person>
<Person>
<Name>Ella</Name>
<City>LA</City>
<Age>13</Age>
</Person>
<Person>
<Name>Ingrid</Name>
<City>Oslo</City>
<Age>63</Age>
</Person>
</Persons>
|
We are going to use this data to display on our ASPX page, and also filter through the data. We will allow the user to specify the data they want to see through the use of a DropDownList - we will let the user filter the data by City. But first, we need to create our Controls. To our ASPX page, we will add a button and a Literal Control. When clicked, the button will retrieve the XML data and display it in the Literal Control. Our ASPX page with these added will look something like this:
|
<asp:Button ID="butGetXML" runat="server" Text="Get All XML"
onclick="butGetXML_Click" /><br /><br />
<asp:Literal ID="litXMLData" runat="server"></asp:Literal>
|
We have defined a handler for the click event of this button, and the code-behind will look something like this:
protected void butGetXML_Click(object sender, EventArgs e)
{
XDocument xmlDoc = XDocument.Load(Server.MapPath("XMLFile.xml"));
var persons = from person in xmlDoc.Descendants("Person")
select new
{
Name = person.Element("Name").Value,
City = person.Element("City").Value,
Age = person.Element("Age").Value,
};
litXMLData.Text = "";
foreach (var person in persons)
{
litXMLData.Text = litXMLData.Text + "Name: " + person.Name + "<br />";
litXMLData.Text = litXMLData.Text + "City: " + person.City + "<br />";
litXMLData.Text = litXMLData.Text + "Age: " + person.Age + "<br /><br />";
}
if (litXMLData.Text == "")
litXMLData.Text = "No Results.";
}
|
This block of code will retrieve the data from the XML file and input it into the Literal Control. If there is no data in the XML file, the user will be notified. We are using LINQ in this method, notice how it is similar to SQL Statement - we are using a SELECT keyword, as well as the FROM keyword, except it is the opposite way round to SQL. LINQ is relatively logical in this way, as we are simply selecting the values of Name, City and Age elements of the XML file. We then loop through the data and output it to the Literal Control. This should now be functional in that if we run it, we will be able to extract all the data from the XML file when the button is clicked. However, we want more functionality than this. We will now add a DropDownList to our ASPX page and populate it with the data from the XML file - we will only want the City nodes, though. Our ASPX page will now look something like this:
|
<asp:Button ID="butGetXML" runat="server" Text="Get All XML"
onclick="butGetXML_Click" /><br /><br />
Filter data by City:<br />
City: <asp:DropDownList ID="ddlCity" runat="server">
</asp:DropDownList><br />
<asp:Button ID="butFilterXML" runat="server" Text="Filter XML"
onclick="butFilterXML_Click" /><br /><br />
<asp:Literal ID="litXMLData" runat="server"></asp:Literal>
|
We have now added a DropDownList and another button. The user will be able to select a City from the DropDownList and then click the button to see data matching his request. Now we need to populate the DropDownList. We will do this on Page Load:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
loadDDL();
}
protected void loadDDL()
{
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("XMLFile.xml"));
XmlNodeList nodeList = doc.SelectNodes("Persons/Person");
foreach(XmlNode node in nodeList)
ddlCity.Items.Add(new ListItem(node.SelectSingleNode("City").InnerText));
}
|
Upon Page Load, the method will be called if the page is not posted back. The method retrieves only the City node within the XML file and adds each item to the DropDownList. This means the user can now select any City that is in the XML file. Next, we need to add the logic to filter the XML data by the user's selection. We will do this on the Filter Button Click event:
protected void butFilterXML_Click(object sender, EventArgs e)
{
XDocument xmlDoc = XDocument.Load("XMLFile.xml");
var persons = from person in xmlDoc.Descendants("Person")
where person.Element("City").Value == ddlCity.SelectedItem.ToString()
select new
{
Name = person.Element("Name").Value,
City = person.Element("City").Value,
Age = person.Element("Age").Value,
};
litXMLData.Text = "";
foreach (var person in persons)
{
litXMLData.Text = litXMLData.Text + "Name: " + person.Name + "<br />";
litXMLData.Text = litXMLData.Text + "City: " + person.City + "<br />";
litXMLData.Text = litXMLData.Text + "Age: " + person.Age + "<br /><br />";
}
if (litXMLData.Text == "")
litXMLData.Text = "No Results.";
}
|
This method is similar to the other button, which retrieves all the data, except it has a WHERE clause in the SELECT statement. We only select the data from the XML file that matches the user request, then we output it to the Literal Control in the same way as before. Now if you run this, we will have the option to get all data from the XML file, or get data matching the City we select from the list.
As an added feature, we can add AJAX to the code to improve the performance - there will be no full page postback if we use the code below, which is the entire ASPX page:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Using LINQ to XML - displaying and filtering XML data in Visual Studio 2008 and C#</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="butGetXML" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Button ID="butGetXML" runat="server" Text="Get All XML"
onclick="butGetXML_Click" /><br /><br />
Filter data by City:<br />
City: <asp:DropDownList ID="ddlCity" runat="server">
</asp:DropDownList><br />
<asp:Button ID="butFilterXML" runat="server" Text="Filter XML"
onclick="butFilterXML_Click" /><br /><br />
<asp:Literal ID="litXMLData" runat="server"></asp:Literal>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
|
And the entire code-behind will look something like this:
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Xml;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
loadDDL();
}
protected void loadDDL()
{
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("XMLFile.xml"));
XmlNodeList nodeList = doc.SelectNodes("Persons/Person");
foreach(XmlNode node in nodeList)
ddlCity.Items.Add(new ListItem(node.SelectSingleNode("City").InnerText));
}
protected void butGetXML_Click(object sender, EventArgs e)
{
XDocument xmlDoc = XDocument.Load(Server.MapPath("XMLFile.xml"));
var persons = from person in xmlDoc.Descendants("Person")
select new
{
Name = person.Element("Name").Value,
City = person.Element("City").Value,
Age = person.Element("Age").Value,
};
litXMLData.Text = "";
foreach (var person in persons)
{
litXMLData.Text = litXMLData.Text + "Name: " + person.Name + "<br />";
litXMLData.Text = litXMLData.Text + "City: " + person.City + "<br />";
litXMLData.Text = litXMLData.Text + "Age: " + person.Age + "<br /><br />";
}
if (litXMLData.Text == "")
litXMLData.Text = "No Results.";
}
protected void butFilterXML_Click(object sender, EventArgs e)
{
XDocument xmlDoc = XDocument.Load("XMLFile.xml");
var persons = from person in xmlDoc.Descendants("Person")
where person.Element("City").Value == ddlCity.SelectedItem.ToString()
select new
{
Name = person.Element("Name").Value,
City = person.Element("City").Value,
Age = person.Element("Age").Value,
};
litXMLData.Text = "";
foreach (var person in persons)
{
litXMLData.Text = litXMLData.Text + "Name: " + person.Name + "<br />";
litXMLData.Text = litXMLData.Text + "City: " + person.City + "<br />";
litXMLData.Text = litXMLData.Text + "Age: " + person.Age + "<br /><br />";
}
if (litXMLData.Text == "")
litXMLData.Text = "No Results.";
}
}
|
Download the Full Working Version of this Project written with Visual Studio.NET 2008 Here!
Looking for more .NET Database Tutorials? Click Here!
|