Json usage in LSL

From Second Life Wiki
Revision as of 01:31, 13 June 2013 by Gistya Eusebio (Talk | contribs)

Jump to: navigation, search

Type Conversions

Json has native representation for:

  • numbers - directly mappable to LSL Integer and Float (json numbers without a decimal point are assumed to be Integers, those with a decimal point are Floats)
  • strings - identical to LSL String
  • arrays - a list of values of any type: directly analogous to an LSL List
  • objects - represented in LSL as a strided list of name/value pairs (see below re: values)
  • the constants 'true' and 'false' - directly mapped to and from the LSL constants JSON_TRUE and JSON_FALSE
  • the constant 'null' - directly mapped to and from the LSL constant JSON_NULL
  • All other LSL types (Key, Rotation, and Vector) are implicitly converted to their string representation when converting to Json; when converting from Json to LSL, these values are returned as String values, so the script must explicitly convert using the existing conversion methods.

New LSL Methods

Specifying Json Elements

llJsonGetValue, llJsonValueType and llJsonSetValue take a Json value in an LSL string, and an LSL list of specifiers. The specifiers are a list consisting only of strings (or keys) and integers, which define a path to the desired value in a Json compound object.

  • An empty list specifies the entire Json value.
  • If the list is not empty, each element of the list is used to select the element at the same level of nesting in the Json value:
    • if the specifier list element is a string, then the corresponding element in the json value must be an object and the list element selects the value whose Json name exactly matches the string.
    • if the specifier list element is an integer, then the corresponding element in the json value must be an array and the list element is used as a zero-based index into the Json array.
  • Additionally llJsonSetValue accepts JSON_APPEND as a specifier to indicate appending the value to the end of the array at that level.

For example, given the json value: <javascript> {

   alpha: 1,
   beta: [
   gamma: {
      "a": 3.2,
      "b": true

} </javascript> the contents of the string returned would be: <lsl> llJsonGetValue ( value, [ "alpha" ] ) ⇒ 1 llJsonGetValue ( value, [ "beta" ] ) ⇒ [ "x", "y", "z" ] llJsonGetValue ( value, [ "beta", 2 ] ) ⇒ z llJsonGetValue ( value, [ "gamma", "a" ] ) ⇒ 3.2 </lsl>

For llJsonGetValue and llJsonValueType If the specifiers do not specify a valid path in the given json value, the constant JSON_INVALID is returned, unless the specifiers reduce the JSON string to nothing (not even brackets), in which case JSON_NULL is returned. For instance for: {"foo": {"bar":, "foo": {"bar":"foo"} } } the JSON type of specifier ["foo","bar"] is JSON_NULL as is ["foo","bar","anything","else"]. Meanwhile the JSON type of ["foo","foo","anything other than bar"] is JSON_INVALID. Also ["bar","anything"] etc.

llJsonSetValue will force the resulting json to conform with the specifiers supplied.

Json Interrogation and Validation

To determine the type of a json value:

<lsl>string type = llJsonValueType( string json, list specifiers );</lsl>

returns one of several following special constants (see table below). Each constant has a name, JSON_XXXX, which unlike most LSL constants is not an integer—instead, it's a single-character string. The single character is not printable but has a specific escape value (if run through llEscapeURL) in the range of  %EF%B7%90–97. The below table shows each constant's invocation and escape code:
Contant Escape value

Json to LSL Conversion

To directly extract a Json value to an LSL string:

string value = llJsonGetValue( string json, list specifiers );
  • json is a string containing a valid json array or object value
  • specifiers is a list of specifiers (see Specifying Json Elements)
  • returns a json string
  • if the specifiers do not indicate a value that exists in the input, JSON_INVALID is returned

To convert a json compound value (either an array or an object) to an LSL List:

list values = llJson2List( string json );
  • json is a string containing a valid json array or object value
  • If the string in json is not a valid json object or array a list with a single item matching the conversion above is returned.

Recursive Parsing

Since any value in a Json array or object may be any arbitrary type, including an array or object, the parsing methods must handle nested values. Nested arrays or objects are not converted, but remain LSL String values. If an LSL script needs to use the components in such a nested value, it must explicitly pass that string to the appropriate method. For example, the following json value is passed to llJson2List: <javascript> {

   alpha: 1,
   beta: [
   gamma: {
      a: 3.2,
      b: true

} </javascript> The result would be an LSL list with a stride of 2: the first elements of the 3 strides would be "alpha", "beta", and "gamma". The second element of the first stride would be the integer 1, but the second elements of the other two strides would be LSL strings containing the json representation of the array '[ "x", "y", "z" ]' and object '{ a: 3.2, b: true }' respectively.

LSL to Json

To convert a list to json:

string json = llList2Json( string type, list values );
Produces an LSL String containing a Json compound value, either an array or an object depending on type, containing the values in the input list.
If type is JSON_ARRAY, the list may contain values of any LSL type; they are converted as described in Type Conversions above.
If type is JSON_OBJECT, the list must have a stride of 2. The first value of each stride must be a string. The second value of each stride may be any LSL type, and are converted as described in Type Conversions above. [[JSON_INVALID] is returned if the stride is not 2.
JSON_INVALID is returned if any other string or json type is specified as the type.

To directly set a Json value within a string:

string jsonresult = llJsonSetValue( string json, list specifiers, string value );
  • json is a string containing a valid json array or object value
  • specifiers is a list of specifiers (see #Specifying Json Elements)
  • value the value to be inserted into the specified place in json
  • Returns the newly modified json string
The only failure mode for llJsonSetValue is if an array index is specified in specifiers that is negative (but not JSON_APPEND) or more greater than the list size. In all other cases the json is modified so that the set can succeed. For example if an integer is specified for a level that is an object, the object will be removed completely and replaced with an array. If the object key does not exist it will be added, and JSON_APPEND or an index one larger than the last item in an array can be used to append to an array. These features are to allow building a Json string with llJsonSetValue.

Recursive Construction of Compound Json Values

Since LSL does not support nested lists, the construction method may only be used to convert a single level; to create a Json array or object whose values are nested arrays or objects, the LSL script must first construct the nested values and then pass those values as strings to another construction method call. For example, to construct the Json value: <javascript> {

   alpha: 1,
   beta: [
   gamma: {
      a: 3.2,
      b: true

} </javascript> The following sequence could be used:

string gamma_value = llList2Json( JSON_OBJECT, [ "a", 3.2, "b", TRUE ] );
string beta_value  = llList2Json( JSON_ARRAY, [ "x", "y", "z" ] );
string value       = llList2Json( JSON_OBJECT,[ "alpha", 1, "beta", beta_value, "gamma", gamma_value ] );

or the equivalent without the intermediate variables: <lsl> string value =

   llList2Json( JSON_OBJECT,
       ["alpha", 1,
        "beta", llList2Json( JSON_ARRAY, [ "x", "y", "z" ] ),
        "gamma", llList2Json( JSON_OBJECT, [ "a", 3.2, "b", TRUE ] )]