ASP.NET中XML子节点更新失败问题求助
表单更新XML子节点异常:字段为空或显示控件类型名
我尝试通过表单新数据更新XML文件的子节点,现有逻辑是:若XML文件存在则读取数据到表单字段;若不存在则创建新XML并添加子节点。但更新子节点时,要么得到System.Web.UI.WebControls.TextBox字样,要么字段为空;尝试删除原有子节点再重建,新节点仍为空。请帮忙分析原因。
现有XML文件内容
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <CGTemplateDATA> <title>Title here</title> <text>Text here</text> <reference>Reference here</reference> </CGTemplateDATA>
我的ASPX代码
<%@ Page Language="C#" Debug="true" %> <%@ Import Namespace="System.Xml" %> <script runat="server"> protected void Save(object sender, EventArgs e) { //this.txtReference.Text = DateTime.Now.ToString("hh:mm:ss"); this.txtReference.Text = "Læs mere på tvsyd.dk"; } protected void Page_Load(object sender, EventArgs e) { string xmlPath = MapPath("xml/feed.xml"); XmlDocument xmldoc = new XmlDocument(); if (System.IO.File.Exists(xmlPath)) { xmldoc.Load(xmlPath); XmlNode nodeTitle = xmldoc.DocumentElement.SelectSingleNode("title"); txtTitle.Text = nodeTitle.InnerText; XmlNode nodeText = xmldoc.DocumentElement.SelectSingleNode("text"); txtText.Text = nodeText.InnerText; XmlNode nodeRef = xmldoc.DocumentElement.SelectSingleNode("reference"); txtReference.Text = nodeRef.InnerText; lblResult.Text = "Opdater teksten i XML dokumentet"; } } </script> <script runat="server"> protected void btnSave_Click(object sender, EventArgs e) { string xmlPath = MapPath("xml/feed.xml"); XmlDocument doc = new XmlDocument(); //Check if the file already exists or not if (System.IO.File.Exists(xmlPath)) { //XmlDocument doc = new XmlDocument(); doc.Load(xmlPath); XmlNode nodeTitle = doc.SelectSingleNode("/CGTemplateDATA/title"); XmlNode nodeText = doc.SelectSingleNode("/CGTemplateDATA/text"); XmlNode nodeReference = doc.SelectSingleNode("/CGTemplateDATA/reference"); XmlNode parent = doc.SelectSingleNode("/CGTemplateDATA"); parent.RemoveChild(nodeTitle); parent.RemoveChild(nodeText); parent.RemoveChild(nodeReference); XmlNode parentNode = CreateNewBookNode(doc); //Append the cgtemplatedata node to the document doc.AppendChild(parentNode); doc.Save(xmlPath); } else { XmlNode declarationNode = doc.CreateXmlDeclaration("1.0", "utf-8", "yes"); doc.AppendChild(declarationNode); XmlNode bookNode = CreateBookNode(doc); //Append the cgtemplatedata node to the document doc.AppendChild(bookNode); lblResult.Text = "XML dokumentet er hermed oprettet"; doc.Save(xmlPath); } } XmlNode CreateBookNode(XmlDocument doc) { XmlNode bookNode = doc.CreateElement("CGTemplateDATA"); //Add all the children of the book node XmlNode titleNode = doc.CreateElement("title"); titleNode.InnerText = txtTitle.Text; bookNode.AppendChild(titleNode); XmlNode textNode = doc.CreateElement("text"); textNode.InnerText = txtText.Text; bookNode.AppendChild(textNode); XmlNode referenceNode = doc.CreateElement("reference"); referenceNode.InnerText = txtReference.Text; bookNode.AppendChild(referenceNode); return bookNode; } XmlNode CreateNewBookNode(XmlDocument doc) { XmlNode parentNode = doc.SelectSingleNode("/CGTemplateDATA"); XmlNode titleNode = doc.CreateElement("title"); titleNode.InnerText = txtTitle.Text; parentNode.AppendChild(titleNode); XmlNode textNode = doc.CreateElement("text"); textNode.InnerText = txtText.Text; parentNode.AppendChild(textNode); XmlNode referenceNode = doc.CreateElement("reference"); referenceNode.InnerText = txtReference.Text; parentNode.AppendChild(referenceNode); return parentNode; } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Storke-TV tekst</title> <link href="css/stylesheet.css" rel="stylesheet" type="text/css" /> </head> <body> <form id="form1" runat="server"> <div> <img alt="" class="style5" src="images/storke_tekst_top.png" /><br /> <br /> <table> <tr> <td colspan="2" style="width: 586px"> <b>FORSIGTIG! Denne side giver direkte adgang til at opdatere storke tekst.</b><br /> <br /> 1: Udfyld felterne.<br /> 2: Tryk på GEM TEKST.<br /> 3: Hvis du vil opdatere teksten, så ret den, og tryk på GEM TEKST igen.<br /> </td> </tr> <tr> <td colspan="2" style="width: 586px"> </td> </tr> <tr> <td style="width: 85px; height: 40px"> Overskrift: </td> <td style="width: 501px; height: 40px"> <asp:TextBox ID="txtTitle" runat="server" Width="182px" Height="28px" Text="temp" /> </td> </tr> <tr> <td style="width: 85px; height: 41px"> Tekst: </td> <td style="width: 501px; height: 152px"> <asp:TextBox ID="txtText" Textmode="Multiline" runat="server" Width="240px" height="150" /> </td> </tr> <tr> <td style="width: 85px; height: 41px"> Henvisning: </td> <td style="width: 501px; height: 54px"> <asp:TextBox ID="txtReference" Textmode="Multiline" runat="server" Width="240px" Height="42px" /> < <asp:Button Text="Indsæt web henvisning" runat="server" ID="btnReftxt" Width="142px" Height="24" font-size="12px" OnClick="Save" /> </td> </tr> <tr> <td style="width: 85px; height: 41px"> </td> <td style="width: 586px; height: 52px"> <asp:Button Text="GEM TEKST" runat="server" ID="btnSave" Width="240px" Height="40" OnClick="btnSave_Click" /> </td> </tr> <tr> <td style="width: 85px; height: 41px"> </td> <td style="width: 586px; height: 41px"> <asp:Label Text="Gem tekst" runat="server" ID="lblResult" Width="295px"></asp:Label> </td> </tr> </table> </div> </form> </body> </html>
问题原因分析与修复方案
1. Page_Load未判断PostBack,表单新值被覆盖
Page_Load在每次页面请求(包括按钮触发的PostBack)都会执行。点击保存时,Page_Load会先从XML读取旧数据,覆盖用户输入的新值,导致保存的还是旧内容,看起来像字段未更新或为空。
修复代码:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { string xmlPath = MapPath("xml/feed.xml"); XmlDocument xmldoc = new XmlDocument(); if (System.IO.File.Exists(xmlPath)) { xmldoc.Load(xmlPath); XmlNode nodeTitle = xmldoc.DocumentElement.SelectSingleNode("title"); txtTitle.Text = nodeTitle.InnerText; XmlNode nodeText = xmldoc.DocumentElement.SelectSingleNode("text"); txtText.Text = nodeText.InnerText; XmlNode nodeRef = xmldoc.DocumentElement.SelectSingleNode("reference"); txtReference.Text = nodeRef.InnerText; lblResult.Text = "Opdater teksten i XML dokumentet"; } } }
2. 更新逻辑错误,重复添加根节点
在更新分支中,删除子节点后调用CreateNewBookNode获取根节点,再执行doc.AppendChild(parentNode),会导致XML中新增重复的<CGTemplateDATA>根节点,而非更新原有节点。
修复更新分支代码:
if (System.IO.File.Exists(xmlPath)) { doc.Load(xmlPath); XmlNode parent = doc.SelectSingleNode("/CGTemplateDATA"); // 直接修改现有节点文本,无需删除重建 parent.SelectSingleNode("title").InnerText = txtTitle.Text; parent.SelectSingleNode("text").InnerText = txtText.Text; parent.SelectSingleNode("reference").InnerText = txtReference.Text; doc.Save(xmlPath); lblResult.Text = "XML dokumentet er opdateret"; }
3. 控件名异常的原因
出现System.Web.UI.WebControls.TextBox字样,是因为误将控件对象直接赋值给InnerText(比如写了titleNode.InnerText = txtTitle而非txtTitle.Text),确保所有赋值都使用控件的.Text属性即可避免。
内容的提问来源于stack exchange,提问作者Tue Sandbæk
相关产品推荐
相关产品推荐

