詳解 C# 中XML對象的序列化和反序列化
這一篇主要是用來介紹關(guān)于C#中的XML序列化的問題,這個相信大家一定會經(jīng)常使用它,特別是在WPF中,有時候我們需要將我們后臺的數(shù)據(jù)保存在數(shù)據(jù)庫中,從而在軟件下一次啟動的時候能夠自動去加載這些數(shù)據(jù),由于我們的這些Model中字段眾多,如果單獨進(jìn)行保存那是不太現(xiàn)實的,這個時候?qū)⑦@些字段序列化成xml字符串并保存在數(shù)據(jù)庫中就是一個不錯的選擇,當(dāng)我們需要這些數(shù)據(jù)的時候我們也可以反過來將其序列化為一些字段,最終達(dá)到我們的效果,首先我們來看看是如何實現(xiàn)的?
public class XMLUtil
{
/// <summary>
/// XML & Datacontract Serialize & Deserialize Helper
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="serialObject"></param>
/// <returns></returns>
public static string Serializer<T>(T serialObject) where T : class
{
try
{
XmlSerializer ser = new XmlSerializer(typeof(T));
System.IO.MemoryStream mem = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(mem, Encoding.UTF8);
ser.Serialize(writer, serialObject);
writer.Close();
return Encoding.UTF8.GetString(mem.ToArray());
}
catch (Exception ex)
{
return null;
}
}
public static T Deserialize<T>(string str) where T : class
{
try
{
XmlSerializer mySerializer = new XmlSerializer(typeof(T));
StreamReader mem2 = new StreamReader(
new MemoryStream(System.Text.Encoding.UTF8.GetBytes(str)),
System.Text.Encoding.UTF8);
return (T)mySerializer.Deserialize(mem2);
}
catch (Exception)
{
return null;
}
}
}
微軟為我們提供的XmlSerializer這個類就為我們提供了這個可能,在序列化的過程中我們需要注意下面的情況,所有的屬性必須是可序列化的對象,像BitmapImage、SolidColorBrush等這些對象都是不能夠進(jìn)行序列化的對象,如果用上面的方法進(jìn)行序列化時將返回null,正確的方式是在這些字段上面加上[XmlIgnore]說明,從而在進(jìn)行序列化時候跳過這些對象,就像下面的方式。
/// <summary>
///背景顏色
/// </summary>
private SolidColorBrush _BackgroundColor;
[XmlIgnore]
public SolidColorBrush BackgroundColor
{
get
{
return _BackgroundColor;
}
set
{
if (value != _BackgroundColor)
{
_BackgroundColor = value;
OnPropertyChanged("BackgroundColor");
}
}
}
那么像上面的這個SolidColorBrush對象該怎樣去進(jìn)行序列化呢,這里我們選擇將當(dāng)前顏色的ARGB值保存在一個byte數(shù)組中,從而在反序列化的時候通過Color.FromArgb的方式進(jìn)行還原,就像下面的方式。
byte[] colorByte=savedModel.ConfigurationBaseModel.BackgroundColorArgb; Color backColor=Color.FromArgb(colorByte[0],colorByte[1],colorByte[2],colorByte[3]); sourceBaseModel.BackgroundColor = new SolidColorBrush(backColor);
那么這個對象在進(jìn)行序列化的時候該怎么進(jìn)行保存呢?同樣的原理我們可以通過下面的方式。
/// <summary>
///背景顏色
/// </summary>
private SolidColorBrush _BackgroundColor;
[XmlIgnore]
public SolidColorBrush BackgroundColor
{
get
{
return _BackgroundColor;
}
set
{
if (value != _BackgroundColor)
{
_BackgroundColor = value;
OnPropertyChanged("BackgroundColor");
}
}
}
/// <summary>
///背景顏色ARGB
/// </summary>
private byte[] _BackgroundColorArgb=new byte[4];
[XmlArray("argb"),XmlArrayItem("value")]
public byte[] BackgroundColorArgb
{
get
{
if (null != _BackgroundColor)
{
Color color = _BackgroundColor.Color;
_BackgroundColorArgb[0] = color.A;
_BackgroundColorArgb[1] = color.R;
_BackgroundColorArgb[2] = color.G;
_BackgroundColorArgb[3] = color.B;
}
return _BackgroundColorArgb;
}
set
{
if (value != _BackgroundColorArgb)
{
_BackgroundColorArgb = value;
OnPropertyChanged("BackgroundColorArgb");
}
}
}
這里在實際的使用中發(fā)現(xiàn),就像byte數(shù)組必須通過[XmlArray("argb"),XmlArrayItem("value")] 這類型的標(biāo)識來將其分類,在將其序列化完畢以后,我們可以看看這個BackgroundColorArgb字段最終是通過怎樣的方式來保存的?

在進(jìn)行反序列化的時候會將這個argb和value反序列化為一個byte數(shù)組。
除了這些特例意外,有時候經(jīng)常需要將一些對象的數(shù)組進(jìn)行序列化,那么原理是什么呢?這里我借用別人的一個例子來進(jìn)行相關(guān)的說明。
對象數(shù)組的Xml序列化:
數(shù)組的Xml序列化需要使用XmlArrayAttribute和XmlArrayItemAttribute;XmlArrayAttribute指定數(shù)組元素的Xml節(jié)點名,XmlArrayItemAttribute指定數(shù)組元素的Xml節(jié)點名。
如下代碼示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace UseXmlSerialization
{
class Program
{
static void Main(string[] args)
{
//聲明一個貓咪對象
var cWhite = new Cat { Color = "White", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };
var cBlack = new Cat { Color = "Black", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };
CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite,cBlack} };
//序列化這個對象
XmlSerializer serializer = new XmlSerializer(typeof(CatCollection));
//將對象序列化輸出到控制臺
serializer.Serialize(Console.Out, cc);
Console.Read();
}
}
[XmlRoot("cats")]
public class CatCollection
{
[XmlArray("items"),XmlArrayItem("item")]
public Cat[] Cats { get; set; }
}
[XmlRoot("cat")]
public class Cat
{
//定義Color屬性的序列化為cat節(jié)點的屬性
[XmlAttribute("color")]
public string Color { get; set; }
//要求不序列化Speed屬性
[XmlIgnore]
public int Speed { get; set; }
//設(shè)置Saying屬性序列化為Xml子元素
[XmlElement("saying")]
public string Saying { get; set; }
}
}
最終獲得的結(jié)果是:
<?xml version="1.0" encoding="gb2312"?> <cats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <items> <item color="White"> <saying>White or black, so long as the cat can catch mice, it is a good cat</saying> </item> <item color="Black"> <saying>White or black, so long as the cat can catch mice, it is a good cat</saying> </item> </items> </cats>
以上就是詳解 C# 中XML對象的序列化和反序列化的詳細(xì)內(nèi)容,更多關(guān)于c# xml序列化和反序列化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#難點逐個擊破(8):可空類型System.Nullable
null值用來表示數(shù)據(jù)類型未被賦予任何值,它是一種引用類型;void表示沒有類型,或者說是沒有任何值。null與void的區(qū)別可以認(rèn)為void是根本沒有,而null是一個空箱子,里面什么都沒有。2010-02-02
將c#編寫的程序打包成應(yīng)用程序的實現(xiàn)步驟分享(安裝,卸載) 圖文
時常會寫用c#一些程序,但如何將他們和photoshop一樣的大型軟件打成一個壓縮包,以便于發(fā)布.2011-12-12
Unity UGUI LayoutRebuilder自動重建布局介紹及使用
這篇文章主要為大家介紹了Unity UGUI LayoutRebuilder自動重建布局介紹及使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07

