C# XML UWP 中的序列化
C# XML Serialization in UWP
我正在尝试将多个列表序列化为一个唯一的 xml 文件。
我的项目是一个 UWP,目前它似乎序列化了我的 3 列表,但文件显示为空。
以前有用户帮我写了部分代码。
我如何正确序列化它。
To execute my code only use: "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);
}
}
}
I wanna get something similar to this:
<?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>
感谢任何帮助。
您从未在 myCompoundClass
:
中设置任何 属性 值 List1
或 List2
或 List3
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
class但它是静态的 class,因此不能按原样序列化。我的建议是:
重命名您的类型。您有 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
class 中。这样做会增加复杂性而不是清晰度。
将静态值列表设为只读:
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()
{
}
}
由于不能序列化静态类型,引入如下数据传输对象进行序列化:
[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 集合属性。
[XmlRoot("Root")]
指示该类型应使用名为 <Root>
.
的根元素进行序列化
[XmlElement]
应用于集合 属性 表示集合应该被序列化为没有外部容器元素的重复元素序列。
现在您将能够做到:
var new_instance = new ApplicationServicesDTO();
您的静态列表将以您想要的 XML 格式序列化。
请注意,如果您稍后想要反序列化您的 XML,您可能需要先清除 ApplicationServices
中预先存在的列表。有关解释,请参阅 。
我正在尝试将多个列表序列化为一个唯一的 xml 文件。 我的项目是一个 UWP,目前它似乎序列化了我的 3 列表,但文件显示为空。 以前有用户帮我写了部分代码。 我如何正确序列化它。
To execute my code only use: "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);
}
}
}
I wanna get something similar to this:
<?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>
感谢任何帮助。
您从未在 myCompoundClass
:
List1
或 List2
或 List3
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
class但它是静态的 class,因此不能按原样序列化。我的建议是:
重命名您的类型。您有
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
class 中。这样做会增加复杂性而不是清晰度。将静态值列表设为只读:
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() { } }
由于不能序列化静态类型,引入如下数据传输对象进行序列化:
[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 集合属性。[XmlRoot("Root")]
指示该类型应使用名为<Root>
. 的根元素进行序列化
[XmlElement]
应用于集合 属性 表示集合应该被序列化为没有外部容器元素的重复元素序列。
现在您将能够做到:
var new_instance = new ApplicationServicesDTO();
您的静态列表将以您想要的 XML 格式序列化。
请注意,如果您稍后想要反序列化您的 XML,您可能需要先清除 ApplicationServices
中预先存在的列表。有关解释,请参阅