Không có 1 thông tin chính thức từ Microsoft về sự thay thế của Linq2Xml cho XDocument về việc thao tác với tài liệu Xml, trong bài blog này mình sẽ hướng dẫn các bạn các tác vụ cơ bản CRUD (create, retrieve, update, và delete) với Linq2Xml sử dụng XElement object.
Mình sẽ sử dụng Gridview vì nó support Edit và Delete xây dựng sẵn, và dùng gridview để hiển thị danh sách các elements.
Sử dụng Visual Studio tạo 1 website mới C# code.
Tạo dữ liệu xml với schema và data như sau:
<?xml version="1.0" encoding="utf-8"?>
<contacts>
<contact id="f02c78b4956f4b2f9ecfb7a5bfbcfbf6" name="quachnguyen" email="quachnguyen@gmail.com"></contact>
<contact id="f02c78b4956f4b2f0ecfb7a5bfbcfbf6" name="neonquach" email="neonquach@gmail.com"></contact>
<contact id="f02c87b4956f4b2f9ecfb7a5bfbcfbf6" name="code2code" email="admin@code2code.info"></contact>
</contacts>
Mình save với tên là contact.xml và lưu trong App_Data.
Từ toolbox kéo gridview vào Visual Designer, set các thuộc tính như sau:
AutoGenerateColumns="False"
AutoGenerateDeleteButton="True"
AutoGenerateEditButton="True"
DataKeyNames="id"
Tiến hành add thêm 2 cột cho gridview và bind 2 thuộc tính name và email và markup language cho gridview như sau:
<asp:GridView ID="grdContact" runat="server" AutoGenerateColumns="False" AutoGenerateDeleteButton="True"
AutoGenerateEditButton="True" OnRowCancelingEdit="grdContact_RowCancelingEdit"
OnRowDeleting="grdContact_RowDeleting" OnRowEditing="grdContact_RowEditing" OnRowUpdating="grdContact_RowUpdating"
DataKeyNames="id">
<Columns>
<asp:TemplateField HeaderText="Name">
<EditItemTemplate>
<asp:TextBox ID="txtName" runat="server" Text='<%# Bind("name") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Bind("name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Email">
<EditItemTemplate>
<asp:TextBox ID="txtEmail" runat="server" Text='<%# Bind("email") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblEmail" runat="server" Text='<%# Bind("email") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Như chúng ta đả thấy gridview contact của chúng ta có 1 số sự kiện như:
OnRowCancelingEdit, OnRowUpdating, OnRowDeleting, OnRowCancelingEdit
Add new, chúng ta thêm 2 textbox, 2 label và 1 button, markup như sau:
<asp:Label ID="lblName" runat="server" Text="Name:"></asp:Label>
<asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></p>
<p>
<asp:Label ID="Label2" runat="server" Text="Email: "></asp:Label>
<asp:TextBox ID="txtEmailAdress" runat="server"></asp:TextBox>
<p />
<asp:Button ID="btnAdd" runat="server" Text="Add" onclick="btnAdd_Click" />

Tiến hành viết 1 hàm load tất cả các danh sách contact như sau:
public void LoadContacts()
{
string filePath = Server.MapPath("~/App_Data/contact.xml");
XElement Contacts = XElement.Load(filePath);
if (Contacts != null)
{
var query = from c in Contacts.Elements("contact")
select new
{
Id = (string)c.Attribute("id").Value,
Name = c.Attribute("name").Value,
Email = c.Attribute("email").Value
};
grdContact.DataSource = query.ToList();
grdContact.DataBind();
}
}
Load danh sách trong sự kiện Page_Load()
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadContacts();
}
}
Nhấn F5, chúng ta sẻ thấy màng hình như sau:

Thêm mới 1 contact, double click vào button add và paste đoạn code sau vào:
protected void btnAdd_Click(object sender, EventArgs e)
{
string name = txtUserName.Text.Trim();
string email = txtEmailAdress.Text.Trim();
string FilePath = Server.MapPath("~/App_Data/contact.xml");
XDocument doc = XDocument.Load(FilePath);
IEnumerable<XElement> contacts = doc.Element("contacts").Elements("contact");
var contact = new XElement("contact",
new XAttribute("id", Guid.NewGuid().ToString().Replace("-","")),
new XAttribute("name", name),
new XAttribute("email",email));
contacts.Last().AddAfterSelf(contact);
doc.Save(FilePath);
LoadContacts();
txtUserName.Text = txtEmailAdress.Text = "";
}
Chúng ta sẽ add vào thứ cuối cùng của danh sách với:
contacts.Last().AddAfterSelf(contact);
Sau khi add thành công chúng ta tiến hành Load lại danh sách để xem sự thay đổi và clear tất cả các textboxes để tiếp tục thêm 1 contact mới.
Delete 1 contact:
protected void grdContact_RowDeleting(object sender, System.Web.UI.WebControls.GridViewDeleteEventArgs e)
{
string FilePath = Server.MapPath("~/App_Data/contact.xml");
string contactId = (string)grdContact.DataKeys[e.RowIndex].Value;
XElement element = XElement.Load(FilePath);
var query = (from c in element.Descendants("contact")
where c.Attribute("id").Value == contactId
select c).Single();
if (query != null)
{
query.Remove();
element.Save(FilePath);
}
LoadContacts();
}
Để delete thì chúng ta phải biết chính xác record nào chúng ta delete, string contactId = (string)grdContact.DataKeys[e.RowIndex].Value; sau đó chúng ta query trong danh sách với id là giá trị record mà ta nhấn delete.
Sau khi delete xong, chúng ta load lại danh sách để xem sự thay đổi.
Chỉnh sửa 1 contact:
khi user click vào link edit bắt đầu chỉnh sửa 1 contact
protected void grdContact_RowEditing(object sender, System.Web.UI.WebControls.GridViewEditEventArgs e)
{
grdContact.EditIndex = e.NewEditIndex;
LoadContacts();
}
Không loại trừ trường hợp user cancel việc edit của mình:
protected void grdContact_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
grdContact.EditIndex = -1;
LoadContacts();
}
Một khi user hài lòng với thông tin mới của mình và click vào hyperlink update:
protected void grdContact_RowUpdating(object sender, System.Web.UI.WebControls.GridViewUpdateEventArgs e)
{
string contactId = (string)grdContact.DataKeys[e.RowIndex].Value;
string FilePath = Server.MapPath("~/App_Data/contact.xml");
string name = (grdContact.Rows[e.RowIndex].FindControl("txtName") as TextBox).Text.Trim();
string email = (grdContact.Rows[e.RowIndex].FindControl("txtEmail") as TextBox).Text.Trim();
XDocument doc = XDocument.Load(FilePath);
IEnumerable<XElement> contacts = doc.Element("contacts").Elements("contact");
var contact = (from c in contacts
where c.Attribute("id").Value.Equals(contactId) == true
select c).SingleOrDefault();
contact.SetAttributeValue("name", name);
contact.SetAttributeValue("email", email);
doc.Save(FilePath);
LoadContacts();
}
Các bạn có thể check out source code ta: http://code2code.googlecode.com/svn/trunk/CRUDLinq2Xml