Difference between revisions of "LlJsonValueType"

From Second Life Wiki
Jump to navigation Jump to search
(the first example is more like pseudo-code that is lossibly very buggy. but it is a practical starting example)
(Formatting cleanup.)
 
(17 intermediate revisions by 4 users not shown)
Line 8: Line 8:
|func_desc=Gets the [http://json.org JSON] type for the value in {{LSLPT|json}} at the location {{LSLPT|specifiers}}.  
|func_desc=Gets the [http://json.org JSON] type for the value in {{LSLPT|json}} at the location {{LSLPT|specifiers}}.  
|Return_text=specifying the type of the value at {{LSLPT|specifiers}} in {{LSLPT|json}}.
|Return_text=specifying the type of the value at {{LSLPT|specifiers}} in {{LSLPT|json}}.
|spec=See [[Json_usage_in_LSL]]
|spec=See [[Json_usage_in_LSL|Json usage in LSL]].
|constants={{LSL_Constants/JSON}}
|constants= ===Constants===
|examples=
{{LSL_Constants/JSON}}
<lsl>
|examples=<source lang="lsl2">


//all these functions are untested functions
 
//see them as buggy PSEUDO-code and consider yourself lucky if there are less than 10 syntax errors, 2 wrong counters and 4 bad pointers/names.
//all these functions are untested functions that may have some very strange cases were they acd badly or where the comments are wrong
//see them as buggy PSEUDO-code and consider yourself lucky if there are less than 2 wrong counters and 4 bad pointers/names.
//they are more an example and a concept and unlikely fully functional AS IS.
//they are more an example and a concept and unlikely fully functional AS IS.
 
string JisI(string j){if(llJsonValueType(j,[])==JSON_INTEGER)return 1llJsonGetValue(j,[]);return "";}
string JisN(string j){if(llJsonValueType(j,[])==JSON_NUMBER  )return llJsonGetValue(j,[]);return "";}
//return the JSON if "j" is a JSON_INTEGER, like j="1"  j="-2"  j="0"                 otherwise return 0;
//return the JSON if "j" is a JSON_NUMBER, like j="10.1234"  j="-0.1234"  j="3.14159"  j="-1" j="123456"  otherwise return "";
//these would be string representations of an integer because j is a string.
//these would be sting representations of a float because j is a string.
 
//storing floats in a JSON will easily lose you a lot of accuracy. Integers stored in JSON may have a smaller range than 32-bit signed integers.
string JisF(string j){if(llJsonValueType(j,[])==JSON_FLOAT )return 1llJsonGetValue(j,[]);return "";}
//return the JSON if "j" is a JSON_FLOAT, like j="10.1234"  j="-0.1234" j="3.14159"  otherwise return 0;
//these would be sting representations of an float because j is a string.
//storing floats in a JSON will easily lose you a lot of accuracy.
 
string JisA(string j){if(llJsonValueType(j,[])==JSON_ARRAY  )return llJsonGetValue(j,[]);return "";}
string JisA(string j){if(llJsonValueType(j,[])==JSON_ARRAY  )return llJsonGetValue(j,[]);return "";}
//return the JSON if "j" is a JSON_ARRAY, like j="[]"  j="[1,2]"  j="[[1],[3,4]]"     otherwise return "";
//return the JSON if "j" is a JSON_ARRAY, like j="[]"  j="[1,2]"  j="[[1],[3,4]]"                       otherwise return "";
//these would be string representations of a (nested) list because j is a string.
//these would be string representations of a (nested) list because j is a string.
 
string JisS(string j){if(llJsonValueType(j,[])==JSON_STRING )return llJsonGetValue(j,[]);return "";}
string JisS(string j){if(llJsonValueType(j,[])==JSON_STRING )return llJsonGetValue(j,[]);return "";}
//return the string that is stored in "j" if "j" is a JSON_STRING, like j="\"PI\""  j="\"3.14\""  j="\"-1\"" otherwise return "";
//return the string that is stored in "j" if "j" is a JSON_STRING, like j="\"PI\""  j="\"3.14\""  j="\"-1\"" otherwise return "";
Line 35: Line 32:
//because j is a string that is also able to store numbers and floats and (nested) lists ... as strings.  
//because j is a string that is also able to store numbers and floats and (nested) lists ... as strings.  
//this returns the string within "j" if "j" is "A string within a string".  
//this returns the string within "j" if "j" is "A string within a string".  
/*
if (JisS(j)){} will still work because JisS(j) returns an empty string="" if "j" is NOT a JSON_STRING.
*/
 
 
/*the above functions return strings to be used in simple  
/*the above functions return strings to be used in simple  
if(JisN(j)){}
if(JisA(j)){}  
if(JisA(j)){}  
if(JisS(j)){}  
if(JisS(j)){}  
//conditions as if they are booleans. //the boolean-ish condition works because "" equals FALSE within sls.
//conditions as if they are booleans. //the boolean-ish condition works because "" equals FALSE within LSL.
The functions that return a string MAY return a JSON_STRING or JSON_ARRAY can be useful recursively as shown below:
The functions MAY return a JSON_STRING or JSON_ARRAY can be useful recursively as shown below:
*/
*/
JstringPARSED(string j){
    //j="\"PI\"";
    //j="\"3.14\"";
    //j="\"-1\"";
    string JayWeHaveToGoDeeperS = JisS(JisS(j));
    llOwnerSay( JayWeHaveToGoDeeperS ); // says "PI", or ""        , or ""        , because "3.14" is a JSON_NUMBER and "-1" is a JSON_NUMBER but not a JSON_STRING
    string JayWeHaveToGoDeeperN = JisN(JisS(j));
    llOwnerSay( JayWeHaveToGoDeeperN ); // says ""  , or "3.14000" , or "-1.0000",  because "PI" is a JSON_STRING but "PI" is not a JSON_NUMBER


JrecursiveSTRING(string j){
//j="\"PI\"";
    if (llJsonValueType(j,[])==JSON_INVALID){}//would be TRUE for j="";
//j="\"3.14\"";
}
//j="\"-1\"";
string JayWeHaveToGoDeeperS = JisS(JisS(j));
//==== End of JstringPARSED(j) ===== start of Jnested(j) for  nested/recursive lists =====
llOwnerSay( JayWeHaveToGoDeeperS ); // says "PI", or "0" , or "0", because "3.14" is a JSON_FLOAT and "-1" is a JSON_INTEGER.
string JayWeHaveToGoDeeperI = JisI(JisS(j));
Jnested(string j,list rope){//goes trough each value of a nested JSON_ARRAY and says its value and its "position-list"
llOwnerSay( JayWeHaveToGoDeeperI ); // says "0", or "0" , or "-1", because "3.14" is a JSON_FLOAT and "PI" is a JSON_STRING.
string JayWeHaveToGoDeeperF = JisF(JisS(j));
llOwnerSay( JayWeHaveToGoDeeperI ); // says "0", or "3.14" , or "0", because "3.14" is a JSON_FLOAT and "-1" is a JSON_INTEGER.
if (llJsonValueType(j,[])==JSON_INVALID){}//wopuld be TRUE for j="";
 
Jnested(string j){
JisA(JisA(string j){
     //j="[]";
     //j="[]";
     //j="[[1],[2]]";
     //j="[[1],[2]]";
Line 67: Line 63:
     //j="[[-3,-4]]";  //the only true case HERE for = JisA(JisA(j)); below
     //j="[[-3,-4]]";  //the only true case HERE for = JisA(JisA(j)); below
     string JayWeHaveToGoDeeperA = JisA(JisA(j));
     string JayWeHaveToGoDeeperA = JisA(JisA(j));
    llOwnerSay("you stored a whole list nested as only entry of another list, that was dumb:" JayWeHaveToGoDeeperA );
    //just in case your json is poorly formatted to store a whole list within another whole list as its only entry..
 
     string subJ=JisA(j);
     string subJ=JisA(j);
     if (subJ){
     if (subJ){
         //here you actually have to loop trough each entry of the subJ JSON_LIST to test its TYPE for each entry (if we want to go deeper recursively)
         //here you actually have to loop trough each entry of the subJ JSON_LIST to test its TYPE for each entry (if we want to go deeper recursively)
         //You can go deeper once you know if entry number x is a JSON_LIST (NESTED!!!) or JSON_STRING (for some reason)
         //You can go deeper once you know if entry number x is a JSON_LIST (NESTED!!!) or JSON_STRING (for some reason)
         first see how many list entries there are; we go trough entries of subJ starting on the left until its a JSON_INVALID
         //first see how many list entries there are; we go trough entries of subJ starting on the left until its a JSON_INVALID
         list types;  
         list types;  
         integer i;
         integer i = -1;
         while (++i){
         while (++i != -1){
             string type=llJsonValueType(j,[i]);//stores the TYPE of "j"'s entry at position i as "type"
             string type=llJsonValueType(j,[i]);//stores the TYPE of "j"'s entry at position i as "type"
             if (type==JSON_INVALID) i=-1; //this exits this the while-loop
             if (type==JSON_INVALID) i=-2; //this exits this the while-loop
             else i=i+[type]//the list "types" will store all the JSON types, untill the first invalid one is reached. (which which should also be for "out of bounds"
             else types += [type]// the list "types" will store all the JSON types, until the first invalid one is reached. (which which should also be for "out of bounds"
         }
         }
 
         //this is split in 2 loops to explain 1 task by splitting it in 2 smaller tasks. Actually the loops above and below could be merged easily.  
         //this is split in 2 loops to explain 1 task by splitting it in 2 smaller tasks. Actually the loops above and below could be merged easily.  
 
         //we now have a list that lists all json types of j; lets see how long it is;  
         i=llGetListLength(types);//we now have a list that lists all JSON types of j; lets see how long it is;  
         i=llListLength(types);
         //and we loop trough all types, calling THIS function recursively if the list contains another nested list in it at position i
        and we loop trough all types, calling THIS function recursively if the list contains another nested list in it at position i
         while (i--){//I like to go reverse from right to left when ever possible, its faster (??) and costs less memory in LSL (??)
         while (i--){//i like to go reverse from left to right when ever possible, its faster and costs less memory in sls
             if (llList2String(types,i)==JSON_ARRAY || llList2String(types,i)==JSON_OBJECT){
             if llList2String(types,i)==JSON_ARRAY){
                   Jnested(llJsonGetValue(j,[i]));//the function calls itself here, recursively to go trough the nested JSON_ARRAY or JSON_OBJECT
                   nestedlisttest(j,[i]);//the function calls itself here, recursively, but only sends the i#th SUB.list of itself to an instance of itself.
             }
             }
             else{
             else{
                llOwnerSay("["+llList2CSV(rope)+"]== "+llJsonGetValue(j,[i]));
                 //read from your list what json type is at this position and do something with it.
                 //read from your list what json type is at this position and do something with it.
                //maybe you need a global counter that increases each time you go "one nested list deeper" and decreases when you go "one nested list back up"
}}}}
                //otherwise you may not know how deep you are within nested lists.
//Jnested(json,[]);//would print each value of the nexted JSN_ARRAY with its "address list", that is building up recursively as "rope" that leads you trough the tree/maze.
            }
 
        }
//Jnested(j) should be useful to read from large matrices (as in 300x300 fields) that may even contain complex numbers at some places.
    }
//I tried to read very long JSONs with llGetSubString(), but llGetSubString() too easily stack-heap collides on very long strings,
//so you have to go trough the nested list using Jnested(j) to read and print it per entry.


}
</lsl>


</source>
|caveats=
|caveats=
|helpers
|helpers

Latest revision as of 12:02, 5 June 2022

Summary

Function: string llJsonValueType( string json, list specifiers );

Gets the JSON type for the value in json at the location specifiers.
Returns the string specifying the type of the value at specifiers in json.

• string json A string serialization of a json object.
• list specifiers A path to a value in the json parameter.

Specification

Constants

Type Flags Value Unicode Integer URL Encoded HTML Encoded Description
JSON_INVALID U+FDDO 64976 "%EF%B7%90" &#xFDD0; Value returned when inputs are not well formed.
JSON_OBJECT U+FDD1 64977 "%EF%B7%91" &#xFDD1;
JSON_ARRAY U+FDD2 64978 "%EF%B7%92" &#xFDD2;
JSON_NUMBER U+FDD3 64979 "%EF%B7%93" &#xFDD3;
JSON_STRING U+FDD4 64980 "%EF%B7%94" &#xFDD4;
JSON_NULL U+FDD5 64981 "%EF%B7%95" &#xFDD5;
JSON_TRUE U+FDD6 64982 "%EF%B7%96" &#xFDD6;
JSON_FALSE U+FDD7 64983 "%EF%B7%97" &#xFDD7;
JSON_DELETE U+FDD8 64984 "%EF%B7%98" &#xFDD8; Used with llJsonSetValue to remove a key-value pair.

Examples

//all these functions are untested functions that may have some very strange cases were they acd badly or where the comments are wrong
//see them as buggy PSEUDO-code and consider yourself lucky if there are less than 2 wrong counters and 4 bad pointers/names.
//they are more an example and a concept and unlikely fully functional AS IS.
 
string JisN(string j){if(llJsonValueType(j,[])==JSON_NUMBER  )return llJsonGetValue(j,[]);return "";}
//return the JSON if "j" is a JSON_NUMBER, like j="10.1234"  j="-0.1234"  j="3.14159"  j="-1" j="123456"   otherwise return "";
//these would be sting representations of a float because j is a string.
//storing floats in a JSON will easily lose you a lot of accuracy. Integers stored in JSON may have a smaller range than 32-bit signed integers.
 
string JisA(string j){if(llJsonValueType(j,[])==JSON_ARRAY  )return llJsonGetValue(j,[]);return "";}
//return the JSON if "j" is a JSON_ARRAY, like j="[]"   j="[1,2]"  j="[[1],[3,4]]"                        otherwise return "";
//these would be string representations of a (nested) list because j is a string.
 
string JisS(string j){if(llJsonValueType(j,[])==JSON_STRING )return llJsonGetValue(j,[]);return "";}
//return the string that is stored in "j" if "j" is a JSON_STRING, like j="\"PI\""   j="\"3.14\""   j="\"-1\"" otherwise return "";
//these would be string representations of a string, typecast with \" as that within itself,
//because j is a string that is also able to store numbers and floats and (nested) lists ... as strings. 
//this returns the string within "j" if "j" is "A string within a string". 
 
/*the above functions return strings to be used in simple 
if(JisN(j)){} 
if(JisA(j)){} 
if(JisS(j)){} 
//conditions as if they are booleans. //the boolean-ish condition works because "" equals FALSE within LSL.
The functions MAY return a JSON_STRING or JSON_ARRAY can be useful recursively as shown below:
*/
 
JstringPARSED(string j){
    //j="\"PI\"";
    //j="\"3.14\"";
    //j="\"-1\"";
    string JayWeHaveToGoDeeperS = JisS(JisS(j));
    llOwnerSay( JayWeHaveToGoDeeperS ); // says "PI", or ""        , or ""         , because "3.14" is a JSON_NUMBER and "-1" is a JSON_NUMBER but not a JSON_STRING
    string JayWeHaveToGoDeeperN = JisN(JisS(j));
    llOwnerSay( JayWeHaveToGoDeeperN ); // says ""  , or "3.14000" , or "-1.0000",   because "PI" is a JSON_STRING but "PI" is not a JSON_NUMBER 

 
    if (llJsonValueType(j,[])==JSON_INVALID){}//would be TRUE for j="";
}
 
//==== End of JstringPARSED(j) ===== start of Jnested(j) for  nested/recursive lists =====
 
Jnested(string j,list rope){//goes trough each value of a nested JSON_ARRAY and says its value and its "position-list"
    //j="[]";
    //j="[[1],[2]]";
    //j="[-1,[2]]";
    //j="[[1],-2]";
    //j="[[-3,-4]]";  //the only true case HERE for = JisA(JisA(j)); below
    string JayWeHaveToGoDeeperA = JisA(JisA(j));
 
    string subJ=JisA(j);
    if (subJ){
        //here you actually have to loop trough each entry of the subJ JSON_LIST to test its TYPE for each entry (if we want to go deeper recursively)
        //You can go deeper once you know if entry number x is a JSON_LIST (NESTED!!!) or JSON_STRING (for some reason)
        //first see how many list entries there are; we go trough entries of subJ starting on the left until its a JSON_INVALID
        list types; 
        integer i = -1;
        while (++i != -1){
             string type=llJsonValueType(j,[i]);//stores the TYPE of "j"'s entry at position i as "type"
             if (type==JSON_INVALID) i=-2; //this exits this the while-loop
             else types += [type];  // the list "types" will store all the JSON types, until the first invalid one is reached. (which which should also be for "out of bounds"
        }
 
        //this is split in 2 loops to explain 1 task by splitting it in 2 smaller tasks. Actually the loops above and below could be merged easily. 
 
        i=llGetListLength(types);//we now have a list that lists all JSON types of j; lets see how long it is; 
        //and we loop trough all types, calling THIS function recursively if the list contains another nested list in it at position i
        while (i--){//I like to go reverse from right to left when ever possible, its faster (??) and costs less memory in LSL (??)
             if (llList2String(types,i)==JSON_ARRAY || llList2String(types,i)==JSON_OBJECT){
                  Jnested(llJsonGetValue(j,[i]));//the function calls itself here, recursively to go trough the nested JSON_ARRAY or JSON_OBJECT
            }
            else{
                llOwnerSay("["+llList2CSV(rope)+"]== "+llJsonGetValue(j,[i]));
                //read from your list what json type is at this position and do something with it.
}}}}
//Jnested(json,[]);//would print each value of the nexted JSN_ARRAY with its "address list", that is building up recursively as "rope" that leads you trough the tree/maze.

//Jnested(j) should be useful to read from large matrices (as in 300x300 fields) that may even contain complex numbers at some places.
//I tried to read very long JSONs with llGetSubString(), but llGetSubString() too easily stack-heap collides on very long strings,
//so you have to go trough the nested list using Jnested(j) to read and print it per entry.

See Also

Functions

•  llList2Json
•  llJson2List
•  llJsonSetValue
•  llJsonGetValue

Articles

•  Typecast

Deep Notes

History

Date of Release 20/05/2013

Signature

function string llJsonValueType( string json, list specifiers );