DataList绑定xml数据,并实现删除和修改
在网络上看到很多朋友在求datalist或是repeater控件绑定xml数据源的例子,在这里整理了一下,以datalist为便写了一个DEMO.
有xml文档:
<?xml version="1.0" encoding="utf-8" ?>
<music>
<Entry>
<Title> 千里之外 - 周杰伦 </Title>
<Ref href="http://www.lzpcc.com.cn/268316.wma" />
</Entry>
<Entry>
<Title> 听妈妈的话 - 周杰伦 </Title>
<Ref href="http://wma.1ting.com/wmam/2.wma" />
</Entry>
</music>
<music>
<Entry>
<Title> 千里之外 - 周杰伦 </Title>
<Ref href="http://www.lzpcc.com.cn/268316.wma" />
</Entry>
<Entry>
<Title> 听妈妈的话 - 周杰伦 </Title>
<Ref href="http://wma.1ting.com/wmam/2.wma" />
</Entry>
</music>
页面代码:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Xml"%>
<%@ Import Namespace="System.Xml.XPath"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
private XmlDocument doc = new XmlDocument();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
bind();
}
}
protected void bind()
{
//XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("x1.xml"));
XmlNodeList nodes = doc.SelectNodes("music/Entry");
DataList1.DataSource = nodes;
DataList1.DataBind();
}
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
switch(e.CommandName)
{
case "edit":
DataList1.EditItemIndex = e.Item.ItemIndex;
bind(); break;
case "cancel":
DataList1.EditItemIndex = -1;
bind(); break;
case "dele":
doc.Load(Server.MapPath("x1.xml"));
XmlNode node=doc.SelectSingleNode("/music/Entry/Ref[@href='"+e.CommandArgument+"']");
node.ParentNode.ParentNode.RemoveChild(node.ParentNode);
doc.Save(Server.MapPath("x1.xml"));
bind(); break;
case "update":
doc.Load(Server.MapPath("x1.xml"));
XmlNode xnode = doc.SelectSingleNode("/music/Entry/Ref[@href='" + e.CommandArgument + "']");
XmlElement elem1 = xnode as XmlElement;
elem1.SetAttribute("href", ((TextBox)e.Item.FindControl("tb2")).Text);
doc.Save(Server.MapPath("x1.xml"));
DataList1.EditItemIndex = -1;
bind(); break;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>datalist绑定xml</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DataList ID="DataList1" EnableViewState="true" runat="server" OnItemCommand="DataList1_ItemCommand" >
<HeaderTemplate>
<table>
<tr>
<td>歌曲名称</td>
<td>歌曲地址</td>
<td>操作</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%#((XmlNode)Container.DataItem)["Title"].InnerText%> </td>
<td><%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%> </td>
<td>
<asp:LinkButton ID="ltn1" Text="编辑" runat="server" CommandName="edit" CommandArgument='<%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%>'></asp:LinkButton>
<asp:LinkButton Text="删除" ID="ltn2" runat="server" CommandName="dele" CommandArgument='<%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%>'></asp:LinkButton>
</td>
</tr>
</ItemTemplate>
<EditItemTemplate>
<tr>
<td><asp:TextBox ID="tb1" runat="server" Text='<%#((XmlNode)Container.DataItem)["Title"].InnerText%>'></asp:TextBox></td>
<td><asp:TextBox ID="tb2" runat="server" Text='<%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%>'></asp:TextBox></td>
<td>
<asp:LinkButton ID="ltn3" runat="server" CommandArgument='<%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%>' CommandName="update">保存</asp:LinkButton>
<asp:LinkButton ID="ltn4" runat="server" CommandName="cancel">取消</asp:LinkButton></td>
</tr>
</EditItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:DataList>
</div>
</form>
</body>
</html>
<%@ Import Namespace="System.Xml"%>
<%@ Import Namespace="System.Xml.XPath"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
private XmlDocument doc = new XmlDocument();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
bind();
}
}
protected void bind()
{
//XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("x1.xml"));
XmlNodeList nodes = doc.SelectNodes("music/Entry");
DataList1.DataSource = nodes;
DataList1.DataBind();
}
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
switch(e.CommandName)
{
case "edit":
DataList1.EditItemIndex = e.Item.ItemIndex;
bind(); break;
case "cancel":
DataList1.EditItemIndex = -1;
bind(); break;
case "dele":
doc.Load(Server.MapPath("x1.xml"));
XmlNode node=doc.SelectSingleNode("/music/Entry/Ref[@href='"+e.CommandArgument+"']");
node.ParentNode.ParentNode.RemoveChild(node.ParentNode);
doc.Save(Server.MapPath("x1.xml"));
bind(); break;
case "update":
doc.Load(Server.MapPath("x1.xml"));
XmlNode xnode = doc.SelectSingleNode("/music/Entry/Ref[@href='" + e.CommandArgument + "']");
XmlElement elem1 = xnode as XmlElement;
elem1.SetAttribute("href", ((TextBox)e.Item.FindControl("tb2")).Text);
doc.Save(Server.MapPath("x1.xml"));
DataList1.EditItemIndex = -1;
bind(); break;
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>datalist绑定xml</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DataList ID="DataList1" EnableViewState="true" runat="server" OnItemCommand="DataList1_ItemCommand" >
<HeaderTemplate>
<table>
<tr>
<td>歌曲名称</td>
<td>歌曲地址</td>
<td>操作</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%#((XmlNode)Container.DataItem)["Title"].InnerText%> </td>
<td><%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%> </td>
<td>
<asp:LinkButton ID="ltn1" Text="编辑" runat="server" CommandName="edit" CommandArgument='<%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%>'></asp:LinkButton>
<asp:LinkButton Text="删除" ID="ltn2" runat="server" CommandName="dele" CommandArgument='<%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%>'></asp:LinkButton>
</td>
</tr>
</ItemTemplate>
<EditItemTemplate>
<tr>
<td><asp:TextBox ID="tb1" runat="server" Text='<%#((XmlNode)Container.DataItem)["Title"].InnerText%>'></asp:TextBox></td>
<td><asp:TextBox ID="tb2" runat="server" Text='<%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%>'></asp:TextBox></td>
<td>
<asp:LinkButton ID="ltn3" runat="server" CommandArgument='<%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%>' CommandName="update">保存</asp:LinkButton>
<asp:LinkButton ID="ltn4" runat="server" CommandName="cancel">取消</asp:LinkButton></td>
</tr>
</EditItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:DataList>
</div>
</form>
</body>
</html>
功能实现,现在来说下原理
我们在把sql server数据绑定到datalist时,实际是绑定的一个记录集,而把xml数据绑定到datalist也是一样,只不过它不是记录集,而是一个节点集.
doc.Load(Server.MapPath("x1.xml"));
XmlNodeList nodes = doc.SelectNodes("music/Entry");
DataList1.DataSource = nodes;
DataList1.DataBind();
XmlNodeList nodes = doc.SelectNodes("music/Entry");
DataList1.DataSource = nodes;
DataList1.DataBind();
声明好绑定的节点集以后,我们在前台还要想写相应的前台绑定模板列
<td><%#((XmlNode)Container.DataItem)["Title"].InnerText%> </td>
<td><%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%> </td>
<td><%#((XmlNode)Container.DataItem)["Ref"].GetAttribute("href").ToString()%> </td>
我们在前台就提到,我们的datalist绑定的为一个节点集,所以我们需要把Container.DataItem转换为一个XmlNode,我们是分别想绑定其title节点值,和Ref的href属性值所以其上面分别表达为以上两种形式.
其实只绑定好了,其删除和修改功能就显得相对简单了,在绑定sql 数据源是分别为删除和修改记录,而在这里就分别是删除和修改节点.
switch(e.CommandName)
{
case "edit":
DataList1.EditItemIndex = e.Item.ItemIndex;
bind(); break;
case "cancel":
DataList1.EditItemIndex = -1;
bind(); break;
case "dele":
doc.Load(Server.MapPath("x1.xml"));
XmlNode node=doc.SelectSingleNode("/music/Entry/Ref[@href='"+e.CommandArgument+"']");
node.ParentNode.ParentNode.RemoveChild(node.ParentNode);
doc.Save(Server.MapPath("x1.xml"));
bind(); break;
case "update":
doc.Load(Server.MapPath("x1.xml"));
XmlNode xnode = doc.SelectSingleNode("/music/Entry/Ref[@href='" + e.CommandArgument + "']");
XmlElement elem1 = xnode as XmlElement;
elem1.SetAttribute("href", ((TextBox)e.Item.FindControl("tb2")).Text);
doc.Save(Server.MapPath("x1.xml"));
DataList1.EditItemIndex = -1;
bind(); break;
}
{
case "edit":
DataList1.EditItemIndex = e.Item.ItemIndex;
bind(); break;
case "cancel":
DataList1.EditItemIndex = -1;
bind(); break;
case "dele":
doc.Load(Server.MapPath("x1.xml"));
XmlNode node=doc.SelectSingleNode("/music/Entry/Ref[@href='"+e.CommandArgument+"']");
node.ParentNode.ParentNode.RemoveChild(node.ParentNode);
doc.Save(Server.MapPath("x1.xml"));
bind(); break;
case "update":
doc.Load(Server.MapPath("x1.xml"));
XmlNode xnode = doc.SelectSingleNode("/music/Entry/Ref[@href='" + e.CommandArgument + "']");
XmlElement elem1 = xnode as XmlElement;
elem1.SetAttribute("href", ((TextBox)e.Item.FindControl("tb2")).Text);
doc.Save(Server.MapPath("x1.xml"));
DataList1.EditItemIndex = -1;
bind(); break;
}
其主要过程就是查找节点,删除/修改节点或是属性值.
我们通过XPath表达式来查询节点.因为考虑到其src为唯一值,所以把其值作为参数,在前面绑定时我们已经指定了CommandArgument.所以我们的XPath表达式记为"/music/Entry/Ref[@href='" + e.CommandArgument + "']"
含义为选择href属性为 e.CommandArgument 的Ref节点.不过在删除节点时,我们想要删除的是整个Entry节点
所以我们需要以这种方式表示:node.ParentNode.ParentNode.RemoveChild(node.ParentNode);
修改完成以后,则保存文件,重新绑定数据.
整操作完成.