Reading and writing in xml can be done in different ways, some common classes people use are XmlTextReader, XmlTextWriter , XmlDocument but we will use XDocument. By using the other classes say XmlTextReader we need to use the while loop to read and check every node by using XmlNodeType, for a long XML file which is not suitable. We need a way to search the exact node by providing Id of the record similar to SQL where clause and work with that node only, which is possible if we will use XDocument and access the node by using Descendants property, which we will see in this article.
What we are going to achieve in this article:
Here is the final output of the article:
First of all we will see the XML file which we are going to use in this article, we will use the ID as the attribute of main product node, if you want to use it as an element, even then you don’t need any change in code except some for XML read and write, binding of grid and loading of XML will work smooth with current code. Here is the product.xml file with only one product, put it on the root of the application otherwise you will need to change the file path load and save methos.
<?xml version="1.0" encoding="utf-8"?>
<Products>
<Product Id="760">
<Name>Samsung Galaxy 6</Name>
<Price>600</Price>
<Category>Mobile</Category>
<CreatedOn>2014-12-20 14:06:06</CreatedOn>
<ModifiedOn />
</Product>
</Products>
We will load this XML file into dataset by using dataset ReadXml method and bind to the Gridview. When we load XML to a dataset, it create tables in it, if XML structure is complicated then it will load more than one table which can be accessed by using the index. But our XML is quite simple so it will have only on table which can be accessed by using dataSet.Tables[0], here is the complete code to load the XML into dataset and then bind to gridview
protected void LoadXMLToGrid()
{
var dataSet = new DataSet();
dataSet.ReadXml(Server.MapPath("~/products.xml"));
gvProducts.DataSource = dataSet.Tables[0];
gvProducts.DataBind();
}
We can call it into page_load method to load the grid as well as after adding and modifying the record to refresh the grid
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadXMLToGrid();
}
Here is the complete HTML to bind the Gridview as well control to add or update the record, I don't think it need any clarification, let me know if you need any clarification about it
<asp:UpdatePanel ID="uplMain" runat="server">
<ContentTemplate>
<div style="display: inline-block">
<asp:HiddenField ID="hfId" runat="server" Value="0" />
<div>
<asp:TextBox ID="txtName" runat="server"
placeholder="Enter product name" />
</div>
<div>
<asp:TextBox ID="txtCategory" runat="server"
placeholder="Enter product Category" />
</div>
<div>
<asp:TextBox ID="txtPrice" runat="server"
placeholder="Enter product price" />
</div>
<div>
<asp:Button ID="btnSave" runat="server"
Text=" Save " OnClick="btnSave_Click" />
</div>
</div>
<div>
<asp:GridView ID="gvProducts" runat="server"
AutoGenerateColumns="false"
DataKeyNames="Id"
Width="100%">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton id="ibtnEdit" runat="server"
Width="22" Height="22"
style="border:none; padding:0; margin:0"
ImageUrl="/images/edit.png"
OnClick="ibtnEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="ID" DataField="Id" />
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:BoundField HeaderText="Category" DataField="Category" />
<asp:BoundField HeaderText="Price" DataField="Price" />
<asp:BoundField HeaderText="Created On" DataField="CreatedOn" />
<asp:BoundField HeaderText="Modefied On" DataField="ModifiedOn" />
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
Run the application and you will see it working smooth and loading the XML into gridview. Now we need to write the code for add and update, we need a model to pass the data from one method to other so we will use the step to create class from XML which is defined in my previous article Convert xml, json to class in asp.net c# by one click, here is the simple steps to convert xml to class if you don’t want to go see in detail
<Product> ….. </Product>
It will create the class which need a little bit change in data type for different properties because XML to class conversion is not 100% correct to get exact data type for value in our XML elements, see this
public partial class Product
{
private string nameField;
private decimal priceField;
private string categoryField;
private DateTime createdOnField;
private DateTime modifiedOnField;
private int idField;
public int Id
{
get { return this.idField; }
set { this.idField = value; }
}
/// <remarks/>
public string Name
{
get {return this.nameField; }
set { this.nameField = value; }
}
/// <remarks/>
public decimal Price
{
get { return this.priceField; }
set { this.priceField = value;
}
}
/// <remarks/>
public string Category
{
get { return this.categoryField; }
set { this.categoryField = value; }
}
/// <remarks/>
public DateTime CreatedOn
{
get { return this.createdOnField; }
set { this.createdOnField = value; }
}
/// <remarks/>
public DateTime ModifiedOn
{
get{ return this.modifiedOnField; }
set { this.modifiedOnField = value; }
}
}
Add a mothod AddNode which will take one parameter Product which we create from XML, load the fild into XDocument and add new product node with values passed in parameter, here is the complete code to add new node:
protected void AddNode(Product product)
{
var doc = XDocument.Load(Server.MapPath("~/products.xml"));
XElement newProduct = new XElement("Product",
new XAttribute("Id", product.Id),
new XElement("Name", product.Name),
new XElement("Price", product.Price),
new XElement("Category", product.Category),
new XElement("CreatedOn",
String.Format("{0:yyyy-MM-dd HH:mm:ss}", product.CreatedOn)),
new XElement("ModifiedOn", null)
);
// Add node as a very first node
doc.Root.AddFirst(newProduct);
// To add bottom use doc.Root.Add
doc.Save(Server.MapPath("~/products.xml"));
}
We have Save button to save the record create the event for it in code behind and add code to add new Node, put all the provided information into Product class and call AddNode method or UpdateNode (we will add latter in this article) with detail, I used hidden field to keep the ID if it is 0 (zero, in case of add) then need to generate a new Id by using random number from 100 to 9999 otherwise in case of update we will assign Id to hidden field and use that to update, here is the code of save button
protected void btnSave_Click(object sender, EventArgs e)
{
var product = new Product();
if (hfId.Value == "0")
{
product.Id = new Random().Next(100, 9999);
product.CreatedOn = DateTime.Now;
}
else
{
product.Id = Convert.ToInt32(hfId.Value);
product.ModifiedOn = DateTime.Now;
}
product.Name = txtName.Text;
product.Price = Convert.ToDecimal(txtPrice.Text);
product.Category = txtCategory.Text;
if (hfId.Value == "0")
{
// Add and load the grid again
AddNode(product);
hfId.Value = "0";
LoadXMLToGrid();
}
else
{
// Update and load the grid again
UpdateNode(product);
hfId.Value = "0";
LoadXMLToGrid();
}
}
Add code to update the record, we need to add the code to get record from grid on clicking edit button in grid, we can get it from XML by using search which you can see in update method but for this example I am getting all the values from grid, here is the edit button click event to fill the text boxes to update the record
protected void ibtnEdit_Click(object sender, ImageClickEventArgs e)
{
var ibtn = sender as ImageButton;
GridViewRow gvrow = ibtn.NamingContainer as GridViewRow;
hfId.Value = Convert.ToString(gvProducts.DataKeys[gvrow.RowIndex].Value);
txtName.Text = gvrow.Cells[2].Text;
txtCategory.Text = gvrow.Cells[3].Text;
txtPrice.Text = gvrow.Cells[4].Text;
}
Code to update the XML file, which is not easy but thousand times faster because we can directly go to that node and manipulate the value directly than open the file, read record by record and then property by property and then update them, see this
protected void UpdateNode(Product product)
{
var doc = XDocument.Load(Server.MapPath("~/products.xml"));
var Contact = (from xml in doc.Descendants("Product")
where Convert.ToInt32(xml.Attribute("Id").Value) == product.Id
select xml).FirstOrDefault();
Contact.Element("Name").Value = product.Name;
Contact.Element("Category").Value = product.Category;
Contact.Element("Price").Value = product.Price.ToString();
Contact.Element("ModifiedOn").Value =
String.Format("{0:yyyy-MM-dd HH:mm:ss}", product.ModifiedOn);
doc.Save(Server.MapPath("~/products.xml"));
}
![]() |
Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
|
By Ali Adravi On 20 Dec, 14 Viewed: 5,015 |
Convert XML or JSON into a class by using visual studio is as easy as just copy and two clicks, never matter how big or how complicated is our XML or JSON. In this article we will create some dummy XML and json and will try to convert them into class without writing a single property manually. It... By Ali Adravi On 20 Dec 2014 Viewed: 2,058
When there was XmlDocument why we need XDocument, is there any better feature available with XDocument, answer is yes, XDocument has a number of benefits, easy to create, easy to update, easy to search, ability to use LINQ to XML, cleaner object model etc. In this post we will see some examples... By Ali Adravi On 16 Mar 2013 Viewed: 3,482
HTML syntax, this is the format suggested for most authors. It is compatible with most legacy Web browsers. If a document is transmitted with the `text/html MIME` type, then it will be processed as an HTML document by Web browsers. This specification defines version 5 of the HTML syntax, known as... By Alicia Gonzalez On 25 Dec 2012 Viewed: 1,183
XML (Extensible Markup Language) is a simple text-based format for representing structured information: documents, data, configuration, books, transactions, invoices, and much more. It was derived from an older standard format called SGML. **XML Used For** XML is one of the most widely-used... By Alicia Gonzalez On 25 Dec 2012 Viewed: 1,133
In some situations we need to create website menu from database, say our application have ability to create pages so that must also need to have a menu item to go to that page. So how to create menu with all those nice CSS and other settings, I think XSLT is best to use in these... By Hamden On 16 Mar 2013 Viewed: 1,858