将XML反序列化为C#,以便可以再次编辑和重新序列化值

时间:2015-02-13 12:36:39

标签: c# xml winforms xml-serialization xml-deserialization

我把一个窗体表格与前一个问题的一些(很多)帮助放在一起,可以找到here,这个表单从文本框中获取两个值并将它们存储在一个元组中,这个元组是存储为字典的值,而字典的键是从第三个文本框中获取的。该表单能够将字典keyvaluepairs序列化为XML文件,但我很难对XML文件进行反序列化,以便可以编辑和重新序列化keyvaluepairs。我有三个按钮添加提交和编辑,添加将用户输入的值添加到字典中,提交序列化字典keyvaluepairs和编辑将反序列化XML文件。我正在使用带有C#的Microsoft Visual Studio 2010。

问题摘要:

  1. 如何反序列化我的XML文件
  2. 如何编辑keyvaluepairs(可能使用列表框)
  3. 如何重新序列化(不确定我是否可以使用当前的当前序列化代码)
  4. 我希望我的“编辑”按钮通过单击反序列化XML文件,一旦点击我希望keyvaluepairs列在我设置的列表框(listbox1)中,如果已经点击了其中一个keyvaluepairs,那么特定值对应插入到三个相应的文本框中,如果用户编辑值,则可以使用“添加”按钮将更新的值添加回列表框,使用“提交”按钮可以将值对重新添加到列表框中序列

    如果我不清楚或者您需要更好的理解,请告诉我,以便澄清。

    我将在下面添加简化代码,以便更容易理解我想要做的事情:

        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);
                    }
                }
            }
        }
    

    感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:1)

您可以在程序开头读取序列化列表(如果有),然后在程序运行时根据需要更新列表。

如果要再次保存数据,可以重新序列化更新后的列表。

以下程序演示。它在开始时读入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;
            }
        }
    }
}