How to Work with JSON Data Using Nelson's json Module: A Complete Guide

Use Nelson's built-in json module with jsonencode() to serialize variables, jsondecode() to parse JSON strings or files, and jsonprettyprint() to format output for readability.

Nelson ships with a dedicated json module that provides MATLAB-compatible JSON handling through three high-level built-in functions. Whether you need to serialize complex data structures, parse configuration files, or debug API responses, the module offers native C++ performance with a simple, familiar syntax.

Core Functions in Nelson's json Module

The json module exposes three primary functions for working with JSON data:

  • jsonencode – Converts any Nelson variable (numeric arrays, cells, structs, strings) into a JSON text string.
  • jsondecode – Parses a JSON text string or file back into a Nelson variable.
  • jsonprettyprint – Produces a human-readable, indented version of JSON text for debugging or logging.

How to Encode Nelson Variables to JSON

The jsonencode function serializes Nelson data types into compact JSON strings. By default, it handles numeric arrays, structures, cell arrays, and strings.

Basic Encoding

% Create a structure with mixed data types
person = struct('name', 'Nelson', 'age', 42, 'active', true, 'tags', {'interpreter', 'open-source'});

% Encode to JSON
jsonStr = jsonencode(person);
disp(jsonStr);
% Output: {"name":"Nelson","age":42,"active":true,"tags":["interpreter","open-source"]}

Handling Inf and NaN Values

Use the 'ConvertInfAndNaN' name-value pair to control how special floating-point values are serialized. When set to true (default), Inf becomes "Inf", -Inf becomes "-Inf", and NaN becomes null.

data = [1, NaN, Inf, -Inf];

% Default behavior
jsonTxt = jsonencode(data, 'ConvertInfAndNaN', true);
% Result: [1,null,"Inf","-Inf"]

% Disable conversion (if supported by underlying implementation)
% Note: Check specific Nelson version behavior for numeric encoding without conversion

The implementation of this logic resides in modules/json/builtin/cpp/jsonencodeBuiltin.cpp, where the C++ code inspects array types and applies the conversion rules before building the final UTF-8 JSON string using the internal nlohmann/json library.

How to Decode JSON Strings and Files

The jsondecode function parses JSON text into Nelson variables. It automatically detects data types and converts JSON objects to structures and JSON arrays to cell arrays or numeric arrays.

Parsing JSON Strings

jsonStr = '{"id": 101, "name": "Test", "values": [1, 2, 3]}';
result = jsondecode(jsonStr);

% Access fields like a standard structure
disp(result.name);    % "Test"
disp(result.values);  % [1, 2, 3]

Reading JSON from Files

Pass the '-file' flag as the second argument to read JSON directly from disk. This mode is implemented by reading the file content internally before parsing.

% Decode JSON from a file
config = jsondecode('settings.json', '-file');

% Verify structure
disp(config);

This file-handling logic is utilized in internal Nelson functions such as modules/webtools/functions/checkupdate.m, which uses jsondecode(..., '-file') to parse API responses stored on disk.

Pretty-Printing JSON Output

Use jsonprettyprint to generate indented, human-readable JSON for debugging or configuration file generation.

compact = '{"a":1,"b":[1,2,3]}';
readable = jsonprettyprint(compact);
disp(readable);
% Output:
% {
%     "a": 1,
%     "b": [
%         1,
%         2,
%         3
%     ]
% }

Module Architecture and Implementation

Understanding the internal structure helps when debugging or extending functionality.

Module Registration

When Nelson starts, modules/json/loader.m executes via addmodule to register the json module:

% modules/json/loader.m
addmodule([nelsonroot() '/modules/' 'json'], 'json');

Builtin Gateway

The loader adds a gateway mapping function names to C++ implementations in modules/json/builtin/cpp/Gateway.cpp:

{ "jsonencode", (ptrBuiltin)Nelson::JsonGateway::jsonencodeBuiltin, 1, -1 },
{ "jsondecode", (ptrBuiltin)Nelson::JsonGateway::jsondecodeBuiltin, 1, -1 },
{ "jsonprettyprint", (ptrBuiltin)Nelson::JsonGateway::jsonprettyprintBuiltin, 1, -1 },

C++ Implementation

