在XMLNode c#上创建/删除元素



这是我第一次使用XML,我使用了一种基本的XML文件格式,如下所示:

<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>

一些节点具有更多的元素(在本例中为phone2(。我想在节点上添加(或删除(一个元素。我正在用C#创建一个WinForms来处理这个XML。我在做:

  • 我读取XML以获得XmlNodeList变量
  • 从XmlNodeList中,我获得了要修改为XmlNode变量的节点
  • 我在XmlNode上修改名称或电话
  • 我再次读取了XML文件,并使用XmlNode变量new info更新了正确的节点

我的问题是我不知道如何添加(或删除(元素";电话2";在我的XmlNode变量上。

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)
{
// here I want to create "phone2" in Program.staff if not exist
// to update XML file later.
Program.staff["phone2"].InnerText = textBoxPhone2.Text;
}

}

我找不到正确的方法,也许这不是最好的方法,但我接受建议。。。

使用XML文件有多种方法。我将在下面显示两个选项。

Test.xml:

<root>
<staff id="1">
<name>Name 1</name>
<phone>123456</phone>
</staff>
<staff id="2">
<name>Name 2</name>
<phone>123457</phone>
<phone>123458</phone>
</staff>
</root>

选项1(LINQ to XML(:

使用指令添加以下内容

  • using System.Xml.Linq;

CreateXmlLinq:

private void CreateXmlLinq(string filename)
{
XElement root = new XElement("root",
new XElement("staff", new XAttribute("id", "1"),
new XElement("name", "Name 1"),
new XElement("phone", "123456")),
new XElement("staff", new XAttribute("id", "2"),
new XElement("name", "Name 2"),
new XElement("phone", "123457"),
new XElement("phone", "123458"))
);
root.Save(filename);
}

用法

using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.Filter = "XML File (*.xml)|*.xml";
sfd.FileName = "Test.xml";
if (sfd.ShowDialog() == DialogResult.OK)
{
//save to file
CreateXmlLinq(sfd.FileName);
Debug.WriteLine($"Info: Saved to {sfd.FileName}");
}
}

删除员工id为2:的电话号码123458

删除手机

private void RemovePhone(string filename, string id, string phoneNumber)
{
//load from file
XElement root = XElement.Load(filename);
//remove specified phone number
root.Elements("staff").Where(s => s.Attribute("id").Value == id).Elements("phone").Where(p => p.Value == phoneNumber).Remove();
//save to file
root.Save(filename);
}

选项2(XML序列化(:

对于这种方法,我们将使用嵌套类。

向每个类添加以下using指令

  • using System.Collections.Generic;
  • using System.Xml;
  • using System.Xml.Serialization;

你可以随心所欲地命名类,我选择了在前面加一个词"Xml";。此外,对于嵌套类,我选择附加祖先的名称。在这种情况下,只有一个祖先(父母(";根";。

  • XmlRoot
  • XmlRootStaff:("XmlRoot"+"Staff"(

XmlRoot.cs:

[XmlRoot(ElementName = "root", IsNullable = false)]
public class XmlRoot
{
[XmlElement(ElementName = "staff")]
public List<XmlRootStaff> Staff { get; set; } = new List<XmlRootStaff>();
}

XmlRootStaff.cs

public class XmlRootStaff
{
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "phone")]
public List<string> Phone { get; set; } = new List<string>();
}

要反序列化XML(从文件读取(,我们将使用以下方法:

反序列化XMLFileToObject

public static T DeserializeXMLFileToObject<T>(string xmlFilename)
{
T rObject = default(T);
try
{
if (string.IsNullOrEmpty(xmlFilename))
{
return default(T);
}
using (System.IO.StreamReader xmlStream = new System.IO.StreamReader(xmlFilename))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
rObject = (T)serializer.Deserialize(xmlStream);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error (DeserializeXMLFileToObject) - {ex.Message}");
throw;
}
return rObject;
}

用法(反序列化(:

private XmlRoot _root = null;
...
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "XML File (*.xml)|*.xml";
ofd.FileName = "Test.xml";
if (ofd.ShowDialog() == DialogResult.OK)
{
//deserialize
_root = HelperXml.DeserializeXMLFileToObject<XmlRoot>(ofd.FileName);
}
}

要序列化XML(写入文件(,我们将使用以下方法:

SerializeObjectToXMLFile:

public static void SerializeObjectToXMLFile(object obj, string xmlFilename)
{
try
{
if (string.IsNullOrEmpty(xmlFilename))
{
return;
}//if
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
settings.OmitXmlDeclaration = false;
settings.Indent = true;
settings.NewLineHandling = System.Xml.NewLineHandling.Entitize;
using (System.Xml.XmlWriter xmlWriter = System.Xml.XmlWriter.Create(xmlFilename, settings))
{
//specify namespaces
System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add(string.Empty, "urn:none");
//create new instance
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
//write XML to file
serializer.Serialize(xmlWriter, obj, ns);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error (SerializeObjectToXMLFile) - {ex.Message}");
throw;
}
}

用法(serialize(:

private XmlRoot _root = null;
...
using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.Filter = "XML File (*.xml)|*.xml";
sfd.FileName = "Test.xml";
if (sfd.ShowDialog() == DialogResult.OK)
{
//create new instance
_root = new XmlRoot();
//add data
_root.Staff.Add(new XmlRootStaff() { Id = "1", Name = "Name 1", Phone = new List<string>() { "123456" } });
_root.Staff.Add(new XmlRootStaff() { Id = "2", Name = "Name 2", Phone = new List<string>() { "123457", "123458" } });
//serialize - save to file
SerializeObjectToXMLFile(_root, sfd.FileName);
Debug.WriteLine($"Info: Saved to {sfd.FileName}");
}
}

删除员工id为2:的电话号码123458

private void RemovePhone(string id, string phoneNumber)
{
if (_root != null)
{
for (int i = 0; i < _root.Staff.Count; i++)
{
if (_root.Staff[i].Id == id)
{
//remove
_root.Staff[i].Phone.Remove(phoneNumber);
break;
}
}
}
}

资源

  • LINQ to XML概述
  • XElement.Save方法
  • 如何从XElement中删除特定节点
  • XML序列化
  • XML序列化示例

最后我解决了更改:

程序.cs

public static XmlDocument doc = new XmlDocument(); // ADDED THIS HERE
public static XmlNode staff;
public static XmlNodeList xnList = GetList();
public static XmlNodeList GetList()
{
XmlNodeList xnList;
// REMOVED XmlDocument from HERE
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)
{
XmlElement elem = Program.doc.CreateElement("phone2");
elem.InnerText = textBoxPhone2.Text;
Program.staff.AppendChild(elem);
}
}

最新更新