You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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">&nbsp;</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" />
                    &nbsp;<&nbsp;<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">
                    &nbsp;
                </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">
                    &nbsp;
                </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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:49:58