【问题标题】:C# XML Serialization in UWPUWP 中的 C# XML 序列化
【发布时间】:2016-08-22 15:18:46
【问题描述】:

我正在尝试将多个列表序列化为一个唯一的 xml 文件。 我的项目是一个 UWP,目前它似乎序列化了我的 3 列表,但文件显示为空。 以前有一个用户帮助我完成部分代码。 我如何正确序列化它。

要执行我的代码,只使用:“project();”

我所有的代码:

using Project.Common;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using Windows.Storage;
using System.Threading.Tasks;

namespace Project
{
    public class All_Classes
    {
        public class List1 : BindableBase
        {
            private int _Property1;
            public int Property1
            {
                get { return _Property1; }
                set { SetProperty(ref _Property1, value); }
            }

            private bool _Property2;
            public bool Property2
            {
                get { return _Property2; }
                set { SetProperty(ref _Property2, value); }
            }

            private bool _Property3;
            public bool Property3
            {
                get { return _Property3; }
                set { SetProperty(ref _Property3, value); }
            }
        }

        public class List2 : BindableBase
        {

            private bool _Property1;
            public bool Property1
            {
                get { return _Property1; }
                set { SetProperty(ref _Property1, value); }
            }

            private bool _Property2;
            public bool Property2
            {
                get { return _Property2; }
                set { SetProperty(ref _Property2, value); }
            }
        }

        public class List3 : BindableBase
        {
            private double _Property1;
            public double Property1
            {
                get { return _Property1; }
                set { SetProperty(ref _Property1, value); }
            }

            private double _Property2;
            public double Property2
            {
                get { return _Property2; }
                set { SetProperty(ref _Property2, value); }
            }

            private double _Property3;
            public double Property3
            {
                get { return _Property3; }
                set { SetProperty(ref _Property3, value); }
            }

            private double _Property4;
            public double Property4
            {
                get { return _Property4; }
                set { SetProperty(ref _Property4, value); }
            }

        }

        public class Values_List1 : ObservableCollection<List1>
        {
        }
        public class Values_List2 : ObservableCollection<List2>
        {
        }
        public class Values_List3 : ObservableCollection<List3>
        {
        }

        public static class ApplicationServices
        {
            public static Values_List1 List1 = new Values_List1();
            public static Values_List2 List2 = new Values_List2();
            public static Values_List3 List3 = new Values_List3();

            static ApplicationServices()
            {
            }
        }

        public static void AddNewData()
        {
            ApplicationServices.List1.Add(new List1()
            {
                Property1 = 1,
                Property2 = true,
                Property3 = false,

            });

            ApplicationServices.List2.Add(new List2()
            {
                Property1 = false,
                Property2 = true,
            });

            ApplicationServices.List3.Add(new List3()
            {
                Property1 = 3.564,
                Property2 = 0.215,
                Property3 = 0.7252,
                Property4 = 23.463,
            });
        }

        public static async void SaveObjectToXml<T>(T objectToSave)
        {
            //<-----------FilePicker------------------>
            var savePicker = new Windows.Storage.Pickers.FileSavePicker();
            savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
            savePicker.FileTypeChoices.Add("New File", new List<string>() { ".xml" });
            savePicker.SuggestedFileName = "New File";
            StorageFile newfile = await savePicker.PickSaveFileAsync();
            //<-----------FilePicker------------------>
            //<----------------Serializacion------------------>

            var serializer = new XmlSerializer(typeof(T));

            Stream stream = await newfile.OpenStreamForWriteAsync();


            using (stream)
            {
                serializer.Serialize(stream, objectToSave);
            }
            //<----------------Serializacion------------------>

        }

        public class myCompoundClass
        {
            public List1 List1 { get; set; }
            public List2 List2 { get; set; }
            public List3 List3 { get; set; }
        }

        public static void project()
        {
            myCompoundClass new_instance = new myCompoundClass();
            AddNewData();
            SaveObjectToXml(new_instance);
        }

    }
}

