将 XML 反序列化为 C#,以便可以再次编辑和重新序列化值
Deserializing XML into C# so that the values can be edited and re-serialized again
我将我上一个问题的一些(很多)帮助放在了一个 windows 表格中,可以找到 ,这个表格从文本框中获取两个值并将它们存储在一个元组,这个元组存储为字典的值,而字典的键取自第三个文本框。该表单能够将字典键值对序列化为 XML 文件,但我很难反序列化 XML 文件,以便可以编辑和重新序列化键值对。我有三个按钮添加提交和编辑,添加将用户输入的值添加到字典中,提交序列化字典键值对,编辑将反序列化 XML 文件。我正在使用带有 C# 的 Microsoft Visual Studio 2010。
问题汇总:
- 如何反序列化我的 XML 文件
- 如何编辑键值对(可能使用列表框)
- 如何重新序列化(不确定我是否可以使用当前的序列化代码)
我希望我的编辑按钮通过单击反序列化 XML 文件,单击后我希望键值对列在我设置的列表框 (listbox1) 中,如果其中一个键值对已单击,该特定值对应插入到三个相应的文本框中,如果用户编辑值,则可以使用“添加”按钮将更新的值添加回列表框中,使用“提交”按钮值对可以重新序列化。
如果我不清楚或者您需要更好的理解,请告诉我,以便我澄清。
我将在下面包含简化的代码,以便更容易理解我想做什么:
namespace Test1
{
public partial class Adding : Form
{
Dictionary<string, Tuple<int, int>> d = new Dictionary<string, Tuple<int, int>>();
public Adding()
{
InitializeComponent();
}
public void btn_Add_Click(object sender, EventArgs e)
{
//Declare values for Tuple and Dictionary
int X_Co = Convert.ToInt32(XCoordinate.Text);
int Y_Co = Convert.ToInt32(YCoordinate.Text);
string B_ID = Convert.ToString(BeaconID.Text);
//Create new Tuple
var t = new Tuple<int, int>(X_Co, Y_Co);
//Add Beacon ID and X,Y coordinates from the tuple into the dictionary
if (!d.ContainsKey(B_ID))
{
d.Add(B_ID, t);//Make sure keys are unique
}
else
{
MessageBox.Show("Key already exists please enter a unique key.");
}
//Display dictionary values in the listbox
listBox1.DataSource = new BindingSource(d, null);
listBox1.DisplayMember = "Key,Value";
//listBox1.ValueMember = "Key";
}
public void btn_Submit_Click(object sender, EventArgs e)
{
List<Coordinate> cv = new List<Coordinate>();
foreach (KeyValuePair<string, Tuple<int, int>> entry in d)
{
Coordinate v = new Coordinate();
v.DateTime = DateTime.Now.ToString("dd/MM/yyyy hh/mm/ss");
v.BeaconID = entry.Key;
v.XCoordinate = entry.Value.Item1.ToString();
v.YCoordinate = entry.Value.Item2.ToString();
cv.Add(v);
}
SaveValues(cv);
MessageBox.Show("Coordinates were exported successfully", "Message");
}
public void btn_Edit_Click(object sender, EventArgs e)
{
}
public class Coordinate
{
public string DateTime { get; set; }
public string BeaconID { get; set; }
public string XCoordinate { get; set; }
public string YCoordinate { get; set; }
}
public void SaveValues(List<Coordinate> v)
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Coordinate>), new XmlRootAttribute("Coordinates"));
using (TextWriter textWriter = new StreamWriter(@"F:\Vista\Exporting into XML\Test1\Coordinates.xml", true))
{
serializer.Serialize(textWriter, v);
}
}
}
}
感谢您的所有帮助。
您可以在程序开始时读入您的序列化列表(如果有的话),然后在程序 运行s 期间根据需要更新列表。
当你想再次保存数据时,只需将更新后的列表重新序列化即可。
以下程序演示。它在开始时读取 List<Coordinate>
(如果 XML 文件不存在,则初始化一个空列表)。
然后它向列表中添加更多项目并打印出最后添加的项目的 BeaconID
。
最后它重新序列化新列表。
如果你 运行 这个程序几次(在将文件名更改为适合你的环境的名称之后),你会发现列表越来越大。
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace Demo
{
public class Coordinate
{
public string DateTime { get; set; }
public string BeaconID { get; set; }
public string XCoordinate { get; set; }
public string YCoordinate { get; set; }
}
public static class Program
{
public static void Main()
{
var date = DateTime.Now.ToString();
string filename = "D:\TMP\TEST.XML";
List<Coordinate> coords;
// Deserialize the existing list or create an empty one if none exists yet.
if (File.Exists(filename))
coords = DeserializeFromFile<List<Coordinate>>(filename);
else
coords = new List<Coordinate>();
// Add some new items to the list.
int n = coords.Count;
for (int i = 0; i < 5; ++i)
{
int j = n + i;
coords.Add(new Coordinate
{
DateTime = date,
BeaconID = "ID" + j,
XCoordinate = "X" + j,
YCoordinate = "Y" +j
});
}
// Print the BeaconID of the last item in the list.
Console.WriteLine(coords[coords.Count-1].BeaconID);
// Save the amended list.
SerializeToFile(coords, filename);
}
public static void SerializeToFile<T>(T item, string xmlFileName)
{
using (FileStream stream = new FileStream(xmlFileName, FileMode.Create, FileAccess.Write))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stream, item);
}
}
public static T DeserializeFromFile<T>(string xmlFileName) where T: class
{
using (FileStream stream = new FileStream(xmlFileName, FileMode.Open, FileAccess.Read))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return serializer.Deserialize(stream) as T;
}
}
}
}
我将我上一个问题的一些(很多)帮助放在了一个 windows 表格中,可以找到
问题汇总:
- 如何反序列化我的 XML 文件
- 如何编辑键值对(可能使用列表框)
- 如何重新序列化(不确定我是否可以使用当前的序列化代码)
我希望我的编辑按钮通过单击反序列化 XML 文件,单击后我希望键值对列在我设置的列表框 (listbox1) 中,如果其中一个键值对已单击,该特定值对应插入到三个相应的文本框中,如果用户编辑值,则可以使用“添加”按钮将更新的值添加回列表框中,使用“提交”按钮值对可以重新序列化。
如果我不清楚或者您需要更好的理解,请告诉我,以便我澄清。
我将在下面包含简化的代码,以便更容易理解我想做什么:
namespace Test1
{
public partial class Adding : Form
{
Dictionary<string, Tuple<int, int>> d = new Dictionary<string, Tuple<int, int>>();
public Adding()
{
InitializeComponent();
}
public void btn_Add_Click(object sender, EventArgs e)
{
//Declare values for Tuple and Dictionary
int X_Co = Convert.ToInt32(XCoordinate.Text);
int Y_Co = Convert.ToInt32(YCoordinate.Text);
string B_ID = Convert.ToString(BeaconID.Text);
//Create new Tuple
var t = new Tuple<int, int>(X_Co, Y_Co);
//Add Beacon ID and X,Y coordinates from the tuple into the dictionary
if (!d.ContainsKey(B_ID))
{
d.Add(B_ID, t);//Make sure keys are unique
}
else
{
MessageBox.Show("Key already exists please enter a unique key.");
}
//Display dictionary values in the listbox
listBox1.DataSource = new BindingSource(d, null);
listBox1.DisplayMember = "Key,Value";
//listBox1.ValueMember = "Key";
}
public void btn_Submit_Click(object sender, EventArgs e)
{
List<Coordinate> cv = new List<Coordinate>();
foreach (KeyValuePair<string, Tuple<int, int>> entry in d)
{
Coordinate v = new Coordinate();
v.DateTime = DateTime.Now.ToString("dd/MM/yyyy hh/mm/ss");
v.BeaconID = entry.Key;
v.XCoordinate = entry.Value.Item1.ToString();
v.YCoordinate = entry.Value.Item2.ToString();
cv.Add(v);
}
SaveValues(cv);
MessageBox.Show("Coordinates were exported successfully", "Message");
}
public void btn_Edit_Click(object sender, EventArgs e)
{
}
public class Coordinate
{
public string DateTime { get; set; }
public string BeaconID { get; set; }
public string XCoordinate { get; set; }
public string YCoordinate { get; set; }
}
public void SaveValues(List<Coordinate> v)
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Coordinate>), new XmlRootAttribute("Coordinates"));
using (TextWriter textWriter = new StreamWriter(@"F:\Vista\Exporting into XML\Test1\Coordinates.xml", true))
{
serializer.Serialize(textWriter, v);
}
}
}
}
感谢您的所有帮助。
您可以在程序开始时读入您的序列化列表(如果有的话),然后在程序 运行s 期间根据需要更新列表。
当你想再次保存数据时,只需将更新后的列表重新序列化即可。
以下程序演示。它在开始时读取 List<Coordinate>
(如果 XML 文件不存在,则初始化一个空列表)。
然后它向列表中添加更多项目并打印出最后添加的项目的 BeaconID
。
最后它重新序列化新列表。
如果你 运行 这个程序几次(在将文件名更改为适合你的环境的名称之后),你会发现列表越来越大。
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace Demo
{
public class Coordinate
{
public string DateTime { get; set; }
public string BeaconID { get; set; }
public string XCoordinate { get; set; }
public string YCoordinate { get; set; }
}
public static class Program
{
public static void Main()
{
var date = DateTime.Now.ToString();
string filename = "D:\TMP\TEST.XML";
List<Coordinate> coords;
// Deserialize the existing list or create an empty one if none exists yet.
if (File.Exists(filename))
coords = DeserializeFromFile<List<Coordinate>>(filename);
else
coords = new List<Coordinate>();
// Add some new items to the list.
int n = coords.Count;
for (int i = 0; i < 5; ++i)
{
int j = n + i;
coords.Add(new Coordinate
{
DateTime = date,
BeaconID = "ID" + j,
XCoordinate = "X" + j,
YCoordinate = "Y" +j
});
}
// Print the BeaconID of the last item in the list.
Console.WriteLine(coords[coords.Count-1].BeaconID);
// Save the amended list.
SerializeToFile(coords, filename);
}
public static void SerializeToFile<T>(T item, string xmlFileName)
{
using (FileStream stream = new FileStream(xmlFileName, FileMode.Create, FileAccess.Write))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stream, item);
}
}
public static T DeserializeFromFile<T>(string xmlFileName) where T: class
{
using (FileStream stream = new FileStream(xmlFileName, FileMode.Open, FileAccess.Read))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return serializer.Deserialize(stream) as T;
}
}
}
}