這種做法最有彈性, 可以靠著改變 XmlWriterSettings 以及 XmlSerializerNamespaces 的設定去控制序列化出來的 XML 字串的格式與內容, 但要特別注意的是 XmlWriterSettings 預設是有 BOM 的 UTF-8 編碼, 如果接收資料的一方無法處理這種格式的話, 需要特別將 XmlWriterSettings.Encoding 設成無 BOM 的編碼格式, 例如: var ws = new XmlWriterSettings() { Encoding = new UTF8Encoding() }, 比較適合用在需要跟許多不同外部系統介接的模組上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
publicstringSerialize(Encoding encoding) { var serializer = new XmlSerializer(typeof(MyModel));
var ws = new XmlWriterSettings() { Encoding = encoding };
var ns = new XmlSerializerNamespaces(new XmlQualifiedName[] { XmlQualifiedName.Empty });
using (var ms = new MemoryStream()) using (var xw = XmlWriter.Create(ms, ws)) { serializer.Serialize(xw, new MyModel(), ns); return ws.Encoding.GetString(ms.ToArray()); } }
publicstringSerialize(Encoding encoding) { var serializer = new XmlSerializer(typeof(MyModel));
var ns = new XmlSerializerNamespaces(new XmlQualifiedName[] { XmlQualifiedName.Empty });
using (var ms = new MemoryStream()) using (var sw = new StreamWriter(ms, encoding)) // 2nd arg default to utf-8 no BOM { serializer.Serialize(sw, new MyModel(), ns); return encoding.GetString(ms.ToArray()); } }
public T DeSerialize_FromStream<T>(string xml, Encoding encoding) { var serializer = new XmlSerializer(typeof(T));
var xmlBytes = encoding.GetBytes(xml); using (var ms = new MemoryStream(xmlBytes)) using (var xr = XmlReader.Create(ms)) { xr.Read(); var result = serializer.Deserialize(xr); if (result != null) { return (T)result; } returndefault(T); } }
public T DeSerialize_FromStringReader<T>(string xml) { var serializer = new XmlSerializer(typeof(T));
using (var sr = new StringReader(xml)) using (var xr = XmlReader.Create(sr)) { xr.Read(); var result = serializer.Deserialize(xr); if (result != null) { return (T)result; } returndefault(T); } }
public T DeSerialize_StreamReader<T>(string xml, Encoding encoding) { var serializer = new XmlSerializer(typeof(T));
var xmlBytes = encoding.GetBytes(xml); using (var ms = new MemoryStream(xmlBytes)) using (var tr = new StreamReader(ms, encoding)) { var result = serializer.Deserialize(tr); if (result != null) { return (T)result; } returndefault(T); } }
public T DeSerialize_Stream<T>(string xml, Encoding encoding) { var serializer = new XmlSerializer(typeof(T));
var xmlBytes = encoding.GetBytes(xml); using (var ms = new MemoryStream(xmlBytes)) { var result = serializer.Deserialize(ms); if (result != null) { return (T)result; } returndefault(T); } }
StringReader
這種方法在 XML 字串有 DOM 的時候會出 Exception, 優點是不用考慮編碼格式, 只需要知道 XML 字串就可以了.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public T DeSerialize<T>(string xml) { var serializer = new XmlSerializer(typeof(T));
using (var sr = new StringReader(xml)) { var result = serializer.Deserialize(sr); if (result != null) { return (T)result; } returndefault(T); } }
小結
反序列化大部分的做法都很簡單, 以目前實驗看來, 把 XML 字串先轉成 Stream 再處理都可以相容有 BOM 的資料來源, 需要考量的點似乎也比序列化時少很多.
結論
這篇只是要實驗各種序列化與反序列化的方式遇到 BOM 時候的結果, 所以沒有特別實驗各種不同方式在其他複雜的 XML 資料下的轉換結果, 如果之後有遇到其他問題的話再回來補.