【问题标题】:Create a XML Serialization and Deserialization for generic list in C# windows form application?在 C# windows 窗体应用程序中为通用列表创建 XML 序列化和反序列化?
【发布时间】:2013-07-23 13:36:00
【问题描述】:

我试过这样的代码.....

//序列化

private void Serialize_Click(object sender, EventArgs e)
        {
            List<Personal> pdetails = new List<Personal>();
            Personal personals = new Personal
            {
                ID = int.Parse(txtsno.Text),
                Name = txtname.Text,
                Phone = long.Parse(txtpno.Text),
                Address = txtaddr.Text
            };
            pdetails.Add(personals);

 XmlSerializer xmlser = new XmlSerializer(typeof(List<Personal>));
            StreamWriter swtr = new StreamWriter(@"f:\serialize.xml");
            xmlser.Serialize(swtr, pdetails);
            swtr.Close();
 }

//反序列化

private void button3_Click(object sender, EventArgs e)
        {
            XmlSerializer xmlser = new XmlSerializer(typeof(List<Personal>));
            StreamReader srdr = new StreamReader(@"f:\serialize.xml");
            List<Personal>p = (List<Personal>)xmlser.Deserialize(srdr);
            srdr.Close();
        }

但我想要动态 xml 序列化和反序列化...

即当我序列化要添加到 xml 文档中的对象时.. 两个或更多输入数据....

但我也输入了创建 xml 文件的详细信息......但我的探针无法将另一个输入数据输入到现有文件本身......

为此,我想使用内存流..如何使用内存流通过单击按钮在 xml 中写入更多输入..

如何反序列化以获取 xml 到对象...

【问题讨论】:

  • 我无法理解你的问题。你想要动态序列化吗?将新的Personal 插入到 xml 文件中序列化的现有List&lt;Presonanl&gt; 的方法(方法 DynamicInsert(xml_file, PersonalObj))?
  • 动态序列化意味着,在序列化中,第一次输入详细信息意味着对象正确创建 xml 文件没有问题。第二次输入详细信息意味着它覆盖了我第一次输入的数据。 .. 在反序列化中,我收到这样的错误“XML 文档 (2, 2) 中存在错误。”
  • 如果您需要在关闭和打开应用程序后保存数据,我会从我的回答中推荐解决方案 1。否则,您需要说明何时以及为什么要序列化和反序列化数据。

标签: c# .net xml-serialization xml-deserialization


【解决方案1】:

你必须有一个基类来展示你的数据,这就是一个例子:

  [XmlIncludeAttribute(typeof(ConcreteFooOne))]
  [XmlIncludeAttribute(typeof(ConcreteFooTwo))]
  [XmlIncludeAttribute(typeof(ConcreteFooThree))]
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]  
  public abstract partial class AbstractFoo
  {

  }

  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]

  public class ConcreteFooOne : AbstractFoo
  {
    public string MyProp { get; set; }
  }
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]

  public class ConcreteFooTwo : AbstractFoo
  {

  }
  [XmlRoot(ElementName = "FooData", Namespace = "http://foo.bar")]

  public class ConcreteFooThree : AbstractFoo
  {

}


class Program
  {
    static void Main()
    {          

      XmlSerializer xs = new XmlSerializer(typeof(List<AbstractFoo>));
      TextWriter writer = new StreamWriter("test.txt", false);
      var list = new List<AbstractFoo>();
      list.Add(new ConcreteFooOne() { MyProp = "test" });
      list.Add(new ConcreteFooTwo() );
      list.Add(new ConcreteFooThree());
      xs.Serialize(writer, list);

      writer.Close();

      StreamReader srdr = new StreamReader("test.txt");
      var lst = (List<AbstractFoo>)xs.Deserialize(srdr);
      srdr.Close();          
    }
  }

【讨论】:

  • 感谢 houssem....但是我无法从中获得解决方案....我想从序列化创建 xml 文件,即对象到 xml。在反序列化中,xml转为对象。
【解决方案2】:

我认为您的问题不在于序列化本身,而在于同步。

我可以看到几个可能的解决方案:

  1. 关闭时序列化和打开应用时反序列化。您可以将序列化部分移动到表单的 OnClose 事件,并将反序列化部分移动到构造函数。这样在序列化过程中添加额外数据就没有问题

  2. 进程同步。您可以在序列化仍未完成时阻止添加新数据。之后,您可以取消阻止。另一种解决方案可能是拥有pdetails 的副本。这样你就可以序列化副本。序列化会将pdetails 复制到pdetails_copy 并序列化pdetails_copy 并检查pdetails 中是否有新数据。如果是这样,它将再次进行序列化。

【讨论】:

  • @siva 我听不懂
猜你喜欢
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
  • 2011-06-28
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
相关资源
最近更新 更多