序列化时重复的根

时间:2015-02-10 11:52:24

标签: c# xml winforms

我正在尝试将字典序列化为xml,但xml的结构与我想要的结构不同。出于某种原因,我没有在该根中拥有一个根和多个子节点,而是为字典中的每个键和值获取一个新根。此外,还为字典中的每个KeyValuePair显示消息框,我希望在导出字典时显示消息框一次。我正在使用带有C#的Microsoft Visual Studio 2010,以及从窗体上的文本框中收集的字典中的所有值。

这是当前xml布局的样子:

<?xml version="1.0" encoding="utf-8"?>
<Coordinate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Date_Time>10/02/2015 11/17/00</Date_Time>
   <BeaconID>1</BeaconID>
   <X_Coordinate>2</X_Coordinate>
   <Y_Coordinate>3</Y_Coordinate>
</Coordinate><?xml version="1.0" encoding="utf-8"?>
<Coordinate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <Date_Time>10/02/2015 11/17/01</Date_Time>
   <BeaconID>2</BeaconID>
   <X_Coordinate>3</X_Coordinate>
   <Y_Coordinate>4</Y_Coordinate>
</Coordinate>

这就是我希望它的样子:

<?xml version="1.0" encoding="utf-8"?>
<Coordinates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Coordinate>
        <Date_Time>10/02/2015 11/17/00</Date_Time>
        <BeaconID>1</BeaconID>
        <X_Coordinate>2</X_Coordinate>
        <Y_Coordinate>3</Y_Coordinate>
    </Coordinate>
    <Coordinate>
        <Date_Time>10/02/2015 11/17/01</Date_Time>
        <BeaconID>2</BeaconID>
        <X_Coordinate>3</X_Coordinate>
        <Y_Coordinate>4</Y_Coordinate>
     </Coordinate>
</Coordinates>

这是我所有与xml相关的代码:

public void btn_Submit_Click(object sender, EventArgs e)
    {
        foreach (KeyValuePair<string, Tuple<int, int>> entry in d)
        {
            Coordinate v = new Coordinate();

            v.Date_Time = DateTime.Now.ToString("dd/MM/yyyy hh/mm/ss");
            v.BeaconID = entry.Key;
            v.X_Coordinate = entry.Value.Item1.ToString();
            v.Y_Coordinate = entry.Value.Item2.ToString();

            SaveValues(v);
        }
    }

    public class Coordinate//Root element
    {
        public string Date_Time { get; set; }
        public string BeaconID { get; set; }
        public string X_Coordinate { get; set; }
        public string Y_Coordinate { get; set; }
    }

    public void SaveValues(Coordinate v)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Coordinate));
        using (TextWriter textWriter = new StreamWriter(@"F:\Vista\Exporting into XML\Test1\Coordinates output.xml", true))
        {
            serializer.Serialize(textWriter, v);
        }
        MessageBox.Show("Coordinates were exported successfully", "Message");//Let the user know the export was succesfull            
    }
你能告诉我我做错了吗?如果我遗漏了任何东西,或者我只是不清楚,请让我知道它,我会帮助它。我是XML和序列化的新手,所以任何帮助都会受到赞赏。

更新

@ P.K。一个更好的解释:

<?xml version="1.0" encoding="utf-8"?>
<Coordinates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Coordinate>
    <Coordinate>
      <DateTime>10/02/2015 02/35/14</DateTime>
      <BeaconID>1</BeaconID>
      <XCoordinate>2</XCoordinate>
      <YCoordinate>3</YCoordinate>
    </Coordinate>
    <Coordinate>
      <DateTime>10/02/2015 02/35/14</DateTime>
      <BeaconID>2</BeaconID>
      <XCoordinate>3</XCoordinate>
      <YCoordinate>4</YCoordinate>
    </Coordinate>
  </Coordinate>
</Coordinates>

而不是:

<?xml version="1.0" encoding="utf-8"?>
<Coordinates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Coordinate>
      <DateTime>10/02/2015 02/35/14</DateTime>
      <BeaconID>1</BeaconID>
      <XCoordinate>2</XCoordinate>
      <YCoordinate>3</YCoordinate>
    </Coordinate>
    <Coordinate>
      <DateTime>10/02/2015 02/35/14</DateTime>
      <BeaconID>2</BeaconID>
      <XCoordinate>3</XCoordinate>
      <YCoordinate>4</YCoordinate>
    </Coordinate>
</Coordinates>

4 个答案:

答案 0 :(得分:0)

  1. “此外,字典中的每个KeyValuePair都会显示消息框” 这是由于调用SaveValues(v)引起的;在'for'循环中。
  2. 2。 SaveValues应保存坐标列表(List)。 通过针对每个坐标运行它,使其每次都生成不同的XML文档,并将其附加到文档中。

    1. 为了控制生成的XML元素的名称,请使用XmlAttributes 协调对象。
    2. 参见https://msdn.microsoft.com/en-us/library/2baksw0z%28v=vs.110%29.aspx 对于furtehr信息

      旁注: 我建议使用一致的属性命名: 'BeaconID'上骆驼案 或'X_Coordinate'上蛇案(?) 它使代码更容易阅读。

      修改

      The name 'v' does not exist in the current context  
      

      表示在此范围内未定义名为“v”的变量。 您遇到此错误的原因是您在声明它之前尝试使用变量'v'(坐标v)。 我建议您熟悉C#语言的基础知识,以获取更多信息。

      非常好的资源是

      https://msdn.microsoft.com/en-us/library/aa288436%28v=vs.71%29.aspx

答案 1 :(得分:0)

最好的办法是将另一个类添加为坐标。将所有子节点存储在此对象中,然后再将其清除。

public class Coordinates
{
    public Coordinate[] Coordinate;
}

public void btn_Submit_Click(object sender, EventArgs e)
{
    List<Coordinate> lstCoordinates = new List<Coordinate>();
    foreach (KeyValuePair<string, Tuple<int, int>> entry in d)
    {
        Coordinate v = new Coordinate();

        v.Date_Time = DateTime.Now.ToString("dd/MM/yyyy hh/mm/ss");
        v.BeaconID = entry.Key;
        v.X_Coordinate = entry.Value.Item1.ToString();
        v.Y_Coordinate = entry.Value.Item2.ToString();

        lstCoordinates.Add(v);
    }

    Coordinates cdCol = new Coordinates();
    cdCol.Coordinate = lstCoordinates.ToArray();
    SaveValues(cdCol);
}

public void SaveValues(Coordinates v)
{
    XmlSerializer serializer = new XmlSerializer(typeof(Coordinates));
    using (TextWriter textWriter = new StreamWriter(@"F:\Vista\Exporting into XML\Test1\Coordinates output.xml", true))
    {
        serializer.Serialize(textWriter, v);
    }
    MessageBox.Show("Coordinates were exported successfully", "Message");//Let the user know the export was succesfull            
}

答案 2 :(得分:0)

您获得结果的原因是您只是将新的XML文档附加到文件StreamWriter只是写出你告诉它的任何东西 - 它不知道数据已经以XML格式存在,你需要将新XML与现有数据合并。

如果您希望完全将集合导出为有效的XML,则需要在内存中创建集合,然后将其作为 new 文件写出(不附加到现有的)。如果这意味着您需要读取现有的XML,那么您可能需要这样做。

答案 3 :(得分:0)

请问下面的代码吗?

public void btn_Submit_Click(object sender, EventArgs e)
        {
            List<KeyValuePair<string, Tuple<int, int>>> d = new List<KeyValuePair<string, Tuple<int, int>>>
            {
                new KeyValuePair<string, Tuple<int, int>>("1",Tuple.Create<int,int>(1,1)),
                new KeyValuePair<string, Tuple<int, int>>("2",Tuple.Create<int,int>(2,2)),
                new KeyValuePair<string, Tuple<int, int>>("3",Tuple.Create<int,int>(3,3)),
                new KeyValuePair<string, Tuple<int, int>>("4",Tuple.Create<int,int>(4,4)),
                new KeyValuePair<string, Tuple<int, int>>("5",Tuple.Create<int,int>(5,5))
            };

            List<Coordinate> cv = new List<Coordinate>();

            foreach (KeyValuePair<string, Tuple<int, int>> entry in d)
            {
                Coordinate v = new Coordinate();

                v.Date_Time = DateTime.Now.ToString("dd/MM/yyyy hh/mm/ss");
                v.BeaconID = entry.Key;
                v.X_Coordinate = entry.Value.Item1.ToString();
                v.Y_Coordinate = entry.Value.Item2.ToString();
                cv.Add(v);
            }
            SaveValues(cv);
        }

    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 output.xml", true))
                {
                    serializer.Serialize(textWriter, v);
                }
                MessageBox.Show("Coordinates were exported successfully", "Message");//Let the user know the export was succesfull            
            }

更新了代码以获得字典...

public void btn_Submit_Click(object sender, EventArgs e)
            {
                Dictionary<string, Tuple<int, int>> d = new Dictionary<string, Tuple<int, int>>();
            int X_Co = 1;
            int Y_Co = 1;
            var t = new Tuple<int, int>(X_Co, Y_Co);
            d.Add("1", t);

            X_Co = 2;
            Y_Co = 2;
            t = new Tuple<int, int>(X_Co, Y_Co);
            d.Add("2", t);

                List<Coordinate> cv = new List<Coordinate>();

                foreach (KeyValuePair<string, Tuple<int, int>> entry in d)
                {
                    Coordinate v = new Coordinate();

                    v.Date_Time = DateTime.Now.ToString("dd/MM/yyyy hh/mm/ss");
                    v.BeaconID = entry.Key;
                    v.X_Coordinate = entry.Value.Item1.ToString();
                    v.Y_Coordinate = entry.Value.Item2.ToString();
                    cv.Add(v);
                }
                SaveValues(cv);
            }

更新了代码,为每个循环提供单独的文件。

foreach (KeyValuePair<string, Tuple<int, int>> entry in d)
            {
                List<Coordinate> cv = new List<Coordinate>();
                Coordinate v = new Coordinate();

                v.Date_Time = DateTime.Now.ToString("dd/MM/yyyy hh/mm/ss");
                v.BeaconID = entry.Key;
                v.X_Coordinate = entry.Value.Item1.ToString();
                v.Y_Coordinate = entry.Value.Item2.ToString();
                cv.Add(v);
                SaveValues(cv);
            }