JSONPath Functions
This page describes functions that can be called as part of a filter expression. Some of these functions are defined by RFC 9535 and are available by default. Others are bundled with JSON P3 but need to be explicitly registered with a JSONPathEnvironment
. You can create your own function extensions too.
The JSONPath specification defines a type system for function expressions, and rules for how those types can be used within an expression. JSON P3 will throw a JSONPathTypeError at query compile time if it contains expressions that are not deemed to be well-typed.
Please see Section 2.4.3 Well-Typedness of Function Expressions.
Standard functions
These are the standard JSONPath filter selector functions defined by RFC 9535. They are registered with every JSONPathEnvironment
by default.
count()
count(nodes: JSONPathNodeList): number
Return the number of nodes in a node list. Usually, count()
will be given a filter query as its argument, and a call to count()
must be part of a comparison expression.
$.users[?count(@.*) > 2]
length()
length(value: JSONValue): number | undefined
Return the length of a string or array, or the number of items in an object. Usually, length()
will be given a filter query as its argument, and a call to length()
must be part of a comparison expression.
$.users[?length(@) > 2]
match()
match(value: string, pattern: string): boolean
Return true
if value is a full match to the regular expression pattern, or false
otherwise.
$.users[?match(@.name, '[Ss].*')]
search()
search(value: string, pattern: string): boolean
Return true
if value contains pattern, or false
otherwise.
$.users[?search(@.name, '[Aa]')]
value()
value(nodes: JSONPathNodeList): JSONValue | undefined
Return the value associated with the first node in nodes, if nodes has exactly one JSONPathNode
. Usually, value()
will be called with a filter query as its argument.
Filter queries that can result in at most one node are known as "singular queries", and all singular queries will be implicitly replaced with their value as required, without the use of value()
. value()
is useful when you need the value from a query that can, theoretically, return multiple nodes.
Extra functions
These are function extensions that are included with JSON P3, but are not registered by default.
has()
search(value: object, pattern: string): boolean
Return true
if the first argument is an object value and it contains a property name matching the second argument, or false
otherwise. pattern should be an I-Regexp string.
To use has()
in your JSONPath queries, register an instance of jsonpath.functions.Has
with a JSONPathEnvironment
.
import { jsonpath } from "json-p3";
const env = new jsonpath.JSONPathEnvironment();
env.functionRegister.set("has", new jsonpath.functions.Has());
const data = [{ abc: 1 }, 42, { abb: 2 }, { a_c: 3 }];
const nodes = env.query(`$[?has(@, 'ab.')]`, data);
By default, instances of Has
use search semantics. Set the search
option to false
when constructing a Has
instance to use match semantics instead.
env.functionRegister.set("has", new jsonpath.functions.Has({ search: false }));
See HasFilterFunctionOptions for details of all available option.
Function extensions
Add, remove or replace filter functions by updating the function register on a JSONPathEnvironment
. It is a regular Map, mapping function names to objects implementing the FilterFunction
interface.
Every filter function must define the types of its parameters and the type of its return value, according to the JSONPath specification's type system. This example implements a typeof()
function, which accepts a parameter of ValueType
and returns a ValueType
.
import {
FilterFunction,
FunctionExpressionType,
JSONPathEnvironment,
} from "json-p3";
class TypeOfFilterFunction implements FilterFunction {
readonly argTypes = [FunctionExpressionType.ValueType];
readonly returnType = FunctionExpressionType.ValueType;
public call(value: unknown): string {
return typeof value;
}
}
We would then register an instance of TypeOfFilterFunction
with a JSONPathEnvironment
, and use the environment's query()
, compile()
or match()
methods.
// .. continued from above
const env = new JSONPathEnvironment();
env.functionRegister.set("typeof", new TypeOfFilterFunction());
const nodes = env.query("$.users[?typeof(@.score) == 'number']", data);