【问题标题】:XML serializer in a loop循环中的 XML 序列化程序
【发布时间】:2018-06-18 13:16:42
【问题描述】:

我正在尝试序列化来自 dataGridView 的数据,我将其放入一个类中,然后写入文件。但是,我有一个问题,序列化程序会将每个对象放在它自己的“文件”中,而不是将所有对象放在一个中;当我打开 .xml 文件时,你可以看到:

<?xml version="1.0" encoding="utf-8"?>
  <MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Id>1</Id>
    <Column1>XXX</Column1>
    <Column2>YYY</Column2>
  </MyClass>
<?xml version="1.0" encoding="utf-8"?>
  <MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Id>2</Id>
    <Column1>ZZZ</Column1>
    <Column2>AAA</Column2>
  </MyClass>

这是我用来序列化的代码。我该如何解决这个问题,这样当我打开 .xml 文件时,我只会得到一个文件,而不是像上面那样拆分?我是否必须将所有对象添加到列表中,然后从列表中写入?

private void expXML_Click(object sender, EventArgs e)
    {
        XmlSerializer ser = new XmlSerializer(typeof(MyClass));
        TextWriter writer = new StreamWriter("Filename.XML");
        for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
        {
            MyClass abc = new MyClass(Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value), dataGridView1.Rows[i].Cells[1].Value.ToString(), dataGridView1.Rows[i].Cells[2].Value.ToString());
            ser.Serialize(writer, abc);
        }
        writer.Close();
    }

【问题讨论】:

  • 您必须创建一个类作为根元素并包含所有数据作为集合。您的 xml 中不能有多个根元素。
  • Do I have to add all the objects into a list and then write from the list? 似乎您可能已经回答了您自己的问题,否则您可以围绕所有类创建一个包装器并按照@HimBromBeere 的建议序列化该包装器
  • 正如@HimBromBeere 所说,创建另一个拥有 MyClass 类型的 List 属性的类并将每个对象添加到该列表中,然后在该根类上使用序列化

标签: c# xml winforms


【解决方案1】:

好吧,我听从了建议和自己的预感;这是正确序列化数据的编辑代码:

private void expXML_Click(object sender, EventArgs e)
{
    List<MyClass> newList = new List<MyClass>();
    XmlSerializer ser = new XmlSerializer(typeof(List<MyClass>));
    TextWriter writer = new StreamWriter("Filename.XML");
    for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
    {
        MyClass abc = new MyClass(Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value), dataGridView1.Rows[i].Cells[1].Value.ToString(), dataGridView1.Rows[i].Cells[2].Value.ToString());
        newList.add(abc);            
    }
    ser.Serialize(writer, newList);
    writer.Close();
}

【讨论】:

  • 比我的答案更好
【解决方案2】:

试试这个

private class MyClassList
{
   IEnumerable<MyClass> Root{  get;  set;}
}

private void expXML_Click(object sender, EventArgs e)
{
    var myClassList = new MyClassList();
    myClassList.Root = new List<MyClass>();

    XmlSerializer ser = new XmlSerializer(typeof(MyClass));
    TextWriter writer = new StreamWriter("Filename.XML");
    for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
    {
        MyClass abc = new MyClass(Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value), dataGridView1.Rows[i].Cells[1].Value.ToString(), dataGridView1.Rows[i].Cells[2].Value.ToString());
        myClassList.Root.Add(abc);

    }
    ser.Serialize(writer, myClassList);
    writer.Close();
}

【讨论】:

    【解决方案3】:

    你可以这样做:

    var ser = new XmlSerializer(typeof(MyClass));
    using (var writer = XmlWriter.Create("Filename.XML", new XmlWriterSettings { Indent = true }))
    {
        writer.WriteStartElement("root");
        for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
        {
            MyClass abc = new MyClass(Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value), dataGridView1.Rows[i].Cells[1].Value.ToString(), dataGridView1.Rows[i].Cells[2].Value.ToString());
            ser.Serialize(writer, abc);
        }
        writer.WriteEndElement();
    }
    

    这里,我们使用XmlWriter手动创建根元素,这样你就可以使用XmlSerializer重复写入。


    但是,最好使用像 List&lt;MyClass&gt; 这样的集合并完全(反)序列化它。

    另外,我建议你做数据绑定:

    var list = new List<MyClass>();
    // fill the list
    
    // bind collection to control
    dataGridView1.DataSource = list;
    

    【讨论】:

      猜你喜欢
      • 2014-04-30
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多