Working with the Lua JSON Example

This document focuses on how data in the JSON format is parsed into objects in the I/O Model. Parsing XML data is covered in Working with the Lua HTTP Example.

An open source parsing function can also be used to process JSON outputs.

Automatic JSON Example Setup

You can then have the JSON example automatically set up by running the following Lua script (which employs the esi-examples library) in the Console Display.

local exm = require('esi-examples')
exm:SETUP({{"json"}})
I/O Model Tree after JSON example MassConfig
Figure 1. I/O Model Tree after JSON example MassConfig

A Folder, JSON, containing an ActionItem, JSON Processor, is created in the LUA folder. The ActionItem JSON Processor executes a script which defines a JSON object which is then parsed by the JSON parser and uses the information in the JSON object to create objects in the Data Folder.

The JSON Processor Script

Open the JSON Processor script from the Object Properties panel:

local json = require 'dkjson'

local str = [[
{
	"currency": "\u20AC",
	"numbers": [ 2, 3, -20.23e+2, -4 ],
	"animals": ["dog","cat","aardvark"],
	"address": {
		"streetAddress": "21 2nd Street",
		"city": "New York",
		"state": "NY"
	}
}
]]

In the above section of the JSON Processor script the dkjson script library is called (this library is embedded in the system) and the JSON _str string is defined. The JSON values "numbers" and "animals" are set as arrays whereas the "address" value is set as another JSON object.

local obj, pos, err = json.decode (str)
if err then
	return "Error: " .. err
else
	local folder = get_object(syslib.getself():parent():path(), "Data", "MODEL_CLASS_GENFOLDER")

	local currency = get_object(folder:path(), "currency", "MODEL_CLASS_HOLDERITEM")
	syslib.setvalue(currency:path(), obj.currency)

	local numbers = get_object(folder:path(), "numbers", "MODEL_CLASS_HOLDERITEM")
	syslib.setvalue(numbers:path(), obj.numbers) -- set the entire array as a value

	local animals = get_object(folder:path(), "animals", "MODEL_CLASS_GENFOLDER")
	-- iterate the array and create an object for each value
	for i = 1, #obj.animals do
		get_object(animals:path(), obj.animals[i], "MODEL_CLASS_HOLDERITEM")
	end

	local address = get_object(folder:path(), "address", "MODEL_CLASS_GENFOLDER")
	local street = get_object(address:path(), "street", "MODEL_CLASS_HOLDERITEM")
	-- obj.address is itself a )SON object so we get its fields through the dot syntax
	syslib.setvalue(street:path(), obj.address.streetAddress)
	local city = get_object(address:path(), "city", "MODEL_CLASS_HOLDERITEM")
	syslib.setvalue(city:path(), obj.address.city)
	local state = get_object(address:path(), "state", "MODEL_CLASS_HOLDERITEM")
	syslib.setvalue(state:path(), obj.address.state)

	return "OK"
...

In the above section of code the str JSON string is processed using the decode function from the dkjson library.

The get_object function (defined at the beginning of the script) returns an object or creates it if it doesn’t already exist. The objects are created in the I/O tree, then values are set to them using the syslib.setvalue function.

The arrays for "numbers" and "animals" are handled differently. The entire "numbers" array is set as the value of the "numbers" data holder. The "animals" array on the other hand, is iterated with a for loop to create data holder items for each entry in the array (no values are set to the items in this script though).

"address" is a JSON object so it’s fields are accessed using the dot syntax when setting the values with syslib.setvalue.

For example, the extract shown below:

syslib.setvalue(street:path, obj.address.streetAddress)