zoukankan      html  css  js  c++  java
  • 使用.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;
        ......
    }
    

      

  • 相关阅读:
    约合¥1720 LG法国称G Watch将于6月开卖
    c语言中的位移位操作
    兼容的动态加载JS【原】
    Oracle 10g AND Oracle 11g手工建库案例--Oracle 10g
    面向对象思想----不看懊悔!
    学习设计模式--观察者模式(C++)
    使用POI 导入excel
    机器学习 F1-Score, recall, precision
    阿里无线11.11:手机淘宝移动端接入网关基础架构演进之路
    ICE 迁移64位安装问题
  • 原文地址:https://www.cnblogs.com/wmesci/p/3031083.html
Copyright © 2011-2022 走看看