Debug.Log a JSON array

Hi guys,

I have a JSON parser in my game which can be found here:

http://wiki.unity3d.com/index.php?title=JSONParse

It works PERFECTLY but the problem is that Debug.Log() doesn’t Log all objects in the JSON array.

What I would like to know is how I can Debug.Log a JSON array (kind of the same way that PHP uses var_dump() ).

The code I use:

function Save(data)
{
	Debug.Log(data); // --> data#
	_Data = JSONParse.JSONParse(data);
	Debug.Log(_Data); // --> returns: Boo.Lang.Hash
	for (fields in _Data)
	{
		Debug.Log(fields); // --> returns: System.Collections.DictionaryEntry
		for (field in fields)
		{
			Debug.Log(field); // --> returns: error#
		}
	}
}

data# : {“server”:{“connected”:true,“name”:“Test Server”,“error”:false}}

error# : ApplicationException: Argument is not enumerable (does not implement System.Collections.IEnumerable).
Boo.Lang.Runtime.RuntimeServices.GetEnumerable

“a JSON object” isn’t a very clear thing in Unity since there is nothing like that. You use a JSON Parser which “probably” converts the JSON string into a Dictionary and Array / List representation. If the types this parser uses doesn’t implement such a function, you can’t simply “print” it’s content.

It seems GitHub is down for maintanance at the moment so i can’t take a look at the parser, but it seems _Data contains just a dictionary (HashTable). when you iterate over a hachtable you will get DictionaryEntry which have a Key and a Value.

This should work:

for (field in _Data)
{
    Debug.Log(field.Key + " = " + field.Value);
}

edit

Well, it seems he’s using a Hashtable and the ArrayList class. If you want to “iterate” through the whole structure you have to write a recursive function that processes each item seperately and test for the type. I never use UnityScript, so i can’t offer an example. I’ve written a simple JSON parser / builder in C# but haven’t posted it on the wiki yet. I will post it the other day, but these days i don’t have much time :wink: Actually it’s 03:15 again and i should go to bed now :wink:

My parser uses strong typed classes and each “Node” can be rebuilded as a JSON string. I recently improved the usage and added a custom binary serialisation / deserialization with optional BZip2(using SharpZipLib) compression and Base64 encode

Before i can post it to the wiki i have to create some examples and have to test if and how all of it’s features work in UnityScript as well.

edit(2012.12.30)
I finally posted my SimpleJSON framework to the wiki.

Here is the JSON Parser, since gitgub is offline:

/*

JSONParse.js
A JSON Parser for the Unity Game Engine
 
Based on json_parse by Douglas Crockford
Ported by Philip Peterson (ironmagma/ppeterson)

*/



private static var at : int;

private static var ch : String;

private static var escapee = {
            "\"": "\"",
            "\\": "\\",
            "/": "/",
            "b": "b",
            "f": "\f",
            "n": "

",
“r”: “\r”,
“t”: " "
};

private static var text : String;

private static function error (m) : void {
    throw new System.Exception("SyntaxError: 

Message: "+m+
"
At: "+at+
"
Text: "+text);
}

private static function next (c) : System.String {

    if(c && c != ch) {
        error("Expected '" + c + "' instead of '" + ch + "'");
    }
    
    
    if(text.length >= at+1) {
        ch = text.Substring(at, 1);
    }
    else {
        ch = "";
    }
    
    at++;
    return ch;
    
}

private static function next () {
    return next(null);
}

private static function number () : Number {
    var number;
    var string = "";
    
    if(ch == "-") {
        string = "-";
        next("-");
    }
    while(ch in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]) {
        string += ch;
        next();
    }
    if(ch == ".") {
        string += ".";
        while(next() && ch in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]) {
            string += ch;
        }
    }
    if(ch == "e" || ch == "E") {
        string += ch;
        next();
        if(ch == "-" || ch == "+") {
            string += ch;
            next();
        }
        while(ch in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]) {
            string += ch;
            next();
        }
    }
    number = Number.Parse(string);
    
    if (System.Double.IsNaN(number)) {
        error("Bad number");
    } else {
        return number;
    }
    
}


private static function string () : System.String {
    var hex : int;
    var i : int;
    var string : String = "";
    var uffff : int;
    
    if(ch == "\"") {
        while(next()) {
            if(ch == "\"") {
                next();
                return string;
            } else if (ch == "\\") {
                next();
                if(ch == "u") {
                    uffff = 0;
                    for(i = 0; i < 4; i++) {
                        hex = System.Convert.ToInt32(next(), 16);
                        if (hex == Mathf.Infinity || hex == Mathf.NegativeInfinity) {
                            break;
                        }
                        uffff = uffff * 16 + hex;
                    }
                    var m : char = uffff;
                    string += m;
                } else if(ch in escapee) {
                    string += escapee[ch];
                } else {
                    break;
                }
            } else {
                string += ch;
            }
        }
    }
    error("Bad string");
};



private static function white () : void {
    while(ch && (ch.length >= 1 && ch.Chars[0] <= 32)) { // if it's whitespace
        next();
    }   
}

private static function value () : System.Object {
    white();
    // Again, we have to pass on the switch() statement.
    
    if(ch == "{") {
        return object();
    } else if(ch == "[") {
        return array();
    } else if(ch == "\"") {
        return string();
    } else if(ch == "-") {
        return number();
    } else {
        return (ch in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]) ? number() : word();
    }
    
};

private static function word () {
    // We don't use a switch() statement because
    // otherwise Unity will complain about
    // unreachable code (in reality it's not unreachable).
    
    if(ch == "t") {
        next("t");
        next("r");
        next("u");
        next("e");
        return true;
    } else if (ch == "f") {
        next("f");
        next("a");
        next("l");
        next("s");
        next("e");
        return false;
    } else if (ch == "n") {
        next("n");
        next("u");
        next("l");
        next("l");
        return null;
    } else if (ch == "") { 
        return null; // Todo: why is it doing this?
    }
    
    error("Unexpected '" + ch + "'");
}

private static function array () {
    
    var array : Array = new Array();
    
    if(ch == "[") {
        next("[");
        white();
        if(ch == "]") {
            next("]");
            return array; // empty array
        }
        while(ch) {
            array.Push(value());
            white();
            if(ch == "]") {
                next("]");
                return array;
            }
            next(",");
            white();
        }
    }
    error("Bad array");
};

private static function object () {
    
    var key;
    var object = {};
    
    if(ch == "{") {
        next("{");
        white();
        if(ch == "}") {
            next("}");
            return object; // empty object
        }
        while(ch) {
            key = string();
            white();
            next(":");
            object[key] = value();
            white();
            if (ch == "}") {
                next("}");
                return object;
            }
            next(",");
            white();
        }
    }
    error("Bad object");
}



public static function JSONParse (source, reviver) {
    var result;
    
    text = source;
    at = 0;
    ch = " ";
    result = value();
    white();
    if (ch) {
        error("Syntax error");
    }

    return result;
    
}

public static function JSONParse (source) {
    return JSONParse(source, null);
}