Skip to content

outscale/csonpath

csonpath

that's not my path, that's not your path, but csonpath

Project Sandbox

csonpath is a partial JSONPath implementation in C, with Python bindings. It allows you to query, update, and remove data from JSON objects using path expressions.

🌐 Links

πŸ“„ Table of Contents

πŸš€ Features

jsonpath

  • support simple path like ex: "$.a[3]["oui"]
  • support ..: "$..non
  • support [*]: "$.array[*].obj[*].field"
  • support filters:
    • with > or <: "$.obj[?field > 123]"
    • with = or '!=': "$.obj[?field != "123"]"
    • with regex, using POSIX regcom: "$.obj[?.field ~= "123"]"
    • with &: "$.obj[?field != "123" & second = 1]"
  • support |: "$.obj | $.otherobj"

Functions

  • Find First: Retrieve the first value matching a path.
  • Find All: Retrieve all values matching a path.
  • Update or Create: Update values or create new ones according to the path.
  • Remove: Remove values matching a path.
  • Update or Create Callback: Update values or create new ones according to the path, using a user-define callback.
  • Callback: Call a callback according to the path.
  • Supports both C (using json-c) and Python objects.

βœ… Getting Started

Prerequisites

  • C compiler (gcc/clang)
  • json-c library for C usage
  • Python 3.x (for Python bindings)

Build

To build the C tests and examples:

make

Usage (json-c)

See examples in tests/json-c/get-a.c:

#include "csonpath_json-c.h"

const char *json_str = "{ \"a\": \"value\", \"array\": [1,2,3] }";
struct csonpath p;
struct json_object *jobj = json_tokener_parse(json_str);
struct json_object *ret;

csonpath_init(&p, "$.a");
ret = csonpath_find_first(&p, jobj);
// ret now points to "value"

Avaible functions:

int csonpath_init(struct csonpath cjp[static 1], const char path[static 1])

init a csonpath struct

int csonpath_set_path(struct csonpath cjp[static 1], const char path[static 1])

change the path of a struct

int csonpath_compile(struct csonpath cjp[static 1])

compile the path, doesn't need to be called before using it, but can be useful to catch error earlyer.

void csonpath_print_instruction(struct csonpath cjp[static 1])

print all instructions once compiled

struct json_object *csonpath_find_first(struct csonpath cjp[static 1], struct json_object *json);

Retrieve the first value matching a path

struct json_object *csonpath_find_all(struct csonpath cjp[static 1], struct json_object *json);

Retrieve all values matching a path, return need to be free using json_object_put

struct json_object *csonpath_remove(struct csonpath cjp[static 1], struct json_object *json);

Remove all matching elements from json

struct json_object *csonpath_update_or_create(struct csonpath cjp[static 1], struct json_object *json, struct json_object *new_val)

update and push new_val, in json.

struct json_object *csonpath_callback(struct csonpath cjp[static 1], struct json_object *json, json_c_callback callback, void *userdata)

call callback on each value matching path

struct json_object *csonpath_update_or_create_callback(struct csonpath cjp[static 1], struct json_object *json, json_c_callback callback, void *userdata)

like callback, but update json base on the path, along the way.

Usage (Python)

Example

import csonpath

d = { "a": "value", "array": [1,2,3] }
o = csonpath.CsonPath("$.a")
print(o.find_first(d))  # Output: "value"

Avaible methodes:

  • CsonPath(path): create a new csonpath object.
  • OBJ.find_first(self, json): take a json, return first found occurrence.
  • OBJ.find_all(self, json): take a json, return all found occurrence in a list.
  • OBJ.remove(self, json): take a json, remove all found occurrence from it.
  • OBJ.update_or_create(self, json, value): take a json, replace all found occurrence from it, by the value, if doesn't found something, create it.
  • OBJ.update_or_create_callback(self, json, callback, callback_data): take a json, if it doesn't find a parent object, create it, then it calls a callback.
  • OBJ.callback(self, json, callback, callback_data): take a json, call a callback, an all occurrence.

callback is a function that take 4 arguments: parent, idx, cur_value and callback_data

Check tests for more examples

Backends and Direct Usage

csonpath is inspired by JSONPath, but is designed to be backend-agnostic: it can work with any C library or environment that manipulates array, object, and scalar typesβ€”not just JSON. Out of the box, backends for Python and json-c are provided, but you can create your own backend for other formats such as YAML, or any custom data structure.

To use csonpath with a different data type or library, simply define the required macros and types in a header file (similar to csonpath_json-c.h or csonpath_python.c), then include your backend header before csonpath.h. This approach allows you to adapt csonpath for manipulating data in any format that supports array/object semantics, giving you full flexibility beyond just JSON.

Directory Structure

  • csonpath.h, csonpath_do.h - Main implementation files
  • csonpath_json-c.h - Json-C implementation, use it by including "csonpath_json-c.h" directly in your source
  • csonpath_python.c - python implementation, use it like a python lib (so pip install .)
  • tests/ - Contains tests
  • bench/ - Some benchmarks

🀝 Contributing

We welcome contributions!

Please read our Contributing Guidelines and Code of Conduct before submitting a pull request.

Feel free to open issues or pull requests!

πŸ“œ License

BSD 3-Clause. See LICENSE.

About

Recode of jsonpath-ng

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •