xml序列化是将對象的公共屬性和字段轉換為xml格式,以便存儲或傳輸的過程。反序列化則是從xml輸出中重新建立原始狀态的對象。xml序列化中最主要的類是xmlserializer類。它的最重要的方法是serialize和deserialize方法,它位于system.xml.serialization命名空間。
在本節開始之前,首先來看一個最簡單的示例:
該代碼輸出如下:
從以上輸出,我們可以得出結論,必須要求無參構造函數,預設的也可以。但注意當預設的無參構造函數比覆寫時,要補上一個無參構造函數。另外,私有屬性,隻讀屬性是不能被序列化的。
更多的注意事項:
要序列化的類必須有預設的構造的構造函數,才能使用xmlserializer序列化;
方法不能被序列化;
索引器、私有字段或隻讀屬性(隻讀集合屬性除外)不能被序列化;
需要序列化的類都必須有一個無參的構造函數
枚舉變量可序列化為字元串,無需用[xmlinclude]
導出非基本類型對象,都必須用[xmlinclude]事先聲明。該規則遞歸作用到子元素
attribute中的isnullable參數若等于false,表示若元素為null則不顯示該元素。(針對值類型有效)
某些類就是無法xml序列化的(即使使用了[xmlinclude])
idictionary(如hashtable)
父類對象賦予子類對象值的情況
對象間循環引用
9.對于無法xml序列化的對象,可考慮
使用自定義xml序列化(實作ixmlserializable接口)
實作idictionary的類,可考慮(1)用其它集合類替代;(2)用類封裝之,并提供add和this函數
某些類型需要先經過轉換,然後才能序列化為
xml。如xml序列化system.drawing.color,可先用toargb()将其轉換為整數
過于複雜的對象用xml序列化不便的話,可考慮用二進制序列化。
不想序列化時:
當不想序列化一個屬性時,使用[system.xml.serialization.xmlignore]标記,能用于屬性;
[nonserializable]應用于屬性無效,能用于類,結構體等
預設構造函數是必須的,因為反序列化本質上使用的是反射,需要預設構造函數來執行個體化類,如果去掉其中的預設構造函數,則編譯沒有問題,但運作就會報錯。
盡量不要将比較大的屬性放在預設構造函數初始化,那會導緻在反序列化時對清單初始化兩次:預設構造函數中執行一次,反序列化時從xml文檔讀取再執行一次。
通常,在xml序列化的過程中,有很多東西是自動生成的,例如xml命名空間,編碼等等。
1、去除預設的命名空間與字首:
輸出對比:
當然,這個方法也可以用于生成你想要的自定義命名空間。
2、去除xml聲明:頂部的 <?xml version="1.0"
encoding="utf-8"?>
輸出:
3、換行縮進
當xmlwritersettings如此設定後,輸出的xml為:
4、指定縮進字元
輸出如下:
xmlwritersettings更多設定屬性如下:
成員
說明
closeoutput
擷取或設定一個值,該值訓示在調用 close 方法時,xmlwriter 是否還應該關閉基礎流或 textwriter。
encoding
擷取或設定要使用的文本編碼的類型。
indent
擷取或設定一個值,該值訓示是否縮進元素。
indentchars
擷取或設定縮進時要使用的字元串。
namespacehandling
擷取或設定一個值,該值訓示在編寫 xml 内容時,xmlwriter 是否應移除重複的命名空間聲明。
的預設是輸出程式中出現的所有命名空間聲明。
newlinechars
擷取或設定要用于分行符的字元串
newlinehandling
擷取或設定一個值,該值訓示是否将輸出中的分行符正常化。
newlineonattributes
擷取或設定一個值,該值訓示是否将屬性寫入新行。
omitxmldeclaration
擷取或設定一個值訓示省略 xml 聲明。
reset方法
重置以上屬性
實作ixmlserializable接口之後,我們能夠自定義類序列化的方式。
該接口包含3個方法:
簡單示例:
我們都知道,接口是不支援序列化的。下面來做個有用的示例,實作ilist<t>的序列化與反序列化:
以上代碼是能夠直接用于序列化數組的,也就是ilist<person>的,下面在貼上兩個序列化與反序列化ilist<t>的方法:
下面給出一個序列化與反序列化通過反射的複雜對象的示例:
以上代碼輸出:
特别提示,一定要特别特别注意,readstartelement與readendelement的問題,否則很容易出現反序列化集合時隻能夠讀取第一個的情況。而對于序列化,如果writestartelement與writeendelement不比對,出現的隻是xml标簽對不比對的問題,沒read的時候那麼坑。
有時,我們在序列化時想要自定義xml的結構,這時候就要用到我們的屬性類了。屬性類提供了很多特性供我們使用,以完成自定義序列化功能。
名稱
描述
xmlattribute
表示一個特性對象的集合,這些對象控制xmlserializer如何序列化和反序列化對象
xmlarrayattribute
指定xmlserializer應将特定的類成員序列化為xml元素數組
xmlarrayitemattribute
指定xmlserializer可以放置在序列化數組中的派生類型
xmlarrayitemattributes
表示xmlarrayitemattribute對象的集合
xmlattributeattribute
指定xmlserializer應将類成員作為xml特性序列化
xmlchoiceidentifierattribute
指定可以通過使用枚舉來進一步消除成員的歧義
xmlelementattribute
在xmlserializer序列化或反序列化包含對象時,訓示公共字段或屬性表示xml元素
xmlelementattributes
表示xmlelementattribute的集合,xmlserializer将其用于它重寫序列化類的預設方式
xmlenumattribute
控制xmlserializer如何序列化枚舉成員
xmlignoreattribute
訓示xmlserializer方法不序列化公共字段或公共讀/寫屬性值
xmlincludeattribute
允許xmlserializer在它序列化或反序列化對象時識别類型
xmlrootattribute
控制視為xml根元素的屬性目标的xml序列化
xmltextattribute
當序列化或反序列化時,想xmlserializer訓示應将此成員作為xml文本處理
xmltypeattribute
控制當屬性目标由xmlserializer序列化時生成的xml結構
xmlanyattributeattribute
指定成員(傳回xmlattribute對象的數組的字段)可以包含xml屬性
xmlanyelementattribute
指定成員可以包含對象,該對象表示在序列化或反序列化的對象中沒有相應成員的所有xml元素
xmlanyelementattributes
表示xmlanyelementattribute對象的集合
xmlattributeeventargs
為unknowattribute提供資料
xmlattributeoverrides
允許你在使用xmlserializer序列化或反序列化時重寫屬性、字段和類特性
xmlelementeventargs
為unknownelement事件提供資料
xmlnamespacedeclarationsattribute
指定目标屬性、參數、傳回值或類成員包含與xml文檔中所用命名空間關聯的字首
xmlnodeeventargs
為unknownnode時間提供資料
xmlserializer
将對象序列化到xml文檔中和從xml文檔中反序列化對象,xmlserializer使你得以控制如何将對象編碼到xml中
xmlserializernamespaces
包含xmlserializer用于在xml文檔執行個體中生成限定名的xml命名空間和字首
xmltypemapping
包含從一種類型到另一種類型的映射
更多更詳細的說明,可以在這裡看到:
下面僅僅給出兩個簡單示例:
2013/12/27 常遇錯誤記錄:
反序列化錯誤提示:
1、xml 文檔(2, 2)中有錯誤:
報這個錯誤一般是由于序列化與反序列化的類型不一緻: