Developing ASP.NET Applications Using XML as Data Storage

This article mainly concentrates on using XML as data storage (instead of using RDBMS). We will cover how to develop a Web application using ASP.NET by developing our own simple business logic, which gets directly mapped to XML data and XML schema files.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 44
May 16, 2005
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Designing a simple XML Wrapper:

The main advantage to designing an XML wrapper is to maintain common operations such as add, update and delete at a single point. We need to design this wrapper in such a way that it works with almost any type of XML file. If we think logically, the wrapper needs to know the following issues before it implements any operations:

  • What XML document should it write to?
  • What sort of XML Schema should it write on?
  • Which tag behaves as the table name?
  • What are the other tags, which behave as column names?
  • What are the column values that need to be written?

Considering the above issues, it is obvious that we need to design some properties to hold that information. The following members would make a simple XML wrapper class to solve our requirements.

  • FilenameXMLSchema (m_FilenameXMLSchema)
  • FilenameXMLDocument (m_FilenameXMLDocument)
  • TableName (m_TableName)
  • ColumnNames (m_ColumnNames)
  • ColumnValues (m_ColumnValues)
  • Add
  • Update
  • Delete

"FilenameXMLSchema," "FilenameXMLDocument" and "TableName" are simple properties of the string type. "ColumnNames" and "ColumnValues" are the properties of string array (as they hold more than one value). The words given opposite them (in parentheses) are the private memory variables inside the class, which hold the property values.

"Add," "Update" and "Delete" are methods to provide appropriate operations. "Update" and "Delete" will have a parameter "Criteria" to provide a condition in the form of a string. 

The entire class is available in the "supported download files" section with the filename CXMLWrapper.vb. The next section explains bit about the main methods in that class.

{mospagebreak title=Implementing DML operations within the XML wrapper}

 

Let's take a look at the code for the "add" method.

 

PublicSubadd()

               DimdsAsNewDataSet

                ds.ReadXmlSchema(m_FilenameXMLSchema)

                ds.ReadXml(m_FilenameXMLDocument)

 

                DimdtAsDataTable

                dt = ds.Tables(m_TableName)

                DimdrAsDataRow = dt.NewRow

                DimcAsInteger

 

                Forc = 0Tom_ColumnNames.Length - 1

                      DimFieldNameAsString= m_ColumnNames(c)

                      DimFieldValueAsString= m_ColumnValues(c)

                      dr(FieldName) = FieldValue

                Next

               dt.Rows.Add(dr)

                ds.WriteXml(m_FilenameXMLDocument)

                ds.Dispose()

EndSub

I hope the steps are very simple. Here ReadXMLSchema and ReadXML methods are used to read XML Schema Structure and XML document data, respectively. The datatable (dt) points to a particular table in the dataset (ds) identified by “m_TableName.” We add a new row (dr) to the datatable (dt), and we assign all the column values available in “m_ColumnValues” using a loop to that new row (dr). Finally, we add that row (dr) to the datatable (dt), and  the dataset (ds) is written into the XML document (filename in “m_FilenameXMLDocument”) using “writeXML” method.

Now let's examine the code for the "update" method.

PublicSubupdate(ByValcriteriaAsString)

                DimdsAsNewDataSet

                ds.ReadXmlSchema(m_FilenameXMLSchema)

                 ds.ReadXml(m_FilenameXMLDocument)

 

          DimdtAsDataTable

                dt = ds.Tables(m_TableName)

          DimdvAsDataView = dt.DefaultView

                dv.RowFilter = criteria

           DimdrvAsDataRowView

           ForEachdrvIndv'go through all filtered rows

                  DimcAsInteger

        'go through the columns to be updated for the particular row

                  Forc = 0Tom_ColumnNames.Length - 1

                    DimFieldNameAsString= m_ColumnNames(c)

                    DimFieldValueAsString= m_ColumnValues(c)

                    drv(FieldName) = FieldValue

                  Next

                Next

       'write to XML file if there exists any rows in filter

               Ifdv.Count > 0Thends.WriteXml(m_FilenameXMLDocument)

           ds.Dispose()

         EndSub

Even here, the steps are somewhat similar. But here we are passing "criteria" as a parameter to this method. The primary requirement to update data is that rows need be filtered depending on criteria. So, the "defaultview" of "datatable" will be used to filter the rows, and its reference gets stored in the "dataview" object (dv). We assign "criteria" to the "RowFilter" property of "dv" (which filters the rows automatically). We then declare object "drv" of type "DataRowView," which will loop through all filtered rows. The columns get updated for every filtered row by using a nested loop. The final step is to write to the XML file if and only if there exists any rows in the filter.

