Exemplo n.º 1
0
Arquivo: Json.cs Projeto: nir94/Eddie
        private static bool FromJson(string s, bool canThrowException, out object result, out string remain)
        {
            try
            {
                s = s.TrimStart();

                if (s == "")
                {
                    throw new Exception("Empty value");
                }

                if (s[0] == '[')
                {
                    s = s.Substring(1).TrimStart();
                    Json a = new Json();
                    a.InitAsArray();
                    for (;;)
                    {
                        if (s[0] == ']')
                        {
                            break;
                        }
                        object v;
                        FromJson(s, canThrowException, out v, out s);
                        a.Append(v);
                        s = s.TrimStart();
                        if (s[0] == ',')
                        {
                            s = s.Substring(1).TrimStart();
                        }
                    }
                    result = a;
                    remain = s.Substring(1).TrimStart();
                    return(true);
                }
                else if (s[0] == '{')
                {
                    s = s.Substring(1).TrimStart();
                    Json a = new Json();
                    a.InitAsDictionary();
                    for (;;)
                    {
                        if (s[0] == '}')
                        {
                            break;
                        }
                        object k;
                        FromJson(s, canThrowException, out k, out s);
                        s = s.TrimStart();
                        if (s[0] == ':')
                        {
                            s = s.Substring(1).TrimStart();
                            object v;
                            FromJson(s, canThrowException, out v, out s);
                            a.SetKey(k as string, v);
                            s = s.TrimStart();
                            if (s[0] == ',')
                            {
                                s = s.Substring(1).TrimStart();
                            }
                        }
                        else
                        {
                            throw new Exception("Syntax error");
                        }
                    }
                    result = a;
                    remain = s.Substring(1).TrimStart();
                    return(true);
                }
                else
                {
                    // Direct value
                    bool inQuote = false;

                    int i = 0;
                    for (i = 0; i < s.Length + 1; i++)
                    {
                        char ch = (char)0;
                        if (i < s.Length)
                        {
                            ch = s[i];
                        }

                        if (inQuote)
                        {
                            if ((ch == '\"') && ((i == 0) || (s[i - 1] != '\\')))
                            {
                                inQuote = false;
                            }
                        }
                        else
                        {
                            if ((ch == '\"') && ((i == 0) || (s[i - 1] != '\\')))
                            {
                                inQuote = true;
                            }
                            else if ((ch == (char)0) ||
                                     (ch == ',') ||
                                     (ch == ':') ||
                                     (ch == '}') ||
                                     (ch == ']'))
                            {
                                // Valore singolo
                                string value = s.Substring(0, i).Trim();

                                if ((value.StartsWith("\"")) && (value.EndsWith("\"")))
                                {
                                    result = DecodeString(value.Substring(1, value.Length - 2));
                                    remain = s.Substring(i);
                                    return(true);
                                }

                                if (value == "null")
                                {
                                    result = null;
                                    remain = s.Substring(i);
                                    return(true);
                                }

                                if (value == "true")
                                {
                                    result = true;
                                    remain = s.Substring(i);
                                    return(true);
                                }

                                if (value == "false")
                                {
                                    result = false;
                                    remain = s.Substring(i);
                                    return(true);
                                }

                                int dI = 0;
                                if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out dI))
                                {
                                    result = dI;
                                    remain = s.Substring(i);
                                    return(true);
                                }

                                double dD = 0;
                                if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out dD))
                                {
                                    result = dD;
                                    remain = s.Substring(i);
                                    return(true);
                                }

                                throw new Exception("Cannot detect type of value '" + value + "'");
                            }
                        }
                    }
                    throw new Exception("Syntax error");
                }
            }
            catch (Exception e)
            {
                if (canThrowException)
                {
                    throw new Exception("JsonParser:" + e.Message);
                }
            }
            result = null;
            remain = s;
            return(false);
        }
