Building Dynamic Websites Using XML Files
page 1 of 3
Published: 01 Oct 2007
Abstract
In this article Amal demonstrates how to build a dynamic website using XML files.
by Amal ElHosseiny
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 41222/ 71
Article Contents:

Overview

In this article I will present how to build websites with dynamic content. Content is saved in one XML file so you will not think about database hosting problems.

Our website has sections, each section has content. We will be able to change sections names, add new sections, and edit content of every section. The project is separated into different business Backend ("the responsible of administrating sections and their contents") and FrontEnd (the final website). I have combined both in the same project but you can organize files and projects as you like relevant to your business.

Figure 1

Figure 1 displays how the site looks at the end; the header has sections that added from the backend. The header is DataList control. Of course you can use whatever design you want, but it is bounded to our XML file. Let us discuss XML file structure first; XML file has schema and data in the same time. Schema is one table in sections and every section has an id, name, and content. Id is auto increment to be used as the primary key afterwards in retrieving data, see listing 1.

Listing 1

<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" 
msdata:MainDataTable="Sections" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Sections">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Id" msdata:AutoIncrement="true" type="xs:int" 
minOccurs="0" />
                <xs:element name="Name" type="xs:string" minOccurs="0" />
                <xs:element name="Content" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>

Now we will review the backend structure. I have one master page to backend and another one for frontend. Backend master page is in Figure 2.

Figure 2

In the top menu we have three links: sections, content and website (front-end). Sections page is used to add sections, remove old ones and also update old section name.

Figure 3

In the page load the code checks if there is data in the XML file or not, and if it is then it will be loaded in the listbox.

Listing 2

protected void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack)
  {
    strFilePath = MapPath(@"~/xmls/Sections.xml");
    Session["dtSections"= ManageFile.LoadSections(strFilePath);
    Session["strFilePath"= strFilePath;
    BindList((DataTable)Session["dtSections"]);
  }
  else if (Session["strFilePath"] != null)
    strFilePath = (string)Session["strFilePath"];
}

First, we have folders inside the project for XML file named xmls. I save the path in session and load sections names and content in the session too. We use session to reduce reading from XML all the time.

In the save button we do two transactions. One in adding and the other one is updating, see listing 3. Adding is very easy and it just adds in datatable new row and writes in XML. But updating uses session to hold the id of the selected section. Actually, you can use viewstate or query string; it is up to you how to store data.

Listing 3

protected void btnAdd_Click(object sender, EventArgs e)
{
  DataTable dtSections;
  if (Session["Id"] == null)
    dtSections = dataAccess.AddSection(txtSection.Text, (DataTable)Session[
      "dtSections"], strFilePath);
  else
    dtSections = dataAccess.UpdateSection(txtSection.Text, (DataTable)Session[
      "dtSections"], strFilePath, Session["Id"].ToString());
 
  Session["dtSections"= dtSections;
  BindList(dtSections);
  txtSection.Text = "";
}

Removing a section is not a big deal too, as in listing 4 we will see that I just check if ListBox has the selected value or not and then select the row from the datatable saved in session removing and finally saving it on the XML file.

Listing 4

private void RemoveFromList()
{
  if (listbSections.SelectedItem != null)
  {
    DataTable dtSections = (DataTable)Session["dtSections"];
    DataRow[]drSections = dtSections.Select(" Id = " +
      listbSections.SelectedValue);
    if (drSections != null)
      dtSections.Rows.Remove(drSections[0]);
    Response.Write(
      "<script>alert('Section has been removed successfully')</script>");
    Session["dtSections"= dtSections;
    ManageFile.SaveSections(dtSections, strFilePath);
    BindList(dtSections);
 
  }
}

After adding sections then we are going to fill the content; in the content page you will see a big textbox that the user can type whatever he likes in HTML or normal text and it will presented in frontend as he saved it. The user will have to select the section to begin adding or editing section content and press save.

Figure 4

The Save button does the same as sections page save, but this time it saves content.

Listing 5

private void SaveContent()
{
  dataAccess.SaveContent(drpSections.SelectedValue, txtContent.Text, 
(DataTable)Session["dtSections"], (string)Session["strFilePath"]);
  Response.Write("<script>alert('Content saved')</script>");
}

Note that I use DataAccess class to deal with the XML file. Of course when the section name is selected, I load content from session to prepare for editing.

After we add sections and fill them with content, we are going to see how we present them in the website.

The master page for the website has DataList as the menu bounded to XML file, see figure 5. You will notice that DataList is horizontal, and the table in itemtemplate holds the link to sections, see listing 6.

Figure 5

Listing 6

<asp:DataList ID="dlSections" Width=600px runat=server RepeatDirection=Horizontal 
BackColor=Black ForeColor=white Font-Size=12px Font-Family=verdana>
  
   <ItemTemplate>
   <table>
   <tr>
   <td align=center>
   <a   href="FrontHome.aspx?PageId=<%# Eval("Id")%>"><%#Eval("Name") %></a>
   </td>
   </tr>
   </table>
   </ItemTemplate>
   
   <SeparatorTemplate>
   |
   </SeparatorTemplate>
    </asp:DataList>

During the load of the master page I bound the DataList to XML sections names.

Listing 7

private void LoadSections()
{
  if (Session["dtSections"] == null)
  {
    Session["dtSections"= ManageFile.LoadSections(MapPath(@
      "~/xmls/Sections.xml"));
  }
 
  dlSections.DataSource = (DataTable)Session["dtSections"];
  dlSections.DataBind();
 
}

Then you will have the menu with sections and when you click on any link, content is loaded relevant to the Id sent in query string.

Listing 8

private void LoadContent()
{
  if (Request["PageId"] != null)
  {
    DataAccess dataAccess = new DataAccess();
    if (Session["dtSections"] == null)
    {
      string strFilePath = MapPath(@"~/xmls/Sections.xml");
      Session["dtSections"= ManageFile.LoadSections(strFilePath);
    }
    LtrlContent.Text = dataAccess.GetSectionContent(Request["PageId"],
      (DataTable)Session["dtSections"]);
  }
}

After I finished the project I remembered that I do not have a login page for backend so I added one. It is very simple; you can review two lines of code to check username and password "admin." You also can use whatever authentication you want.

Now that you have finished the simplest dynamic website building, you can implement it all in 30 minutes. Notice that you can use other controls for menus and labels in spite of literal control to the present content. It is very flexible, but never forget set ValidateRequest="false" in the content page directive to allow submitting HTML in XML file.


View Entire Article

User Comments

No comments posted yet.

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2017 ASPAlliance.com  |  Page Processed at 2017-06-24 11:50:45 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search