json-pointer: Referring to bits of JSON
(require json-pointer) | package: json-pointer |
JSON Pointer (RFC 6901) is a straightforward notation for referring to values embedded within a JSON document. Given a JSON object like this:
{ |
"foo": 5, |
"bar": [ 1, 2 ] |
} |
the JSON Pointer expression /foo has the value 5, whereas the expressions /bar/0 and /bar/1 have the values 1 and 2, respectively. /baz and /bar/42 do not refer to anything.
Nothing terribly fancy is going on here: JSON Pointers are nothing more than Racket strings, and we work with jsexpr? values.
1 JSON Pointers and their expressions
This library uses two terms: JSON Pointer and JSON Pointer expression. Briefly, the first is a string, and the second is a list. A predicate for the first:
procedure
(json-pointer? x) → boolean?
x : any/c
Returns #t iff x is a string that adheres to the syntax laid out in RFC 6901.
Next, a JSON Pointer expression is a represenation of the data encoded in JSON Pointers. Think of it as the “parse tree” of a JSON Pointer. We represent this data as a list (possibly empty) of strings (which are themselves possibly empty).
procedure
x : any/c
Returns #t iff x is a list of strings.
There are essentially no constraints. The list might be empty. The strings in the list may themselves be empty, too. Dupliates are allowed.
2 Parsing and rendering
How do you parse JSON Pointers to get JSON Pointer expressions?
procedure
p : json-pointer?
Given a JSON Pointer, produce a JSON Pointer expression.
What about going the other way around? Can you render a “semantic” JSON Pointer expression into a “syntactic” JSON Pointer? Yes, you can:
procedure
(expression->pointer expr) → json-pointer?
expr : json-pointer-expression?
Given a JSON Pointer expression, produce a JSON Pointer.
3 Evaluation of JSON Pointers
procedure
(json-pointer-value jp doc) → jsexpr?
jp : (or/c json-pointer-expression? json-pointer?) doc : jsexpr?
Given a JSON Pointer and a JSON document, evaluate the JSON Pointer within the document. The result is a jsexpr?, if all goes well.
(For the first argument both json-pointer?—a string—as well as a json-pointer-expression?—a list of strings—are allowed. When given a json-pointer?, it will be parsed into a json-pointer-expression?, with which the real computation takes place.)
If things don’t go well, json-pointer-value function throws an exception (of type exn:fail?). These are the conditions under which evaluation might go awry:
The document, or some salient part of it, is not the right kind of JSON value. For traversal through a JSON document to make sense, we need to be dealing with JSON objects or arrays, not with strings, numbers, or null values.
The JSON Pointer refers to a non-existent part of the document. This happens if one refers to a non-existent object property or negative, out-of-bounds or nonsensical array indices such as "radical" or 3.1415).
4 License
This library is offered under the GNU Lesser Public License (LGPL).