這是我第一次使用 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# 創建一個與這個 XML 一起作業的 WinForms。我正在做:
- 我閱讀了 XML 以獲得 XmlNodeList 變數。
- 從 XmlNodeList 我得到要修改為 XmlNode 變數的節點。
- 我在 XmlNode 上修改姓名或電話
- 我再次閱讀了 XML 檔案,并使用 XmlNode 變數新資訊更新了正確的節點。
我的問題是我不知道如何在我的 XmlNode 變數上添加(或洗掉)元素“phone2”。
程式.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;
}
}
我沒有找到正確的方法來做這件事,也許這不是最好的方法,但我接受建議......
uj5u.com熱心網友回復:
有多種方法可以處理 XML 檔案。我將在下面展示兩個選項。
測驗.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 指令:
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}");
}
}
要洗掉123458員工 id = 2 的電話號碼:
洗掉電話:
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(ex.Message);
throw ex;
}
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(寫入檔案),我們將使用以下方法:
序列化物件到XML檔案:
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(ex.Message);
throw ex;
}
}
用法(序列化):
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}");
}
}
要洗掉123458員工 id = 2 的電話號碼:
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 序列化示例
uj5u.com熱心網友回復:
最后我解決了改變:
程式.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);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/506802.html
上一篇:在同一串列中的專案之間進行互動C#(winforms)
下一篇:如何通過雙擊事件更改標簽文本?