我想得到类似的东西:

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <List1>
    <Property1>1</Property1>
    <Property2>true</Property2>
    <Property3>false</Property3>
    <ToAcero>0.1</ToAcero>
  </List1>
  <List2>
    <Property1>true</Property1>
    <Property2>true</Property2>
  </List2>
  <List3>
    <Property1>3.564</Property1>
    <Property2>0.215</Property2>
    <Property3>0.7252</Property3>
    <Property4>23.463</Property4>
  </List3>
</Root>

感谢任何帮助。

【问题讨论】:

    标签: c# serialization xml-serialization uwp uwp-xaml


    【解决方案1】:

    您永远不会在myCompoundClass 中设置任何属性值List1List2List3

            myCompoundClass new_instance = new myCompoundClass();
            AddNewData();
            // new_instance was not passed to AddNewData and so its properties have their default values of null.
            SaveObjectToXml(new_instance);
    

    因此它的所有属性仍然是null。这就是您的 XML 文件为空的原因。在序列化之前,您需要将数据从 static class ApplicationServices 移动到 new_instance

    更新

    你问,我如何用 ApplicationServices 填充“new_instance”?你的问题是你想序列化你的 ApplicationServices 类,但它是一个静态类,因此不能序列化为 -是。我的建议是:

    1. 重命名你的类型。您有诸如List1 之类的类型,它们不是列表。我建议如下:

      public class Values1 : BindableBase // Formerly List1
      {
          // Contents unchanged
      }
      
      public class Values2 : BindableBase // Formerly List2
      {
          // Contents unchanged
      }
      
      public class Values3 : BindableBase // Formerly List3
      {
          // Contents unchanged
      }
      
      public class Values1List : ObservableCollection<Values1>
      {
      }
      public class Values2List : ObservableCollection<Values2>
      {
      }
      public class Values3List : ObservableCollection<Values3>
      {
      }
      

      您现有的命名约定对于什么是集合和不是集合具有误导性。

      另外,我建议您不要将它们嵌套在 All_Classes 类中。这样做会增加复杂性而不是清晰度。

    2. 将静态值列表设为只读:

      public static class ApplicationServices
      {
          public static readonly Values1List List1 = new Values1List();
          public static readonly Values2List List2 = new Values2List();
          public static readonly Values3List List3 = new Values3List();
      
          static ApplicationServices()
          {
          }
      }
      
    3. 由于不能序列化静态类型,引入如下数据传输对象进行序列化:

      [XmlRoot("Root")]
      public class ApplicationServicesDTO
      {
          [XmlElement]
          public Values1List List1 { get { return ApplicationServices.List1; } }
      
          [XmlElement]
          public Values2List List2 { get { return ApplicationServices.List2; } }
      
          [XmlElement]
          public Values3List List3 { get { return ApplicationServices.List3; } }
      }
      

      一些注意事项:

      • 请注意,List 属性是仅获取的。一般XmlSerializer 不会序列化 get-only 属性,但会在预分配集合时序列化 get-only collection properties

      • [XmlRoot("Root")] 表示该类型应使用名为&lt;Root&gt; 的根元素进行序列化。

      • [XmlElement] 应用于集合属性表示该集合应序列化为不带外部容器元素的重复元素序列。

    现在你可以做:

    var new_instance = new ApplicationServicesDTO();
    

    您的静态列表将使用您想要的 XML 格式进行序列化。

    请注意,如果您稍后想要反序列化您的 XML,您可能需要先清除 ApplicationServices 中预先存在的列表。解释见XML Deserialization of collection property with code defaults

    【讨论】:

    • 太失败了,先生,但我需要将我的数据添加到 ApplicationServices 但它是静态的,然后我无法实例化它,我如何用 ApplicationServices 填充“new_instance”,你能帮我吗?
    猜你喜欢
    • 2010-11-25
    • 2010-09-08
    • 2011-06-17
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多