Each builtin resides in its own .cpp file. For example, modules/json/builtin/cpp/jsonencodeBuiltin.cpp receives ArrayOfVector arguments, walks the data structure, and builds UTF-8 JSON strings using the nlohmann/json library.

Complete Code Examples

Example 1: Struct to JSON Round-Trip

% Create a struct with mixed types
s = struct('id', 101, ...
           'name', 'Nelson', ...
           'active', true, ...
           'metrics', [1.2, NaN, Inf]);

% Encode to JSON
jsonTxt = jsonencode(s);
disp(jsonTxt);
% {"id":101,"name":"Nelson","active":true,"metrics":[1.2,null,"Inf"]}

% Decode back
s2 = jsondecode(jsonTxt);
assert_isequal(s, s2);  % Verify round-trip integrity

Example 2: Pretty-Print a JSON File

% Read raw JSON from disk
raw = fileread('config.json');

% Format with indentation
pretty = jsonprettyprint(raw);

% Write formatted version
filewrite('config_pretty.json', pretty);

Example 3: Handling Special Float Values

vec = [1, NaN, Inf, -Inf];

% Default conversion
jsonTxt = jsonencode(vec, 'ConvertInfAndNaN', true);
% Result: [1,null,"Inf","-Inf"]

disp(jsonTxt);

Example 4: Decoding JSON from a File

% Create sample file
data = struct('a', 1, 'b', [2, 3]);
filewrite('sample.json', jsonencode(data));

% Decode directly from file
obj = jsondecode('sample.json', '-file');
disp(obj.a);  % 1
disp(obj.b);  % [2, 3]

Key Source Files

File Role
modules/json/loader.m Registers the json module at startup via addmodule.
modules/json/builtin/cpp/Gateway.cpp Maps jsonencode, jsondecode, and jsonprettyprint to C++ builtins.
modules/json/builtin/cpp/jsonencodeBuiltin.cpp Core encoding logic, handles ConvertInfAndNaN option.
modules/json/builtin/cpp/jsondecodeBuiltin.cpp Parsing logic, supports string and file (-file) modes.
modules/json/builtin/cpp/jsonprettyprintBuiltin.cpp Indentation and formatting implementation.
modules/json/tests/test_jsonencode.m Unit tests for encoding scalars, arrays, structs, and special values.
modules/json/tests/test_jsondecode.m Tests for parsing strings and file mode.
modules/json/tests/test_jsonprettyprint.m Validation of pretty-printing output.

Summary

  • Use jsonencode to convert Nelson variables (structs, cells, arrays) into JSON text strings, with optional 'ConvertInfAndNaN' control for special floating-point values.
  • Use jsondecode to parse JSON strings back into Nelson data structures; add the '-file' argument to read directly from disk.
  • Use jsonprettyprint to generate indented, human-readable JSON for debugging or configuration management.
  • The module is automatically loaded at startup via modules/json/loader.m, with C++ implementations in modules/json/builtin/cpp/ providing high-performance encoding and decoding via the nlohmann/json library.

Frequently Asked Questions

How do I handle NaN and Inf values when encoding JSON in Nelson?

By default, jsonencode converts NaN to null, Inf to "Inf", and -Inf to "-Inf" in the JSON output. You can control this behavior explicitly using the 'ConvertInfAndNaN' parameter set to true or false. This logic is implemented in modules/json/builtin/cpp/jsonencodeBuiltin.cpp.

Can I parse JSON directly from a file instead of a string?

Yes. Pass the '-file' flag as the second argument to jsondecode. For example: data = jsondecode('config.json', '-file'). This instructs the builtin to read the file content before parsing, as demonstrated in modules/webtools/functions/checkupdate.m.

What data types can I encode using jsonencode?

jsonencode handles all standard Nelson types including numeric arrays (double, single, integers), complex numbers, character arrays, strings, logical values, structures, and cell arrays. The C++ implementation in jsonencodeBuiltin.cpp walks these data structures recursively to build the JSON representation.

Is the json module automatically available, or do I need to load it manually?

The json module is automatically loaded when Nelson starts via modules/json/loader.m, which registers the module using addmodule. However, if you need to reload it manually, you can call addgateway(modulepath('json', 'builtin'), 'json').

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →