上篇總結了下JSON的序列化和反序列化,博園中大牛給了不少牛叉的評論,學習了很多。html
不過在上篇中忘了把json序列化和反序列化的另一種方式寫上去了,這裏作個簡單的補充:json
Json篇:http://www.cnblogs.com/zhanghaomars/p/3557644.html工具
Json序列化和反序列化擴展方法實現類:學習
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Script.Serialization; namespace HelpClass.TypeHelp { public static class JsonHelpExpand { public static string JsonSerializer<T>(this T t) where T : class { JavaScriptSerializer jsonSerialize = new JavaScriptSerializer(); return jsonSerialize.Serialize(t); } public static T JsonDeserialize<T>(this string jsonString) { JavaScriptSerializer jsonSerialize = new JavaScriptSerializer(); return (T)jsonSerialize.Deserialize<T>(jsonString); } } }
Ok!接下來就是XMLthis
一、 靜態方法+泛型實現編碼
XML工具類:spa
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Xml; using System.Xml.Serialization; namespace HelpClass.TypeHelp { public class XMLHelp { private static void XmlSerializeInternal(Stream stream, object o, Encoding encoding, bool isnamespaces) { if (o == null) throw new ArgumentNullException("o"); if (encoding == null) throw new ArgumentNullException("encoding"); XmlSerializer serializer = new XmlSerializer(o.GetType()); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.NewLineChars = "\r\n"; settings.Encoding = encoding; settings.IndentChars = " "; //不生成聲明頭 settings.OmitXmlDeclaration = !isnamespaces; MemoryStream w = new MemoryStream(); XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); namespaces.Add("", ""); using (XmlWriter writer = XmlWriter.Create(stream, settings)) { serializer.Serialize(writer, o, namespaces); writer.Close(); } } /// <summary> /// 將一個對象序列化爲XML字符串 /// </summary> /// <param name="o">要序列化的對象</param> /// <param name="encoding">編碼方式</param> /// <param name="isnamespaces">是否須要命名空間true:須要 false:不須要</param> /// <returns>序列化產生的XML字符串</returns> public static string XmlSerialize(object o, Encoding encoding, bool isnamespaces) { using (MemoryStream stream = new MemoryStream()) { XmlSerializeInternal(stream, o, encoding, isnamespaces); stream.Position = 0; using (StreamReader reader = new StreamReader(stream, encoding)) { return reader.ReadToEnd(); } } } /// <summary> /// 從XML字符串中反序列化對象 /// </summary> /// <typeparam name="T">結果對象類型</typeparam> /// <param name="s">包含對象的XML字符串</param> /// <param name="encoding">編碼方式</param> /// <returns>反序列化獲得的對象</returns> public static T XmlDeserialize<T>(string s, Encoding encoding) { if (string.IsNullOrEmpty(s)) throw new ArgumentNullException("s"); if (encoding == null) throw new ArgumentNullException("encoding"); XmlSerializer mySerializer = new XmlSerializer(typeof(T)); using (MemoryStream ms = new MemoryStream(encoding.GetBytes(s))) { using (StreamReader sr = new StreamReader(ms, encoding)) { return (T)mySerializer.Deserialize(sr); } } } /// <summary> /// 將一個對象按XML序列化的方式寫入到一個文件 /// </summary> /// <param name="o">要序列化的對象</param> /// <param name="path">保存文件路徑</param> /// <param name="encoding">編碼方式</param> /// <param name="isnamespaces">是否須要命名空間true:須要 false:不須要</param> public static void XmlSerializeToFile(object o, string path, Encoding encoding, bool isnamespaces) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); using (FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write)) { XmlSerializeInternal(file, o, encoding,isnamespaces); } } /// <summary> /// 讀入一個文件,並按XML的方式反序列化對象。 /// </summary> /// <typeparam name="T">結果對象類型</typeparam> /// <param name="path">文件路徑</param> /// <param name="encoding">編碼方式</param> /// <returns>反序列化獲得的對象</returns> public static T XmlDeserializeFromFile<T>(string path, Encoding encoding) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); if (encoding == null) throw new ArgumentNullException("encoding"); string xml = File.ReadAllText(path, encoding); return XmlDeserialize<T>(xml, encoding); } } }
在一個項目中,若是面臨大量的XML(如調用大量返回XML的外部接口),這時就須要根據XML結構來逆向推導C#類型,而後才能使用序列化和反序列化的方法。code
當須要根據XML結構逆向推導類型,咱們須要瞭解一下類型定義與XML結構的映射關係。xml
映射關係只須要記住幾個標籤:htm
(1) [XmlElement]
類中的屬性或者字段在不標記下默認都會生成XmlElement(不加任何Attribute的狀況下)該標籤把類中的屬性或者字段序列化爲XML中的節點
Public class ddd
{
[XmlElement]
Public string d1{get;set;}
Public string d2{get;set;}
}
ddd cd=new ddd{d1=」1」,d2=」2」}
<ddd><d1>1</d1><d2>2</d2></ddd>
(2) [XmlAttribute]
類中的屬性或者字段在標記爲[XmlAttribute]的狀況下會生成爲XML中以以該類名爲節點的屬性
Public class ddd
{
[XmlAttribute]
Public string d1{get;set;}
[XmlElement]
Public string d2{get;set;}
}
ddd cd=new ddd{d1=」1」,d2=」2」}
<ddd d1=」1」><d2>2</d2></ddd>
(3) [InnerText]
若是但願類型中的屬性或者字段生成InnerText,須要在類型的成員上用[XmlText]
Public class ddd
{
[XmlAttribute]
Public string d1{get;set;}
[InnerText]
Public string d2{get;set;}
}
ddd cd=new ddd{d1=」1」,d2=」2」}
<ddd d1=」1」>2</ddd>
(4) 重命名
XmlAttribute,XmlElement容許接受一個別名用來控制生成節點的名稱,類型的重命名用XmlType來實現
[XmlType(「ccc」)]
Public class ddd
{
[XmlAttribute(「c1」)]
Public string d1{get;set;}
[XmlElement(「c2」)]
Public string d2{get;set;}
}
ddd cd=new ddd{d1=」1」,d2=」2」}
<ccc c1=」1」><c2>2</c2></ccc>
(5) 序列化去掉XML命名空間及聲明頭(工具類中代碼以有相關說明了)
注意:
(1) 當須要考慮使用XML時,先不要想着XML結構,先應該定義好數據類型。
(2) 列表節點不要使用[XmlElement],它會讓全部子節點【升級】,顯得結構混亂。
(3) 若是但願序列化的XML長度小一點,能夠採用[XmlAttribute],或者指定一個更短小的別名(序列化爲JSON進行傳輸也是一種選擇)
(4) 不要在一個列表中輸出不一樣的數據類型,這樣的XML結構的可讀性很差。
(5) 儘可能使用UTF-8編碼,不要使用GB2312編碼。
(6) 列表節點不要使用[XmlElement],它會讓全部子節點【升級】,顯得結構混亂。
二、 擴展方法+泛型實現
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Xml; using System.Xml.Serialization; namespace HelpClass.TypeHelp { public static class XMLHelpExpand { /// <summary> /// XML序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="o"></param> /// <param name="isnamespaces">是否須要命名空間true:須要 false:不須要</param> /// <returns></returns> public static string XmlSerializer<T>(this T o,bool isnamespaces)where T:class { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(o.GetType()); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.NewLineChars = "\r\n"; settings.Encoding = Encoding.UTF8; settings.IndentChars = " "; //不生成聲明頭 settings.OmitXmlDeclaration = !isnamespaces; MemoryStream w = new MemoryStream(); XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); namespaces.Add("", ""); using (XmlWriter writer = XmlWriter.Create(w, settings)) { serializer.Serialize(writer, o, namespaces); writer.Close(); } return Encoding.UTF8.GetString(w.ToArray()); } /// <summary> /// XML反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="XmlString"></param> /// <returns></returns> public static T XmlDeserialize<T>(this string XmlString) { if (string.IsNullOrEmpty(XmlString)) throw new ArgumentNullException("s"); XmlSerializer mySerializer = new XmlSerializer(typeof(T)); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XmlString))) { using (StreamReader sr = new StreamReader(ms, Encoding.UTF8)) { return (T)mySerializer.Deserialize(sr); } } } } }
看完了上面的這些或許你已經對XML的序列化和反序列化有了必定的瞭解,今天就寫到這裏,下次總結一下別的。