使用.NET4.0的dynamic特性解析plist文件及json字符串
1.解析plist文件:
using System; using System.IO; using System.Linq; using System.Xml.Linq; using System.Dynamic; using System.Collections.Generic; public class DynamicDictionary : DynamicObject { public IDictionary<string, object> Items; public override bool TryGetMember(GetMemberBinder binder, out object result) { if (Items == null || !Items.TryGetValue(binder.Name, out result)) result = null; if (result is DynamicDictionary) result = (dynamic)result; return true; } public override bool TrySetMember(SetMemberBinder binder, object value) { if (Items == null) Items = new Dictionary<string, object>(); if (value is IDictionary<string, object>) value = new DynamicDictionary() { Items = (IDictionary<string, object>)value }; else if (value is IEnumerable<IDictionary<string, object>>) value = from x in (IEnumerable<IDictionary<string, object>>)value select new DynamicDictionary() { Items = x }; Items[binder.Name] = value; return true; } } /// <summary>plist文件解析器</summary> public class Plist : DynamicDictionary { public Plist() { Items = new Dictionary<string, object>(); } public Plist(string file) { var doc = XDocument.Load(file); Items = Parse(doc.Element("plist").Element("dict")); } private static IDictionary<string, object> Parse(XElement dict) { if (dict == null || dict.Name != "dict") throw new ArgumentException(); var ret = new Dictionary<string, object>(); var elements = dict.Elements().ToArray(); for (int i = 0; i < elements.Length; i += 2) { var key = elements[i].Value; var node = elements[i + 1]; switch (node.Name.LocalName) { case "string": ret[key] = node.Value; break; case "real": case "integer": ret[key] = int.Parse(node.Value.Trim()); break; case "true": ret[key] = true; break; case "false": ret[key] = false; break; case "date": ret[key] = DateTime.Parse(node.Value.Trim()); break; case "data": ret[key] = Convert.FromBase64String(node.Value.Trim()); break; case "array": ret[key] = from n in node.Elements() select new DynamicDictionary() { Items = Parse(n) }; break; case "dict": ret[key] = new DynamicDictionary() { Items = Parse(node) }; break; default: throw new NotSupportedException(); } } return ret; } private static XElement Save(IDictionary<string, object> dict) { var node = new XElement("dict"); foreach (var kv in dict) { node.Add(new XElement("key", kv.Key)); if (kv.Value is string) node.Add(new XElement("string", kv.Value)); else if (kv.Value is int) node.Add(new XElement("integer", kv.Value)); else if (kv.Value is bool) node.Add(new XElement(kv.Value.ToString())); else if (kv.Value is DateTime) node.Add(new XElement("date", kv.Value)); else if (kv.Value is byte[]) node.Add(new XElement("data", Convert.ToBase64String((byte[])kv.Value))); else if (kv.Value is DynamicDictionary) node.Add(Save(((DynamicDictionary)kv.Value).Items)); else if (kv.Value is IEnumerable<DynamicDictionary>) node.Add(new XElement("array", from x in (IEnumerable<DynamicDictionary>)kv.Value select Save(x.Items))); } return node; } public void Save(string file) { using (var stream = File.Open(file, FileMode.Create, FileAccess.Write, FileShare.None)) Save(stream); } public void Save(Stream stream) { var doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"), new XElement("plist", Save(Items))); doc.Save(stream); } }
使用方法:
dynamic plist = new Plist(file); //加载plist文件 string key = (string)plist.Key; //获取值 if(plist.Name == null) //等于null表示plist文件中不包含节点Name { plist.Name = "esci"; //添加节点Name并赋值为esci } plist.Save(file); //保存为plist文件
2.解析json
public class Json : DynamicObject { private IDictionary<string, object> Dictionary; public Json(IDictionary<string, object> dictionary) { this.Dictionary = dictionary; } public override bool TryGetMember(GetMemberBinder binder, out object result) { result = this.Dictionary[binder.Name]; if (result is IDictionary<string, object>) { this.Dictionary[binder.Name] = result = new Json(result as IDictionary<string, object>); } else if (result is IEnumerable && !(result is string)) { var list = new List<object>(); foreach (var i in (result as IEnumerable)) { if (i is IDictionary<string, object>) list.Add(new Json(i as IDictionary<string, object>)); else list.Add(i); } this.Dictionary[binder.Name] = result = list; } return true; } static readonly JavaScriptSerializer jss = new JavaScriptSerializer(); public static dynamic Deserialize(string json) { return new Json(jss.Deserialize(json, typeof(object)) as IDictionary<string, object>); } public static string Serialize(object obj) { return jss.Serialize(obj); } }
使用方法:
dynamic json = Json.Deserialize(str); if (json != null) { string msg = json.message; ...... }