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

C# WinForms中XML节点的元素添加与删除实现问题

问题描述

我首次接触XML,正在用以下基础XML格式开发C# WinForms程序:

<root>
  <staff id="1">
    <name>name 1</name>
    <phone>123456</phone>
  </staff>
  <staff id="2">
    <name>name 2</name>
    <phone>123789</phone>
    <phone2>123789</phone2>
  </staff>
</root>

部分staff节点包含phone2这类额外元素。我已经实现了读取XML得到XmlNodeList、定位目标XmlNode并修改name/phone元素,但不知道如何在XmlNode中添加或删除phone2元素。现有代码如下,希望得到实现方法及优化建议:

Program.cs代码

public static XmlNode staff;
public static XmlNodeList xnList = GetList();

public static XmlNodeList GetList()
{
    XmlNodeList xnList;

    XmlDocument doc = new XmlDocument();
    doc.Load(path);
    xnList = doc.SelectNodes("/root/staff");

    return xnList;
}

public static void GetID(string id)
{
    foreach (XmlNode xn in xnList)
    {
        if(xn.Attributes["id"].Value == id)
        {
            staff = xn;
        }
    }
}

Form1.cs代码

private void btnOK_Click(object sender, EventArgs e)
{
   Program.staff["name"].InnerText = textBoxName.Text;
   Program.staff["phone"].InnerText = textBoxPhone.Text;
   
   if (Program.staff.SelectSingleNode("phone2") == null)
   {
      // 此处需创建phone2元素并赋值
      Program.staff["phone2"].InnerText = textBoxPhone2.Text;
   }
}

解决方案与优化建议

一、添加/删除phone2元素的实现方法

1. 添加phone2元素

当前代码直接访问Program.staff["phone2"]会报错,因为节点不存在。需要先创建元素再添加到staff节点:

private void btnOK_Click(object sender, EventArgs e)
{
   Program.staff["name"].InnerText = textBoxName.Text;
   Program.staff["phone"].InnerText = textBoxPhone.Text;
   
   XmlNode phone2Node = Program.staff.SelectSingleNode("phone2");
   if (phone2Node == null)
   {
      // 从staff节点获取所属的XmlDocument实例
      XmlDocument doc = Program.staff.OwnerDocument;
      // 创建phone2元素
      XmlElement phone2Element = doc.CreateElement("phone2");
      phone2Element.InnerText = textBoxPhone2.Text;
      // 将元素添加到staff节点下
      Program.staff.AppendChild(phone2Element);
   }
   else
   {
      // 若phone2已存在,直接更新值
      phone2Node.InnerText = textBoxPhone2.Text;
   }

   // 保存修改后的XML文档
   Program.staff.OwnerDocument.Save(path);
}

2. 删除phone2元素

如果要删除已存在的phone2,可以这样实现:

XmlNode phone2Node = Program.staff.SelectSingleNode("phone2");
if (phone2Node != null)
{
   Program.staff.RemoveChild(phone2Node);
   // 保存修改
   Program.staff.OwnerDocument.Save(path);
}

二、现有代码的优化建议

1. 避免静态成员存储XML节点

当前Program类的staff和xnList都是静态成员,在WinForms多线程或多次操作场景下易引发问题。建议改为实例化管理,或者将XmlDocument作为核心对象,而非单独存储节点列表和选中节点。

2. 优化GetID方法

  • 找到目标节点后立即跳出循环,无需遍历全部节点
  • 增加空值判断,避免xn.Attributes["id"]为null时抛出异常:
public static XmlNode GetStaffById(string id)
{
    foreach (XmlNode xn in xnList)
    {
        XmlAttribute idAttr = xn.Attributes["id"];
        if(idAttr != null && idAttr.Value == id)
        {
            return xn;
        }
    }
    return null; // 找不到节点时返回null,调用方可做判断
}

调用示例:

XmlNode targetStaff = Program.GetStaffById("1");
if(targetStaff != null)
{
   // 执行修改操作
}

3. 统一管理XML文档

建议将XmlDocument作为全局可访问对象,避免每次GetList都重新加载文件,减少IO操作:

public static XmlDocument XmlDoc { get; private set; }
public static XmlNodeList StaffList { get; private set; }

public static void LoadXml()
{
    XmlDoc = new XmlDocument();
    XmlDoc.Load(path);
    StaffList = XmlDoc.SelectNodes("/root/staff");
}

程序启动时调用Program.LoadXml(),后续操作基于该XmlDoc实例。

4. 增加异常处理

XML加载、节点操作过程中可能出现文件不存在、格式错误等问题,建议添加try-catch块避免程序崩溃:

try
{
    XmlDoc.Load(path);
}
catch (FileNotFoundException ex)
{
    MessageBox.Show($"XML文件未找到:{ex.Message}");
}
catch (XmlException ex)
{
    MessageBox.Show($"XML格式错误:{ex.Message}");
}

内容的提问来源于stack exchange,提问作者T.S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:25:17