{"id":18849603,"url":"https://github.com/gaurav-gosain/jsml","last_synced_at":"2026-04-29T20:08:52.673Z","repository":{"id":218010690,"uuid":"745364846","full_name":"Gaurav-Gosain/jsml","owner":"Gaurav-Gosain","description":"JSML - JSON Manipulation Library | JSML is a lightweight C library for parsing and manipulating JSON data.","archived":false,"fork":false,"pushed_at":"2024-01-19T11:02:35.000Z","size":15,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-30T14:52:30.887Z","etag":null,"topics":["c","json","parser"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Gaurav-Gosain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-19T07:12:38.000Z","updated_at":"2024-03-08T15:13:00.000Z","dependencies_parsed_at":"2024-01-19T09:25:45.835Z","dependency_job_id":"aa13b9dc-4563-4707-8c84-9befd1718240","html_url":"https://github.com/Gaurav-Gosain/jsml","commit_stats":null,"previous_names":["gaurav-gosain/jsml"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gaurav-Gosain%2Fjsml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gaurav-Gosain%2Fjsml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gaurav-Gosain%2Fjsml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gaurav-Gosain%2Fjsml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Gaurav-Gosain","download_url":"https://codeload.github.com/Gaurav-Gosain/jsml/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239786253,"owners_count":19696772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","json","parser"],"created_at":"2024-11-08T03:21:16.681Z","updated_at":"2026-02-02T22:30:17.240Z","avatar_url":"https://github.com/Gaurav-Gosain.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSML - JSON Manipulation Library\n\nJSML is a lightweight C library for parsing and manipulating JSON data.\n\n## Features\n- Parse JSON data from a string or a file.\n- Access JSON values by key or index.\n- Helper functions for accessing nested JSON values and printing JSON data (along with datatypes).\n- Free up memory used by JSON data.\n\n## Usage\n\nAll you need to do is include the jsml.h header file in your project.\n\n```c\n#include \"jsml.h\"\n```\n\n### Parsing JSON\n\n#### Parse from String (char *)\n\n\u003e Note: The unescape_json_string_literal function is only needed if you are parsing a JSON string that is hardcoded and escaped. If you are parsing a JSON string, you can skip this step.\n\n```C\nchar* json_string = \"{\\\"key\\\": \\\"value\\\"}\";\nconst json* parsed_json = json_parse_utf8(unescape_json_string_literal(json_string));\nif (parsed_json) {\n  json_print(parsed_json, 0);\n}\njson_free(parsed_json);\n```\n\n#### Parse from File\n\n```C\nconst json* parsed_json_file = json_parse_file_utf8(\"example.json\");\nif (parsed_json_file) {\n  json_print(parsed_json_file, 0);\n}\njson_free(parsed_json_file);\n```\n## Accessing JSON Values\nYou can access JSON values by key or index using the json_get and json_item functions. Here is an example:\n\n\u003e For this example, we will use the following JSON data:\n```JSON\n{\n  \"int\": 195,\n  \"array\": [3, 5.1, -7, \"nine\"],\n  \"bool\": true,\n  \"double\": -1e-4,\n  \"null-value\": null,\n  \"hello\": \"world!\",\n  \"obj\": {\n    \"key\": \"val\",\n    \"double\": 1e4\n  },\n  \"nested\": [\n    {\n      \"a\": \"b\"\n    },\n    {\n      \"a\": 69\n    },\n    {\n      \"a\": [4, 2, 0]\n    }\n  ]\n}\n```\n\n\u003e NOTE: Please assert that the value returned by json_get or json_item is not NULL before accessing the value. For the sake of brevity, we have omitted the assertions in the following examples.\n\n```C\nconst json* parsed_json = json_parse_file_utf8(\"example.json\");\n\n/* Access values */\nconst json *int_node = json_get(parsed_json, \"int\");\nassert(int_node-\u003etype == JSON_INTEGER);\nprintf(\"int: %lld\\n\", int_node-\u003ejson_integer);\n\nprintf(\"bool: %s\\n\",\n        json_get(parsed_json, \"bool\")-\u003ejson_bool ? \"true\" : \"false\");\nprintf(\"double: %f\\n\", json_get(parsed_json, \"double\")-\u003ejson_double);\nprintf(\"some-null: %s\\n\",\n        json_get(parsed_json, \"null-value\")-\u003etype == JSON_NULL ? \"null\"\n                                                              : \"not null\");\nprintf(\"hello: %s\\n\", json_get(parsed_json, \"hello\")-\u003ejson_string);\nprintf(\"obj.key: %s\\n\",\n        json_get(json_get(parsed_json, \"obj\"), \"key\")-\u003ejson_string);\nprintf(\"obj.double: %f\\n\\n\",\n        json_get(json_get(parsed_json, \"obj\"), \"double\")-\u003ejson_double);\n\n/* Nested */\nprintf(\"nested[0].a: %s\\n\",\n        json_get(json_item(json_get(parsed_json, \"nested\"), 0), \"a\")\n            -\u003ejson_string);\nprintf(\"nested[1].a: %lld\\n\",\n        json_get(json_item(json_get(parsed_json, \"nested\"), 1), \"a\")\n            -\u003ejson_integer);\nprintf(\"nested[2].a[0]: %lld\\n\",\n        json_item(\n            json_get(json_item(json_get(parsed_json, \"nested\"), 2), \"a\"), 0)\n            -\u003ejson_integer);\nprintf(\"nested[2].a[1]: %lld\\n\",\n        json_item(\n            json_get(json_item(json_get(parsed_json, \"nested\"), 2), \"a\"), 1)\n            -\u003ejson_integer);\nprintf(\"nested[2].a[2]: %lld\\n\\n\",\n        json_item(\n            json_get(json_item(json_get(parsed_json, \"nested\"), 2), \"a\"), 2)\n            -\u003ejson_integer);\n\n/* Nested helper */\nprintf(\"(Helper) obj.key: %s\\n\",\n        json_get_nested(parsed_json, \"obj.key\")-\u003ejson_string);\nprintf(\"(Helper) obj.double: %f\\n\",\n        json_get_nested(parsed_json, \"obj.double\")-\u003ejson_double);\n\nprintf(\"--------------------\\n\\n\");\n\njson_free(parsed_json_file);\n```\n\nOutput\n\n```output\nint: 195\nbool: true\ndouble: -0.000100\nsome-null: null\nhello: world!\nobj.key: val\nobj.double: 10000.000000\n\nnested[0].a: b\nnested[1].a: 69\nnested[2].a[0]: 4\nnested[2].a[1]: 2\nnested[2].a[2]: 0\n\n(Helper) obj.key: val\n(Helper) obj.double: 10000.000000\n--------------------\n```\n\nArray Example\n\n```c\n// access array\nconst json *array = json_get(parsed_json, \"array\");\nassert(array-\u003etype == JSON_ARRAY);\n\n// access array elements\nfor (size_t i = 0; i \u003c array-\u003elength; i++) {\n  const json *element = json_item(array, i);\n  switch (element-\u003etype) {\n  case JSON_INTEGER:\n    printf(\"array[%zu]: %lld (int)\\n\", i, element-\u003ejson_integer);\n    break;\n  case JSON_DOUBLE:\n    printf(\"array[%zu]: %f (double)\\n\", i, element-\u003ejson_double);\n    break;\n  case JSON_STRING:\n    printf(\"array[%zu]: %s (string)\\n\", i, element-\u003ejson_string);\n    break;\n  case JSON_BOOL:\n    printf(\"array[%zu]: %s (bool)\\n\", i,\n            element-\u003ejson_bool ? \"true\" : \"false\");\n    break;\n  case JSON_NULL:\n    printf(\"array[%zu]: null (NULL)\\n\", i);\n    break;\n  default:\n    break;\n  }\n}\n```\n\nOutput\n\n```output\narray[0]: 3 (int)\narray[1]: 5.100000 (double)\narray[2]: -7 (int)\narray[3]: nine (string)\n```\n\n## Printing JSON\nYou can print JSON data using the json_print function. Here is an example:\n\n```c\nif (parsed_json) {\n  json_print(parsed_json);\n}\n```\nOutput\n\n```output\n┼── int: 195 (int)\n┼── array: ARRAY\n┼──┼── 3 (int)\n┼──┼── 5.100000 (double)\n┼──┼── -7 (int)\n┼──┼── nine (string)\n┼── bool: true (bool)\n┼── double: -0.000100 (double)\n┼── null-value: NULL\n┼── hello: world! (string)\n┼── obj: OBJECT\n┼──┼── key: val (string)\n┼──┼── double: 10000.000000 (double)\n┼── nested: ARRAY\n┼──┼── OBJECT\n┼──┼──┼── a: b (string)\n┼──┼── OBJECT\n┼──┼──┼── a: 69 (int)\n┼──┼── OBJECT\n┼──┼──┼── a: ARRAY\n┼──┼──┼──┼── 4 (int)\n┼──┼──┼──┼── 2 (int)\n┼──┼──┼──┼── 0 (int)\n```\n\n## Freeing JSON Data\nYou can free up memory used by JSON data using the json_free function. Here is an example:\n\n```c\n/* PLEASE FREE TO AVOID MEMORY LEAKS */\njson_free(parsed_json_file);\njson_free(parsed_json);\n```\n\n## API Reference\nFor more details, please refer to the jsml.h header file.\n\n```h\ntypedef enum json_type {\n  JSON_NULL,\n  JSON_OBJECT,\n  JSON_ARRAY,\n  JSON_STRING,\n  JSON_INTEGER,\n  JSON_DOUBLE,\n  JSON_BOOL\n} json_type;\n\ntypedef struct json {\n  json_type type;          // type of json node, based on json_type enum\n  const char *key;         // key of the property; applicable only for OBJECT\n  const char *json_string; // value of STRING node\n  long long json_integer;  // value of INTEGER node\n  int json_bool;           // value of BOOL node\n  double json_double;      // value of DOUBLE node\n  int length;              // number of children of OBJECT or ARRAY\n  struct json *child;      // points to first child\n  struct json *next;       // points to next child\n  struct json *last_child;\n} json;\n\ntypedef int (*json_unicode_encoder)(unsigned int codepoint, char *p,\n                                    char **endp);\n\n/* String Parse Functions */\nconst json *json_parse(char *text, json_unicode_encoder encoder);\nconst json *json_parse_file(char *file_path, json_unicode_encoder encoder);\n\n/* File Parse Functions */\nconst json *json_parse_utf8(char *text);\nconst json *json_parse_file_utf8(char *file_path);\n\n/* JSON Access Functions */\nconst json *json_get(const json *json,\n                     const char *key); // get object's property by key\nconst json *json_item(const json *json, int idx); // get array element by index\nconst json *json_get_nested(const json *parsed_json,\n                            const char *key); // get nested object/array\n\n/* Extra Helper Functions */\nchar *unescape_json_string_literal(const char *str);\nvoid json_print(const json *parsed_json);\nvoid json_recursive_print(const json *parsed_json, int depth);\nvoid json_free(const json *js);\n```\n\n## Examples\nYou can find examples of how to use this library in the examples directory.\n\n- [example.c](examples/example.c) - Example of parsing JSON from a string literal and a file.\n  - Usage: \n  ```sh\n  gcc -o example examples/example.c; ./example\n  ```\n- [api_example.c](examples/api_example.c) - Example of using the API functions.\n  - Usage: \n  ```sh\n  gcc -o api_example examples/api_example.c -lcurl; ./api_example\n  ```\n\n## License\nThis project is licensed under the MIT License. See the LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgaurav-gosain%2Fjsml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgaurav-gosain%2Fjsml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgaurav-gosain%2Fjsml/lists"}