JSON P3
JSONPath, JSON Pointer and JSON Patch for JavaScript.
JSONPath (RFC 9535) is a mini language for selecting values from JSON-like data. A JSONPath query has the potential to return multiple values from a data structure, along with their locations. This implementation is non-evaluating and read-only.
JSON Pointer (RFC 6901) is a syntax for targeting a single value in JSON-like data. JSON Pointers can be resolved against data to retrieve the value, or used as part of a JSON Patch operation.
JSON Patch (RFC 6902) is a standard for describing update operations to perform on JSON-like data. You can apply a patch to add, remove, replace, copy and move values within a JSON document.
We use the term JSON-like data to describe arbitrary, possibly nested, JavaScript arrays and objects, plus primitive strings, numbers, booleans and null
, as you might expect from JSON.parse()
. When traversing JSON-like data, we only resolve an object's direct properties, and the length
property of arrays and strings is ignored.
Install
Node.js
Install JSON P3 using your preferred project manager:
- npm
- yarn
- pnpm
npm install --save json-p3
yarn add json-p3
pnpm add json-p3
And import the module:
- ESM
- CJS
import { query } from "json-p3";
const { query } = require("json-p3");
Browser
Download and include JSON P3 in a script tag:
<script src="path/to/json-p3.iife.min.js"></script>
<script>
const data = {
players: [{ name: "Sue" }, { name: "John" }, { name: "Sally" }],
visitors: [{ name: "Brian" }, { name: "Roy" }],
};
const nodes = json_p3.query("$..name", data);
console.log(nodes.values());
// [ 'Sue', 'John', 'Sally', 'Brian', 'Roy' ]
</script>
Or use a CDN
<script src="https://cdn.jsdelivr.net/npm/json-p3@1.1.1/dist/json-p3.iife.min.js"></script>
<script>
const data = {
players: [{ name: "Sue" }, { name: "John" }, { name: "Sally" }],
visitors: [{ name: "Brian" }, { name: "Roy" }],
};
const nodes = json_p3.query("$..name", data);
console.log(nodes.values());
// [ 'Sue', 'John', 'Sally', 'Brian', 'Roy' ]
</script>
Example
This example uses a JSONPath query to find players with a low score, converts each node from the query result to a JSONPointer
, then uses that pointer to build a JSONPatch
that, when applied to our original data, boosts each player's score by 20.
import { query, JSONPatch } from "json-p3";
const data = {
teams: [
{
name: "A Team",
players: [
{
name: "Sue",
score: 110,
},
{
name: "John",
score: 86,
},
],
},
{
name: "B Team",
players: [
{
name: "Sally",
score: 84,
},
{
name: "Jane",
score: 55,
},
],
},
],
};
const nodes = query("$..players[?@.score < 90]", data);
const patch = new JSONPatch();
for (const node of nodes) {
const pointer = node.toPointer().join("score");
patch.replace(pointer, node.value.score + 20);
}
patch.apply(data);
console.log(JSON.stringify(data, undefined, " "));
{
"teams": [
{
"name": "A Team",
"players": [
{
"name": "Sue",
"score": 110
},
{
"name": "John",
"score": 106
}
]
},
{
"name": "B Team",
"players": [
{
"name": "Sally",
"score": 104
},
{
"name": "Jane",
"score": 75
}
]
}
]
}