- Home /
Using JSON to get tree data into JavaScript objects
I am using JSON to transfer data back and forth between my database and my unity app. JSON is a nice alternative to XML that is faster.
Currently I am passing (variable depth acyclic) tree structures.
I have found a C# parser called litJSON that is compatible with all .net languages. An informative thread about this can be found at : http://answers.unity3d.com/questions/531/what-is-the-easiest-json-library-to-integrate-with-unity Here you may also find a useful script for getting the data out of the JSON string. All C# coders that are thinking about using JSON as a data carrier should check it out.
But alas, I can not get it to work. My problem is that i am trying to use JavaScript and I am not able to access the objects made in C#. (Is this possible?) I've been trying for three days, and I am stuck. Can anyone point me towards a simple way of building a tree structure of objects in javascript based on a JSON string? I am a bit confused because the JSON parsers out there promising to do this are all JavaScript, not Unity JavaScript, and the eval() function does not exist in Unity Javascript (or does it?).
How can I create a javascript object tree from JSON string (similar to eval()) at runtime.
Answer by duck · Jul 20, 2010 at 08:40 AM
If the JSON parser script that you're trying to use is C#, and you're trying to access the results from Javascript, you are most likely running into the compilation order problem.
See this answer for details, but basically you may find that putting your JSON parser scripts into a new folder named "Plugins" (in your Assets folder), will solve your problem.
Thank you. I did, and I got it to work now. Cheers. And as I read in the documentation, i cant go both ways, something has to compile first. This means I cannot write to the console when in C# (placed in the plugin folder). Guess this is something I will have to live with.
Jens T - Would you $$anonymous$$d posting a full solution to this problem yourself? I have to do this in the next few days, and a quick walkthrough would be immensely useful.
I will. I just have to do it first. Planning to do it next week. Decided to have sit-down with a friend of $$anonymous$$e who is "The lord of code" or something. I am the "Lord of Datastructures". Together we control the matrix.
Answer by Jens T · Sep 21, 2010 at 06:10 AM
Sorry for the delay everybody. Here is an simplified version of the parser*
Trying feeding it pure string first, then get it to work using a textasset. Then finally, try to get the WWW object coroutine bastard thing to work (with yield).
And you need a class called Component (Comp) to get this to work. It should implement the following methods : setParentComponent(Comp), getComponentName():String, and a few more, you will notice them in the code.
class JsonParser { private var str : String = null; private var cix : int = 0; private var identifiers : String = "{}[],:"; private var debug : boolean =false; private var arr:Array = new Array();
function Parse( json : String )
{
str = json;
cix = 0;
out( str );
var componentRoot = new Comp();
ReadObject(componentRoot);
}
function ReadObject(intoComp:Comp) : Array
{
str.Trim();
while ( cix < str.length )
{
if ( ReadTo( "{" ) == "Component" )
{
comp = ReadComponent(intoComp);
if ( comp ){
comp.setParentComponent(intoComp);
break;
}else{
Error( "Adding Assembly failed!" );
break;
}
}
else
{
Error( "Assembly expected" );
return null;
}
if ( NextIdentifier() == "," ){
ReadTo(",");
}
}
}
function ReadComponent(parentComp :Comp)
{
var comp : Comp = new Comp();
// Out("Adding new component under "+ parentComp.getComponentName()+);
while ( ReadyAttribute() )
{
var attrName = ReadTo( ":" );
switch( attrName )
{
case "name":
comp.setComponentName(ReadString());
break;
case "children":
ReadComponentChildren( comp);
break;
case "assetLink":
comp.setAssetLink(ReadString());
break;
case "x":
comp.setXoffset(ReadFloat());
break;
case "y":
comp.setYoffset(ReadFloat());
break;
case "z":
comp.setZoffset(ReadFloat());
break;
case "h":
comp.setAYoffset(ReadFloat());
break;
case "p":
comp.setAXoffset(ReadFloat());
break;
case "b":
comp.setAZoffset(ReadFloat());
break;
default:
Error( "Unidentified Component attribue: '" + attrName + "'");
ReadToAny("},");
--cix;
break;
}
}
if ( NextIdentifier() == "}" )
{
ReadTo( "}" );
}
else
Error( "'}' or ':' expected" );
}
function ReadComponentChildren( parent : Comp)
{
if ( NextIdentifier() == "[" )
{
ReadTo("[");
while( NextIdentifier() != "]" )
{
var objName = ReadTo( "{" );
switch( objName )
{
case "Component":
ReadComponent(parent);
componentsAdded ++;
break;
if ( NextIdentifier() == "," ){
ReadTo( "," );
}
}
ReadTo("]");
}
else
{
Error( "'[' expected");
}
}
function ReadTo( identifier : String )
{
var pos : int = str.IndexOf( identifier, cix ); // Find first occurance of identifier after current position.
var length : int = pos - cix; // Find distance from current position to identifier ( size of substring )
var result : String = str.Substring( cix, length ).Trim(); // Get substring and remove whitespace.
cix = pos + 1; // Update current position to include identifier.
out( "Read: " + result );
return result;
}
function ReadToAny( identifiers : String )
{
var pos : int = str.IndexOfAny( identifiers.ToCharArray(), cix );
var length : int = pos - cix;
var result : String = str.Substring( cix, length ).Trim();
cix = pos + 1;
out( "Read: " + result );
return result;
}
function NextIdentifier()
{
if (cix < str.Length){
var pos : int = str.IndexOfAny( identifiers.ToCharArray(), cix );
if (pos < str.Length){
var result : char = str.Chars[pos];
return result;
}
}
}
function ReadString()
{
var begin : int = str.IndexOf( "\"", cix ) + 1;
var end : int = str.IndexOf( "\"", begin );
var length : int = end - begin;
var string : String = str.Substring( begin, length );
cix = end + 1;
out( "String: " + string );
return string;
}
function ReadInteger()
{
var numbers : String = "0123456789-";
var delimit : String = " ,\n]}";
var begin : int = str.IndexOfAny( numbers.ToCharArray(), cix );
var end : int = str.IndexOfAny( delimit.ToCharArray(), begin );
var length : int = end - begin;
var numStr : String = str.Substring( begin, length );
var valueAsFloat :float = parseFloat( numStr );
var value:int = Mathf.Floor(valueAsFloat);
cix = end;
out( "Integer: " + value );
return value;
}
function ReadFloat()
{
var numbers : String = "0123456789.-";
var delimit : String = " .\n}]";
var begin : int = str.IndexOfAny( numbers.ToCharArray(), cix );
var end : int = str.IndexOfAny( delimit.ToCharArray(), begin );
var length : int = end - begin;
var numStr : String = str.Substring( begin, length );
var value : float = parseFloat( numStr );
cix = end;
out( "Float: " + value );
return value;
}
function ReadBoolean():boolean{
var numbers : String = "0123456789.-";
var delimit : String = " .\n}]";
var begin : int = str.IndexOfAny( numbers.ToCharArray(), cix );
var end : int = str.IndexOfAny( delimit.ToCharArray(), begin );
var length : int = end - begin;
var value : String = str.Substring( begin, length );
switch (str){
case "true" :
cix = end;
return true;
break;
case "false" :
cix = end;
return false;
break;
}
out( "Float: " + value );
}
function ReadyAttribute()
{
if ( NextIdentifier() == "," )
cix = str.IndexOf(",", cix) + 1;
if ( NextIdentifier() == ":" )
return true;
if ( NextIdentifier() == "}" )
return false;
}
function Error( msg : String )
{
Debug.Log( "ERROR: " + msg + " at (" + cix + ") : " + str.Substring( cix, Mathf.Min( str.length - cix, 100) ).Trim() + "..." );
}
function Warning( msg : String )
{
Debug.Log( "Warning: " + msg + " at (" + cix + ") : " + str.Substring( cix, Mathf.Min( str.length - cix, 100) ).Trim() + "..." );
}
function out(msg:String){
if(debug){
Debug.Log( "MESSAGE: " + msg + " at (" + cix + ") : " + str.Substring( cix, Mathf.Min( str.length - cix, 100) ).Trim() + "..." );
}
}
}
Hi! can you please give me a sample of the Component (Comp) class??
Answer by scone · Oct 15, 2010 at 09:17 PM
I've also written a simple parser, which I think might be easier to use. It's up on the UnifyCommunity Wiki. Check it out.
Your answer
Follow this Question
Related Questions
parse json 2 Answers
How can I find specific parts of an XML and feed them into dialogue? 2 Answers
Setting Scroll View Width GUILayout 1 Answer
Is there eval() for C#? 2 Answers
XML parser, how to get to 1 of many elements with the same name. 1 Answer