Exemplo n.º 2
0
        public static Json ToJson(XmlElement xml)
        {
            /*
             * Comments are ignored.
             * Node renames in json conversion can be forced with attribute json-convert-name.
             * Key name are lowered-case.
             *
             * Can fail if:
             * 1- There are duplicate child names. Example:
             * <test>
             *	<alfa/>
             *	<beta/>
             *	<alfa/>
             * </test>
             * If all childs have the same name, works (detected as Array)
             *
             * 2- There are nested texts. Example:
             * <test>
             *	mytext1
             *	<alfa/>
             *	mytext2
             * </test>
             *
             */

            Json result = new Json();

            foreach (XmlAttribute attr in xml.Attributes)
            {
                string keyName = attr.Name.ToLowerInvariant();
                if (keyName.StartsWith("json-convert-"))
                {
                    continue;
                }

                // Try Cast?
                if (result.HasKey(keyName))
                {
                    throw new Exception("Cannot convert.");
                }

                object value = attr.Value;

                if (attr.Value.ToLowerInvariant() == "true")
                {
                    value = true;
                }
                else if (attr.Value.ToLowerInvariant() == "true")
                {
                    value = false;
                }

                result.SetKey(keyName, value);
            }

            // Exception: if not have attributes, and childs are XmlElement with all the same name, use Json Array.
            bool isArray = false;

            if (xml.Attributes.Count == 0)
            {
                isArray = true;
                string commonName      = "";
                int    nChildsWithName = 0;              // Not really used yet
                foreach (XmlNode child in xml.ChildNodes)
                {
                    if (child is XmlComment)
                    {
                        // Ignore
                    }
                    else if (child is XmlText)
                    {
                        // No Array
                        isArray = false;
                        break;
                    }
                    else if (child is XmlElement)
                    {
                        XmlElement xmlElement = child as XmlElement;
                        string     keyName    = child.Name.ToLowerInvariant();
                        if (xmlElement.HasAttribute("json-convert-name"))
                        {
                            keyName = xmlElement.GetAttribute("json-convert-name");
                        }

                        if (commonName == "")
                        {
                            commonName = keyName;
                        }
                        else if (commonName != keyName)
                        {
                            // No Array
                            isArray = false;
                            break;
                        }
                        nChildsWithName++;
                    }
                    else
                    {
                        throw new Exception("Xml node unknown type");
                    }
                }
            }

            foreach (XmlNode child in xml.ChildNodes)
            {
                if (child is XmlComment)
                {
                    // Ignore
                }
                else if (child is XmlText)
                {
                    /*
                     * if (result.HasKey(child.ParentNode.Name))
                     *      throw new Exception("Cannot convert.");
                     * result.SetKey(child.ParentNode.Name, child.InnerText);
                     */
                }
                else if (child is XmlElement)
                {
                    XmlElement xmlChild = child as XmlElement;

                    // Exception: if contain text
                    bool textFound = false;
                    foreach (XmlNode xmlChild2 in xmlChild.ChildNodes)
                    {
                        if (xmlChild2 is XmlText)
                        {
                            result.SetKey(xmlChild.Name.ToLowerInvariant(), xmlChild.InnerText);
                            textFound = true;
                            break;
                        }
                    }
                    if (textFound)
                    {
                        continue;
                    }

                    // Exception: if have only two attribute 'name' and 'value'
                    if ((xmlChild.Attributes.Count == 2) && (xmlChild.HasAttribute("name")) && (xmlChild.HasAttribute("value")))
                    {
                        if (result.HasKey(xmlChild.GetAttribute("name")))
                        {
                            throw new Exception("Cannot convert.");
                        }
                        result.SetKey(xmlChild.GetAttribute("name").ToLowerInvariant(), xmlChild.GetAttribute("value"));
                    }
                    else
                    {
                        XmlElement xmlElement = child as XmlElement;
                        string     keyName    = child.Name.ToLowerInvariant();
                        if (xmlElement.HasAttribute("json-convert-name"))
                        {
                            keyName = xmlElement.GetAttribute("json-convert-name");
                        }
                        if ((isArray == false) && (result.HasKey(keyName)))
                        {
                            throw new Exception("Cannot convert.");
                        }

                        Json jChild = ToJson(xmlElement);

                        if (isArray)
                        {
                            result.Append(jChild);
                        }
                        else
                        {
                            result.SetKey(keyName, jChild);
                        }
                    }
                }
                else
                {
                    throw new Exception("Xml node unknown type");
                }
            }

            return(result);
        }