AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=856&pId=-1
Working with DataSet Objects and XML
page
by SANJIT SIL
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 16058/ 21

The DataSet class in .NET plays a major role by providing a disconnected data access model.  There are situations when we might not require a database to store data.  Rather, we may store the data in an XML file.  Microsoft .NET provides support for designing such applications with the help of the DataSet class in the System.Data namespace.  In this article I would like to highlight how we can use an XML file as a repository for the CRUD operations and the benefits of doing this.  I will also show how we can search for a specific record based on its primary key value or based on a specific search criterion.  The sample code snippets in this article have been written in C#.

What is a DataSet?

The DataSet is the core component of the disconnected architecture of ADO.NET that is used to cache the data read from the data source in memory.  The data stored in the memory can be modified and written back to the data source.  Hence, DataSet is known as an in-memory representation of data.  DataSets can be used with multiple and different data sources (Database, XML file, etc.).  The DataSet contains one or more DataTable objects.  DataTable object contains DataRows and DataColumns, as well as a primary key, foreign key, and constraint and relation information about the data in the DataTable objects.  The DataTable object represents every table within a DataSet; DataColumn object represents every column within a DataTable.  The DataRow object represents every row within a DataTable.  The DataSet does not validate the XML data against the schema; it simply uses it to infer the structure required for the tables in the DataSet.  The System.Data.DataSet class is provided to support DataSet in .NET.

The XML-Based Methods of the DataSet class

The DataSet class has wonderful support for XML, which will be discussed in detail in this article.  The DataSet class has several methods for reading and writing data as XML, including the following.

·         GetXml Method

·         GetXmlSchema Method

·         InferXmlSchema Method

·         WriteXml Method

·         WriteXmlSchema Method

·         ReadXml Method

·         ReadXmlSchema Method

These methods have been explained in the sections that follow.

The GetXml Method

This method returns a string containing an XML representation of the data stored in the DataSet. No schema is included. The syntax of this method is as follows:

public string GetXml();

The GetXmlSchema Method

This method returns just the schema for an XML representation of the data stored in the DataSet. The GetXmlSchema method returns XML as a string, therefore requiring more overhead than using WriteXmlSchema method to write XML to a file.  The syntax of this method is the following.

public string GetXmlSchema();

InferXmlSchema Method

This method applies XML schema to the DataSet after taking an XML document provided in a TextReader, XmlReader, Stream object or a specified disk file.  The syntax of overloaded versions of this method is as follows.

public void InferXmlSchema(string,string[]);
public void InferXmlSchema(TextReader,string[]);
public void InferXmlSchema(Stream,Stream[]);
public void InferXmlSchema(XmlReader,string[]);

WriteXml Method

This method writes the XML representation of the data in the DataSet object to a TextWriter object, an XmlWriter object, a Stream object or directly to a specified disk file.  The syntax of overloaded versions of this method is below.

public void WriteXml(string);
public void WriteXml(TextWriter);
public void WriteXml(Stream);
public void WriteXml(XmlWriter);

This XML representation can either include or omit the corresponding XML schema.

WriteXmlSchema Method

This method writes the XML schema of the DataSet to a TextWriter object, an XmlWriter object, a Stream object or directly to a specified disk file.  The syntax of overloaded versions of this method is the following.

public void WriteXmlSchema(string);
public void WriteXmlSchema(TextWriter);
public void WriteXmlSchema(Stream);
public void WriteXmlSchema(XmlWriter);

ReadXml Method

This method reads the XML data (including a schema when present) into the DataSet from a TextReader, XmlReader, Stream object or directly to a specified disk file.  The syntax of overloaded versions of this method is below.

public void ReadXml(string);
public void ReadXml(TextReader);
public void ReadXml(Stream);
public void ReadXml(XmlReader);

ReadXmlSchema Method

This method reads the XML schema describing the contents of the DataSet to a TextReader, XmlReader, and Stream object or directly to a specified disk file. The syntax of overloaded versions of this method is the following.

public void ReadXmlSchema(string);
public void ReadXmlSchema(TextReader);
public void ReadXmlSchema(Stream);
public void ReadXmlSchema(XmlReader);

The XmlWriteMode Enumeration