The procedure for "delete" is very similar to the "update" method, except that we put "drv.Delete()" within the nested loop.

{mospagebreak title=Adding a module (gModule) to store constants}

Everyone needs (in general) some project-wide constants (or values) to be stored and accessed throughout the project. It is recommended that theThe constants (or some frequently used utility methods) be embedded in a separate module.

In our case, the file names of XML Schema and XML Data need to be stored in some constant values. Even physical paths must be maintained. So, I decided to use a module (gModule) to maintain all these aspects. The following code helps for all of these matters.

 

ModulegModule

   PublicHostRootPathAsString'gets initilized at InitPaths

   PrivateXMLDATA_PATHAsString= "data/"

   PublicEMPLOYEE_FILENAMEAsString= "XMLStoreData.xml"

   PublicEMPLOYEESCHEMA_FILENAMEAsString= "XMLStoreSchema.xsd"

 

   PublicSubInitPaths(ByReffrAsObject)

       'this method should be executed in session_start event of global.asax

       HostRootPath = fr.Request.ServerVariables("APPL_PHYSICAL_PATH")

   EndSub

 

   PublicFunctiongetXMLDATAPATH()AsString

       ReturnHostRootPath & XMLDATA_PATH

   EndFunction

 

EndModule

 

The matter is very straightforward. We need the physical path of XML files (even in a hosted environment) to store our data. And these small routines will simplify our lives.

{mospagebreak title=Designing a CEmployee class to work with the wrapper}

First of all, is this class necessary? The answer is yes, if we want to use the power of OOPS in our project. I considered designing using OOPS; this is the class for that.

To pass the entire data of an Employee as a simple object in between different objects, I implemented a structure to hold all of the Employee information as follows (inside this class):

PublicStructuretEmployee

                      PublicEmpNOAsString

                      PublicENameAsString

                      PublicDeptNoAsInteger

                                    PublicSalAsInteger

                                  EndStructure

Another "private" method for returning a concrete CXMLWrapper object, which will be used to directly access the physical XML family of files, is shown below.

PrivateFunctiongetXMLDBWrapper()AsCXMLWrapper

       DimObjXMLAsNewCXMLWrapper

       WithObjXML

           .FilenameXMLSchema = gModule.getXMLDATAPATH & gModule.EMPLOYEESCHEMA_FILENAME

           .FilenameXMLDocument = gModule.getXMLDATAPATH & gModule.EMPLOYEE_FILENAME

           .TableName = "Employee"

       EndWith

       ReturnObjXML

   EndFunction

Two more "get" methods for retrieving the information related to employee(s) are shown here:

PublicFunctiongetEmployeeList()AsDataTable

       DimdsAsNewXMLStoreSchema

       ds.ReadXml(gModule.getXMLDATAPATH() & EMPLOYEE_FILENAME)

       DimdtAsDataTable = ds.Tables("Employee")

       Returndt

   EndFunction

 

   PublicFunctiongetEmployee(ByValEmpNoAsString)AsDataRow

       DimdtAsDataTable = getEmployeeList()

       Dimdr()AsDataRow = dt.Select("EmpNo='" & EmpNo & "'")

       Ifdr.Length = 0ThenReturnNothingElseReturndr(0)

   EndFunction

Here is one more method for adding the employee details:

PublicFunctionaddEmployee(ByValEmployeeAstEmployee)

       DimObjXMLAsCXMLWrapper = getXMLDBWrapper()

 

       DimColumnValues()AsString

       WithEmployee

           ColumnValues =NewString() {.EmpNO, .EName, .DeptNo, .Sal}

       EndWith

       DimColumnNames()AsString

       ColumnNames =NewString() {"EmpNO", "EName", "DeptNo", "Sal"}

 

       WithObjXML

           .ColumnValues = ColumnValues

           .ColumnNames = ColumnNames

           .add()

       EndWith

   EndFunction

"UpdateEmployee" and "DeleteEmployee" methods will be almost similar to that of "addEmployee," except that "criteria" is necessary.

 

 {mospagebreak title=Preparing a "strict" structure to work with XML wrapper using VS.NET}

Now we will start by creating a "proper" sequence to work with ASP.NET and XML using Visual Studio.NET 2003 Enterprise Architect as our main Objective. Working with Visual C#.NET is also quite similar to the steps we discuss here (except for the syntactical differences in programming statements).

Using Visual Studio.NET, proceed with the following steps:

  • Go to File >> New Project.
  • Select Project type "Visual Basic" (select Visual C# if you work with C#) from the left panel. Next, select "ASP.NET Web Application" from the right panel and name the Web application "Sample."
  • Right click on project name "Sample" (using "Solution Explorer") and add a new folder named Data.
  • Right click again on project name "Sample" and select Add->Add new item. Select "Dataset" and name it XMLStoreSchema.xsd. You will be presented with a layout where you can create your own XML schema.
  • Select the Element tool from toolbox and drag it on to the layout. Make the modifications to the newly created object as shown in the following figure (Fig 1).

  • Make sure that "generate dataset" is checked "on" in the "schema" menu (as shown in Fig 2) and save the solution. This "generate dataset" option internally creates a new dataset class inherited from pre-defined dataset class, which gets mapped to the current XML Schema design.

  • Right click again on project name "Sample" and select Add->Add new item. Select "XML file" and name it XMLStoreData.xml to the existing project.
  • Go to properties and change Target Schema property to http://tempuri.org/XMLStoreSchema.xsd.
  • Click on the Data tab; provide data accordingly (shown in Figure 3) and save the solution again.

  • Right click again on project name "Sample" and select Add->Add new item. Select "Class" and name it CXMLWrapper.vb. This wrapper contains the Add, Update and Delete methods to operate with any XML file. Copy and paste code (from CXMLWrapper.vb) from the "supported download files" section of this article.

  • Right click again on project name "Sample" and select Add->Add new item. Select "Class" and name it CEmployee.vb. This class contains AddEmployee, UpdateEmployee, DeleteEmployee and methods to operate with any CXMLWrapper object. Copy and paste code (from CEmployee.vb) from "supported download files" section of the article.
  • Right click again on project name "Sample" and select Add->Add new item. Select "Module" and name it gModule.vb. This contains "public" constants used throughout the project. Copy and paste code (from gModule.vb) from the "supported download files" section of this article.

{mospagebreak title=Designing the Web page}

 

Up to this point we completed the main business logic we need to work with XML. Now we must design a Web page which accesses the XML data file though our business logic.

 

Let us start by designing a Web form which will be similar to Figure 4. As you can see from the figure, I heavily use the "DIVs" running at server side. Of course you can also replace them with Panel controls. The Web form can be downloaded from the "supported files" section.

 

 

To add a new employee to the XML store, the following code would do the task very easily:

 

DimtAsCEmployee.tEmployee

           Witht

               .EmpNO =Me.txtEmpNo.Text

               .EName =Me.txtEName.Text

               .DeptNo =Me.txtDeptNo.Text

               .Sal =Me.txtSal.Text

           EndWith

           DimobjAsNewCEmployee

obj.addEmployee(t)

 

Similarly, for the update, the code would be as follows:

DimtAsCEmployee.tEmployee

           Witht

               .EmpNO =Me.txtEmpNo.Text

               .EName =Me.txtEName.Text

               .DeptNo =Me.txtDeptNo.Text

               .Sal =Me.txtSal.Text

           EndWith

           DimobjAsNewCEmployee

obj.updateEmployee (t)

 

For the delete operation, the code is further simple than the above:

DimobjAsNewCEmployee

obj.deleteEmployee (Empno)

 

The rest of the code is just the UI logic, which is quite common among almost any type of ASP.NET application.

 

NOTE: Make sure you provide the write access privileges to the folder “data” within your project. Otherwise you may experience the “Access Denied” error. You should also remember that XML is case sensitive. So, I ask that you follow the same case or convention that you have designed in your XML Schema.

 

Remarks: The entire source code of this article exists in the form of a downloadable zip (including the figures). I developed this small project using just Microsoft Visual Studio.NET 2003 Enterprise Architect. 

 

I leave it to the programmers for further enhancements. Any doubts, comments, suggestions, bugs, errors or feedback are welcome at jag_chat@yahoo.com.  

blog comments powered by Disqus
ASP.NET ARTICLES

- Implementing ASP.NET 4.0 Page.MetaDescriptio...
- ASP.Net Development Tips
- Intro to Sessions in ASP.Net
- Google Maps API Introduction in ASP.NET usin...
- Creating an ASP.NET 3.5 Gridview Image Galle...
- Encrypt QueryString in ASP.NET 3.5 using VB....
- ASP.NET 3.5 Drop Down List Controls
- Connect to Access Database with ASP.Net
- Secure Audio Streaming with ASP.Net and Flash
- Dynamic Sitemap and Navigation in ASP.Net
- Implement Gzip and Deflate Compression in AS...
- Run ASP.Net in Ubuntu with Apache
- ASP.Net Mono Website Contact Forms
- ASP.Net URL Rewriting Methods
- Murach`s ASP.NET 4 Web Programming with C# 2...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 1 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials