/**
         * @ 转换JToken对象到IPListNode
         * */
        protected IPListNode SwitchJToken(JToken token)
        {
            IPListNode node = null;

            switch (token.Type)
            {
            case JTokenType.Array:
                node = new PListArray();
                SetNodeTag(node, token);
                node.ReaderJson(token);
                break;

            case JTokenType.Object:
                node = new PListDict();
                SetNodeTag(node, token);
                node.ReaderJson(token);
                break;

            default:
                node = new PListDict();
                if (token.Type == JTokenType.Property)
                {
                    JProperty  jproperty    = (JProperty)token;
                    IPListNode childrenNode = null;
                    if (jproperty.Value.Type == JTokenType.Array)
                    {
                        childrenNode = new PListArray();
                    }
                    else
                    {
                        childrenNode = new PListDict();
                    }

                    childrenNode.Tag = jproperty.Name;
                    ((PListDict)node).Add(childrenNode.Tag, childrenNode);
                    childrenNode.ReaderJson(jproperty.Value);
                }
                else
                {
                    // 如果上级是数组不用设置 tag 的
                    SetNodeTag(node, token);
                    JValue jValue = (JValue)token;
                    node.Value = jValue.Value;
                }
                break;
            }
            return(node);
        }
        /**
         * @ 把元素的值包装成接口 IPListNode 类型
         * */
        protected virtual IPListNode ParseNode(XElement reader)
        {
            string        key       = reader.Name.LocalName;
            NodeValueType valueType = key.ToUpper().ToEnum <NodeValueType>();
            IPListNode    node      = new PListDict();
            string        val       = string.Empty;

            switch (valueType)
            {
            case NodeValueType.DICT:
                node.ReaderXml(reader);
                break;

            case NodeValueType.ARRAY:
                node = new PListArray();
                node.ReaderXml(reader);
                break;

            case NodeValueType.DATE:
                node.Value = reader.Value.ToDateTime();
                break;

            case NodeValueType.DATA:
                node.Value = reader.Value.ToBytes();
                break;

            case NodeValueType.FALSE:
            case NodeValueType.TRUE:
                node.Value = valueType == NodeValueType.TRUE;
                break;

            case NodeValueType.REAL:
                node.Value = reader.Value.ToDecimal();
                break;

            case NodeValueType.INTEGER:
                node.Value = reader.Value.ToInt();
                break;

            default:
                node.Value = reader.Value;
                break;
            }
            return(node);
        }
        /**
         * @ 将json字符串反序列化为plist对象
         * */
        public virtual IPListNode FromJson(string json)
        {
            IPListNode node  = null;
            JToken     token = JsonConvert.DeserializeObject <JToken>(json);

            if (token.Type == JTokenType.Array)
            {
                node = new PListArray();
            }
            else if (token.Type == JTokenType.Object)
            {
                node = new PListDict();
            }

            node.ReaderJson(token);

            return(node);
        }