Data formats

JSONPath

Query values with JSONPath (RFC 9535): filters, slices, recursive descent and functions, with the paths of what matched.

Version 1.0.0 · 3 functions · 2 crates

#json#api#query#search

Functions

What use jsonpath.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use jsonpath, jsonpath_first from jsonpath (Quillo 0.6).

jsonpath(value: any, query: str) → listor an error

Every value in value that query selects, in document order: $.orders[*].total, $..email, $.items[?@.qty > 1], $.items[0:2], functions length(), count(), match(), search() and value(). An empty list when nothing matches.

jsonpath_first(value: any, query: str) → anyor an error

The first value query selects, or null.

jsonpath_located(value: any, query: str) → listor an error

Where each selected value is, with the value: { path, value }, path written as RFC 9535's normalized path ($['items'][2]) and as a JSON Pointer (pointer: /items/2), for json_patch operations.

Get it

$ quillo install jsonpath               # jsonpath.qwer into this folder$ quillo install jsonpath --example     # and its example, jsonpath.qwe

Or with curl:

$ curl -O https://quillolang.org/plugins/files/jsonpath.qwer$ curl -O https://quillolang.org/plugins/files/jsonpath.qwe

Then, in your program, all of it or only what you call:

main.qwe
use jsonpath.qweruse jsonpath, jsonpath_first from jsonpath      // Quillo 0.6: only these

It uses these crates, which cargo fetches the first time the plugin is built:

[dependencies]
serde_json_path = "0.7"serde_json = "1"

Example

jsonpath.qwe
// Picking what a page needs out of a large API answer with JSONPath.////   quillo run jsonpath.qwe      then open http://localhost:8080/cheapuse "jsonpath.qwer"let STORE = {    store: {        books: [            { title: "Sayings of the Century", author: "Nigel Rees", price: 8.95, tags: ["quotes"] },            { title: "Sword of Honour", author: "Evelyn Waugh", price: 12.99, tags: ["war", "fiction"] },            { title: "Moby Dick", author: "Herman Melville", price: 8.99, isbn: "0-553-21311-3", tags: ["sea", "fiction"] },            { title: "The Lord of the Rings", author: "J. R. R. Tolkien", price: 22.99, isbn: "0-395-19395-8", tags: ["fantasy", "fiction"] },        ],        bicycle: { colour: "red", price: 399 },    },}route GET /cheap = jsonpath(STORE, "$.store.books[?@.price < 10].title")?route GET /query ? { q: str = "$..author" } = { q, found: jsonpath(STORE, q)? }route GET /where = {    with_isbn: jsonpath_located(STORE, "$.store.books[?@.isbn]")? | map((n) => n.pointer),    first_over_10: jsonpath_first(STORE, "$.store.books[?@.price > 10].title")?,    authors_h: jsonpath(STORE, "$.store.books[?match(@.author, 'H.*')].title")?,    two_tags: jsonpath(STORE, "$.store.books[?length(@.tags) == 2].author")?,    bad: jsonpath(STORE, "$.store[").error,}
$ quillo run jsonpath.qwe$ curl 'localhost:8080/cheap'$ curl 'localhost:8080/where'$ curl 'localhost:8080/query?q=$.store.bicycle.colour'

Source

jsonpath.qwer
//! Query values with JSONPath (RFC 9535): `$.store.book[?@.price < 10].title` and the like, to pick fields out of large API answers and documents.//! version: 1.0.0//!//! [dependencies]//! serde_json_path = "0.7"//! serde_json = "1"use serde_json::{json, Value};use serde_json_path::JsonPath;fn path(p: &str) -> Result<JsonPath, String> {    JsonPath::parse(p).map_err(|e| format!("not a JSONPath: {}", e))}/// Every value in `value` that `query` selects, in document order: `$.orders[*].total`, `$..email`, `$.items[?@.qty > 1]`,/// `$.items[0:2]`, functions `length()`, `count()`, `match()`, `search()` and `value()`. An empty list when nothing matches.pub fn jsonpath(value: serde_json::Value, query: &str) -> Result<Vec<Value>, String> {    Ok(path(query)?.query(&value).all().into_iter().cloned().collect())}/// The first value `query` selects, or null.pub fn jsonpath_first(value: serde_json::Value, query: &str) -> Result<Value, String> {    Ok(path(query)?.query(&value).first().cloned().unwrap_or(Value::Null))}/// Where each selected value is, with the value: `{ path, value }`, `path` written as RFC 9535's normalized path (`$['items'][2]`)/// and as a JSON Pointer (`pointer`: `/items/2`), for json_patch operations.pub fn jsonpath_located(value: serde_json::Value, query: &str) -> Result<Vec<Value>, String> {    Ok(path(query)?.query_located(&value).into_iter().map(|n| json!({        "path": n.location().to_string(),        "pointer": n.location().to_json_pointer(),        "value": n.node(),    })).collect())}
Thread
87Useful? Like it, or add to its thread below.

Thread 0 posts

On JSONPath: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.