The WriteXml method can be used with a second parameter that specifies XML output of data in more detail.  However, the second parameter is optional.  This method accepts a value from the XmlWriteMode enumeration.  The options/value of enumeration of XmlWriteMode parameter is as follows:

·         WriteSchema

·         IgnoreSchema

·         DiffGram

The following section discusses the above in details.

Write Schema: In this mode it writes the XML data stored in the Dataset along with the loadedschema in DataSet.

Ignore Schema: In this mode only XML data stored in the DataSet will be written.  No schema will be written or even loaded in DataSet.  This is the default mode.

DiffGram: In this mode the data is written out in a form that includes all the original values and any current values for columns in each row that have been modified since the DataSet was loaded.  So the changes made in the DataSet are persisted in the XML file.  Sometimes we need to transfer (XML in DiffGram format) only the changed data in a DataSet to a XML file, then we use GetChange method of DataSet.

DataSet ChangedsProducts = new DataSet();
ChangedsProducts = dsProducts.GetChange();
ChangedsProducts.WriteXml(sPath,XmlWriteMode.DiffGram);

The XmlReadMode Enumeration

The ReadXml method creates the relational schema of the DataSet depending on the option/value of enumeration of XmlReadMode argument specified.  The XmlReadMode enumeration specifies how to read XML data and schema into a DataSet.  This second parameter of ReadXml method is also optional.  The options/value of enumeration of XmlReadMode parameter are as follows.

·         Auto

·         Diffgram

·         Fragment

·         IgnoreSchema

·         InferSchema

·         ReadSchema

The following section discusses the above in details.

Auto: This is the Default mode.  In this mode it reads and examines the XML and chooses the most appropriate option in the following order.

If the XML data is a DiffGram, then the value of enumeration of XmlReadMode argument is set to DiffGram.  If the dataset contains a schema or the XML contains an in-line schema, then the value of enumeration of XmlReadMode argument is set to ReadSchema.  If the DataSet does not contain a schema and the XML does not contain an in-line schema, then the value of enumeration of XmlReadMode argument is set to InferSchema.  It is recommended to set an explicit value for enumeration of XmlReadMode argument, rather than accept the Auto default.  This gives the best performance if we know the format of the XML being read.

DiffGram: In this mode the ReadXml method reads a DiffGram and adds the data to the current schema.  DiffGram merges new rows with existing rows where the unique identifier values match.

Fragment: In this mode the ReadXml method reads the XML documents containing inline XDR schema fragments.  Fragments that match the DataSet schema are appended to the appropriate tables.  Fragments that do not match the DataSet schema are discarded.

Ignore Schema: In this mode the ReadXml method ignores any inline schema and loads data into the existing DataSet schema.  If the data does not match the existing schema, it is discarded.  If no schema exists in the DataSet, no data will be loaded.

Infer Schema: In this mode the ReadXml method ignores any inline schema, infers schema from the data, and loads the data.  If the DataSet already contains a schema, the current schema is extended by adding columns to existing tables, where they exist, or by adding new tables where there is no existing table.  An exception will be thrown if an inferred table already exists with a different namespace or if any inferred columns conflict with existing columns.

Read Schema: In this mode the ReadXml method reads any inline schema and loads the data and schema.  If the DataSet already contains a schema, new tables are added from the inline schema to the existing schema present in the DataSet.  However, an exception is thrown if any tables in the inline schema already exist in the DataSet.  We will not be able to modify the schema of an existing table using XmlReadMode.ReadSchema.  If the DataSet does not contain a schema and there is no inline schema, no data will be read.

Implementing DataSet with Xml

This section shows how we can use the DataSet with an Xml file.  Please follow the stated configuration settings that are required in the web.config file and add the namespaces that have been mentioned.

Add the following in the web.config file.

<appSettings>   
 <add key  = "CString" value ="Server=self-r8yilmkzvk; Database = Sanjit; User   
 ID=sa;Password = sa;"></add>
 <add key = "ProductFile" value ="/Test/products.xml"> </add>
</appSettings>

Remember to change the above settings (Server, Database, User ID, Password, etc.) in the web.config file as per the settings of the system on which the code is to be executed.

Database structure

In this section I have populated the DataSet from a Sql Server DataBase table.  The following is the table structure.

Table Name:  products

Column Name               DataType               Properties

Prod_ID                       Int(4)                     Primary Key

Prod_Name                  Varchar(50)

Prod_Price                    Money(8)

Prod_Available              Char (3)

Prod_Display                 Bit(1)

Writing Data from a DataSet to an XML File

This example demonstrates how to write data from a DataSet directly to a disk file as an XML document.

Listing 1

SqlConnection conn = 
new SqlConnection(ConfigurationSettings.AppSettings["CString"].ToString ()); 
SqlDataAdapter DA = 
new SqlDataAdapter(
"select Prod_ID, Prod_Name,Prod_Price,Prod_Available,Prod_Display from products ",
 conn);
conn.Open();
DataSet DS = new DataSet();
DA.Fill(DS);
DS.WriteXmlSchema(Server.MapPath("products.xml"));
DS.WriteXml(Server.MapPath("products.xml"));

Add data to XML File

This example demonstrates how to add data to an XML file.

Listing 2

dsProducts = PopulateDataSet();
DataRow newProductRow =dsProducts.Tables[0].NewRow();
newProductRow[0] = txtPID.Text;
newProductRow[1] = txtPName.Text;
newProductRow[2] = txtPPrice.Text;
newProductRow[3] = "Yes";
newProductRow[4] = "true";
dsProducts.Tables[0].Rows.Add(newProductRow);
sPath = ConfigurationSettings.AppSettings["ProductFile"];
sPath = Server.MapPath(sPath);
dsProducts.WriteXml(sPath,XmlWriteMode.WriteSchema);

Search from an XML File using DataView

This example demonstrates how to search a result using Sort and RowFilter properties of the DataView object.

Listing 3

dsProducts = PopulateDataSet();
if(dsProducts.Tables["Products"].Rows.Count > 0)
{
  dv = dsProducts.Tables[0].DefaultView;
  dv.Sort = "Prod_Name";
  dv.RowFilter = " Prod_Price >" +txtSearch.Text.Trim();
  if (dv.Count > 0)
  {
 
    DataList1.DataSource = dv;
    DataList1.DataBind();
 
  }
}

In the above code I have used DataList control to display the searched result.  We have to write some code in the .aspx file to show the searched result in DataList control, which is as follows:

Here I have displayed the Product Name and Product Price in DataList control.

Listing 4

<asp:DataList id="DataList1"
 style="Z-INDEX: 104; LEFT: 128px; POSITION: absolute; TOP: 8px"
runat="server"
RepeatColumns="2"
BorderStyle="None" BorderColor="#DEBA84"
BackColor="#DEBA84" CellSpacing="2"
CellPadding="3" GridLines="Both"
BorderWidth="1px">
<SelectedItemStyle Font-Bold="True" ForeColor="White"
BackColor="#738A9C"></SelectedItemStyle>
<ItemStyle ForeColor="#8C4510"
BackColor="#FFF7E7"></ItemStyle>
<ItemTemplate>
<table>
<tr>
<td>
Product Name:<%#DataBinder.Eval(Container.DataItem, "Prod_Name")%>
</td>
</tr>
<tr>
<td>
ProductPrice:<%#DataBinder.Eval(Container.DataItem, "Prod_Price")%>
</td>
</tr>
</table>
</ItemTemplate>
<FooterStyle ForeColor="#8C4510"BackColor="#F7DFB5"></FooterStyle>
<HeaderStyle Font-Bold="True"ForeColor="White" BackColor="#A55129"></HeaderStyle>
</asp:DataList>

We can also use DataGrid control or Repeter control to display the searched result.

Refer to the code listing above.  The PopulateDataSet method populates a DataSet object from an XML File and returns the same.

Listing 5

private DataSet PopulateDataSet()
{
  dsProducts =(DataSet)(Cache[ProductCacheName]);
  if (dsProducts == null)
  {
    sPath = ConfigurationSettings.AppSettings["ProductFile"];
    sPath = Server.MapPath(sPath);
    if (File.Exists(sPath))
    {
      dsProducts = new DataSet();
      dsProducts.ReadXml(sPath,XmlReadMode.ReadSchema);
      Cache.Insert(ProductCacheName, dsProducts,new CacheDependency(sPath));
 
    }
  }
  return dsProducts;
}

Note: Although I have populated cache object with DataSet and made its expiration dependent upon changes to the XML file, a detail discussion of caching is beyond the scope of this article.

We can also use the Select method of DataTable class to search the data as shown in the previous listing.

Listing 6

DataSet dsProducts = PopulateDataSet();
DataSet.Tables["Products"].Select("Prod_Price>150","Prod_IDDESC");

Use of the GetXML Method

The following example will demonstrate the use of GetXML method of DataSet.  To read the complete XML file as a stream, we can use the GetXml method of the DataSet class.  The following code read the Products.xml file into a DataSet and then uses the GetXml method of the DataSet class to display the data in a TextBox.

Listing 7

sPath = ConfigurationSettings.AppSettings["ProductFile"];
sPath = Server.MapPath(sPath);
dsProducts.ReadXml(sPath);
txtXml.Text=ds.GetXml();

Delete Data from XML File

The Delete method demonstrates how to delete data from an XML file.  It takes the PID as the primary key (Prod_ID) to delete a particular product data from the XML file.

Listing 8

private void Delete(int PID)
{
  dsProducts = PopulateDataSet();
  DataTable dt = new DataTable();
  dt = dsProducts.Tables[0];
  DataView dvProducts = new DataView();
  dvProducts = dt.DefaultView;
  dvProducts.Sort = "P_ID";
  int rowIndex =dvProducts.Find("PID");
  if (rowIndex ==  - 1)
  {
    Response.Write("Product notfound");
  }
  else
  {
    dvProducts.RowFilter = "P_ID=" +PID;
    dvProducts.Delete(0);
    dsProducts.WriteXml(sPath,XmlWriteMode.WriteSchema);
  }
}

Edit Data in XML File

The Update method demonstrates how to update data in an XML file.  It takes the PID as Prod_ID to edit a particular product data.  Here I have edited the price of a particular product after taking the new price from the textbox control named txtPPrice.  We can also update other data of a particular product in a similar way.

Listing 9

private void Update(int PID)
{
  dsProducts = PopulateDataSet();
  DataTable dt = new DataTable();
  dt = dsProducts.Tables[0];
  DataView dvProducts = new DataView();
  dvProducts = dt.DefaultView;
  dvProducts.Sort = "P_ID";
  int rowIndex = dvProducts.Find(PID);
  if (rowIndex ==  - 1)
  {
    Response.Write("Product notfound");
  }
  else
  {
    dvProducts.RowFilter = "P_ID=" +PID;
    dvProducts[0]["P_Price"] =txtPPrice.Text;
    dsProducts.WriteXml(sPath,XmlWriteMode.WriteSchema);
  }
}

This section shows how we can execute the code snippets that have been discussed so far.  For this, we require the creation of objects of the DataSet and the DataView classes.  To use the DataSet class, add the following namespaces along with the default namespaces in your application’s code.

using System.Data.SqlClient;
using System.Configuration;
using System.Web.Caching;

Add the following code to run the code mentioned in this article.

DataSet dsProducts = new DataSet();
string sPath;
string ProductCacheName = "";
DataView dv=new DataView();

Suggested Readings

http://www.c-sharpcorner.com/database/dbaccess_class.asp

http://www.xmlme.com/XmlToDS.aspx?mid=45

http://msdn.microsoft.com/library/default.asp?url=/library/enus/cpguide/html/cpconxmldataset.asp

http://aspnet.4guysfromrolla.com/articles/112603-1.aspx

http://support.microsoft.com/default.aspx?scid=kb;en-us;323290

Conclusion

This article has depicted how we can use the Dataset class to provide simple yet effective access to an XML file.  This is, however, recommended for use in only smaller applications, those with low volume of data.

It will be useful only in the following scenarios.

·         When we are handling a small amount of data.

·         When we are developing a demo, prototype or other small applications.

·         When the user does not need to install and maintain any database engine.

·         When cost is a factor.

The demerit of this methodology can be attributed to memory consumption when dealing with high volumes of data as the entire data would have to be loaded into the memory.  This would become a nightmare for large applications and therefore, is not recommended for use in such scenarios.



©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-29 2:21:47 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search