jsonpath-plus
Advanced tools
Comparing version 0.14.0 to 0.15.0
116
CHANGES.md
# JSONPath changes | ||
## Jan 10, 2016 | ||
## 0.15.0 (Mar 15, 2016) | ||
- Fix: Fixing support for sandbox in the case of functions | ||
- Feature: Use `this` if present for global export | ||
- Docs: Clarify function signature | ||
- Docs: Update testing section | ||
- Dev testing: Add in missing test for browser testing | ||
- Dev testing: Add remark linting to testing process (#70) | ||
- Dev testing: Lint JS test support files | ||
- Dev testing: Split out tests into `eslint`, `remark`, `lint`, `nodeunit` | ||
- Dev testing: Remove need for nodeunit build step | ||
- Dev testing: Simplify nodeunit usage and make available | ||
as `npm run browser-test` | ||
## 0.14.0 (Jan 10, 2016) | ||
- Add `@scalar()` type operator (in JavaScript mode, will also include) | ||
- Version 0.14.0 | ||
## Jan 5, 2016 | ||
## 0.13.1 (Jan 5, 2016) | ||
- Avoid double-encoding path in results | ||
- Version 0.13.1 | ||
## Dec 13, 2015 | ||
- Breaking change (from version 0.11): Silently strip `~` and `^` operators and type operators such as `@string()` in `JSONPath.toPathString()` calls. | ||
- Breaking change: Remove `Array.isArray` polyfill as no longer supporting IE <= 8 | ||
## 0.13.0 (Dec 13, 2015) | ||
- Breaking change (from version 0.11): Silently strip `~` and `^` operators | ||
and type operators such as `@string()` in `JSONPath.toPathString()` calls. | ||
- Breaking change: Remove `Array.isArray` polyfill as no longer | ||
supporting IE <= 8 | ||
- Feature: Allow omission of options first argument to `JSONPath` | ||
- Feature: Add `JSONPath.toPointer()` and "pointer" `resultType` option. | ||
- Fix: Correctly support `callback` and `otherTypeCallback` as numbered arguments to `JSONPath`. | ||
- Fix: Correctly support `callback` and `otherTypeCallback` as numbered | ||
arguments to `JSONPath`. | ||
- Fix: Enhance Node checking to avoid issue reported with angular-mock | ||
- Fix: Allow for `@` or other special characters in at-sign-prefixed property names (by use of `[?(@['...'])]` or `[(@['...'])]`). | ||
- Version 0.13.0 | ||
- Fix: Allow for `@` or other special characters in at-sign-prefixed | ||
property names (by use of `[?(@['...'])]` or `[(@['...'])]`). | ||
## Dec 12, 2015 10:39pm | ||
- Breaking change: Problems with upper-case letters in npm is causing us to rename the package, so have renamed package to "jsonpath-plus" (there are already package with lower-case "jsonpath" or "json-path"). The new name also reflects that | ||
there have been changes to the original spec. | ||
- Version 0.12.0 | ||
## 0.12.0 (Dec 12, 2015 10:39pm) | ||
## Dec 12, 2015 10:36pm | ||
- Actually add the warning in the README that problems in npm with upper-case letters is causing us to rename to "jsonpath-plus" (next version will actually apply the change). | ||
- Version 0.11.2 | ||
- Breaking change: Problems with upper-case letters in npm is causing | ||
us to rename the package, so have renamed package to "jsonpath-plus" | ||
(there are already package with lower-case "jsonpath" or "json-path"). | ||
The new name also reflects that there have been changes to the | ||
original spec. | ||
## Dec 12, 2015 10:11pm | ||
- Give warning in README that problems in npm with upper-case letters is causing us to rename to "jsonpath-plus" (next version will actually apply the change). | ||
- Version 0.11.1 | ||
## 0.11.2 (Dec 12, 2015 10:36pm) | ||
## Dec 12, 2015 | ||
- Breaking change: For unwrapped results, return `undefined` instead of `false` upon failure to find path (to allow distinguishing of `undefined`--a non-allowed JSON value--from the valid JSON values, `null` or `false`) and return the exact value upon falsy single results (in order to allow return of `null`) | ||
- Actually add the warning in the README that problems in npm | ||
with upper-case letters is causing us to rename to "jsonpath-plus" | ||
(next version will actually apply the change). | ||
## 0.11.1 (Dec 12, 2015 10:11pm) | ||
- Give warning in README that problems in npm with upper-case letters | ||
is causing us to rename to "jsonpath-plus" (next version will actually | ||
apply the change). | ||
## 0.11.0 (Dec 12, 2015) | ||
- Breaking change: For unwrapped results, return `undefined` instead | ||
of `false` upon failure to find path (to allow distinguishing of | ||
`undefined`--a non-allowed JSON value--from the valid JSON values, | ||
`null` or `false`) and return the exact value upon falsy single | ||
results (in order to allow return of `null`) | ||
- Deprecated: Use of `jsonPath.eval()`; use new class-based API instead | ||
- Feature: AMD export | ||
- Feature: By using `self` instead of `window` export, allow JSONPath to be trivially imported into web workers, without breaking compatibility in normal scenarios. See [MDN on self](https://developer.mozilla.org/en-US/docs/Web/API/Window/self) | ||
- Feature: Offer new class-based API and object-based arguments (with option to run new queries via `evaluate()` method without resupplying config) | ||
- Feature: By using `self` instead of `window` export, allow JSONPath | ||
to be trivially imported into web workers, without breaking | ||
compatibility in normal scenarios. See [MDN on self](https://developer.mozilla.org/en-US/docs/Web/API/Window/self) | ||
- Feature: Offer new class-based API and object-based arguments (with | ||
option to run new queries via `evaluate()` method without resupplying config) | ||
- Feature: Allow new `preventEval=true` and `autostart=false` option | ||
- Feature: Allow new callback option to allow a callback function to execute as each final result node is obtained | ||
- Feature: Allow type operators: JavaScript types (`@boolean()`, `@number()`, `@string()`), other fundamental JavaScript types (`@null()`, `@object()`, `@array()`), the JSONSchema-added type, `@integer()`, and the following non-JSON types that can nevertheless be used with JSONPath when querying non-JSON JavaScript objects (`@undefined()`, `@function()`, `@nonFinite()`). Finally, `@other()` is made available in conjunction with a new callback option, `otherTypeCallback`, can be used to allow user-defined type detection (at least until JSON Schema awareness may be provided). | ||
- Feature: Support "parent" and "parentProperty" for resultType along with "all" (which also includes "path" and "value" together) | ||
- Feature: Support custom `@parent`, `@parentProperty`, `@property` (in addition to custom property `@path`) inside evaluations | ||
- Feature: Allow new callback option to allow a callback function to execute as | ||
each final result node is obtained | ||
- Feature: Allow type operators: JavaScript types (`@boolean()`, `@number()`, | ||
`@string()`), other fundamental JavaScript types (`@null()`, `@object()`, | ||
`@array()`), the JSONSchema-added type, `@integer()`, and the following | ||
non-JSON types that can nevertheless be used with JSONPath when querying | ||
non-JSON JavaScript objects (`@undefined()`, `@function()`, `@nonFinite()`). | ||
Finally, `@other()` is made available in conjunction with a new callback | ||
option, `otherTypeCallback`, can be used to allow user-defined type | ||
detection (at least until JSON Schema awareness may be provided). | ||
- Feature: Support "parent" and "parentProperty" for resultType along with | ||
"all" (which also includes "path" and "value" together) | ||
- Feature: Support custom `@parent`, `@parentProperty`, `@property` (in | ||
addition to custom property `@path`) inside evaluations | ||
- Feature: Support a custom operator (`~`) to allow grabbing of property names | ||
- Feature: Support `$` for retrieval of root, and document this as well as `$..` behavior | ||
- Feature: Expose cache on `JSONPath.cache` for those who wish to preserve and reuse it | ||
- Feature: Expose class methods `toPathString` for converting a path as array into a (normalized) path as string and `toPathArray` for the reverse (though accepting unnormalized strings as well as normalized) | ||
- Feature: Support `$` for retrieval of root, and document this as well as | ||
`$..` behavior | ||
- Feature: Expose cache on `JSONPath.cache` for those who wish to preserve and | ||
reuse it | ||
- Feature: Expose class methods `toPathString` for converting a path as array | ||
into a (normalized) path as string and `toPathArray` for the reverse (though | ||
accepting unnormalized strings as well as normalized) | ||
- Fix: Allow `^` as property name | ||
- Fix: Support `.` within properties | ||
- Fix: `@path` in index/property evaluations | ||
- Version 0.11 | ||
## Oct 23, 2013 | ||
## 0.10.0 (Oct 23, 2013) | ||
@@ -60,8 +106,6 @@ - Support for parent selection via `^` | ||
- Performance improvements | ||
- Version 0.10 | ||
## Mar 28, 2012 | ||
## 0.9.0 (Mar 28, 2012) | ||
- Support a sandbox arg to eval | ||
- Use vm.runInNewContext in place of eval | ||
- Version 0.9.0 |
@@ -10,3 +10,3 @@ /*global exports, require*/ | ||
var module; | ||
(function (require) {'use strict'; | ||
(function (glbl, require) {'use strict'; | ||
@@ -19,6 +19,23 @@ // Make sure to know if we are in real node or not (the `require` variable | ||
var moveToAnotherArray = function (source, target, conditionCb) { | ||
for (var i = 0, kl = source.length; i < kl; i++) { | ||
var key = source[i]; | ||
if (conditionCb(key)) { | ||
target.push(source.splice(i--, 1)[0]); | ||
} | ||
} | ||
}; | ||
var vm = isNode | ||
? require('vm') : { | ||
runInNewContext: function (expr, context) { | ||
return eval(Object.keys(context).reduce(function (s, vr) { | ||
var keys = Object.keys(context); | ||
var funcs = []; | ||
moveToAnotherArray(keys, funcs, function (key) { | ||
return typeof context[key] === 'function'; | ||
}); | ||
var code = funcs.reduce(function (s, func) { | ||
return 'var ' + func + '=' + context[func].toString() + ';' + s; | ||
}, ''); | ||
code += keys.reduce(function (s, vr) { | ||
return 'var ' + vr + '=' + JSON.stringify(context[vr]).replace(/\u2028|\u2029/g, function (m) { | ||
@@ -28,3 +45,4 @@ // http://www.thespanner.co.uk/2011/07/25/the-json-specification-is-now-wrong/ | ||
}) + ';' + s; | ||
}, expr)); | ||
}, expr); | ||
return eval(code); | ||
} | ||
@@ -457,7 +475,7 @@ }; | ||
else { | ||
self.jsonPath = { // Deprecated | ||
glbl.jsonPath = { // Deprecated | ||
eval: JSONPath.eval | ||
}; | ||
self.JSONPath = JSONPath; | ||
glbl.JSONPath = JSONPath; | ||
} | ||
}(typeof require === 'undefined' ? null : require)); | ||
}(this || self, typeof require === 'undefined' ? null : require)); |
106
package.json
{ | ||
"author": "Stefan Goessner", | ||
"name": "jsonpath-plus", | ||
"description": "A JS implementation of JSONPath with some additional operators", | ||
"contributors": [ | ||
{ | ||
"name": "Prof. Gössner", | ||
"email": "stefan.goessner@fh-dortmund.de" | ||
}, | ||
{ | ||
"name": "Subbu Allamaraju", | ||
"email": "subbu@subbu.org" | ||
}, | ||
{ | ||
"name": "Mike Brevoort", | ||
"email": "mike@brevoort.com" | ||
}, | ||
{ | ||
"name": "Robert Krahn", | ||
"email": "robert.krahn@gmail.com" | ||
}, | ||
{ | ||
"name": "Brett Zamir", | ||
"email": "brettz9@yahoo.com" | ||
}, | ||
{ | ||
"name": "Richard Schneider", | ||
"email": "makaretu@gmail.com" | ||
} | ||
], | ||
"license": "MIT", | ||
"version": "0.14.0", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/s3u/JSONPath.git" | ||
"author": "Stefan Goessner", | ||
"name": "jsonpath-plus", | ||
"description": "A JS implementation of JSONPath with some additional operators", | ||
"contributors": [ | ||
{ | ||
"name": "Prof. Gössner", | ||
"email": "stefan.goessner@fh-dortmund.de" | ||
}, | ||
"bugs": "https://github.com/s3u/JSONPath/issues/", | ||
"homepage": "https://github.com/s3u/JSONPath", | ||
"main": "./lib/jsonpath", | ||
"dependencies": {}, | ||
"engines": { | ||
"node": ">=0.8" | ||
{ | ||
"name": "Subbu Allamaraju", | ||
"email": "subbu@subbu.org" | ||
}, | ||
"devDependencies": { | ||
"nodeunit": "0.9.0", | ||
"eslint": "^1.10.3", | ||
"eslint-config-standard": "^4.4.0", | ||
"eslint-plugin-standard": "^1.3.1" | ||
{ | ||
"name": "Mike Brevoort", | ||
"email": "mike@brevoort.com" | ||
}, | ||
"keywords": ["json", "jsonpath"], | ||
"scripts": {"test": "./node_modules/.bin/eslint test lib && \"./node_modules/.bin/nodeunit\" test"} | ||
{ | ||
"name": "Robert Krahn", | ||
"email": "robert.krahn@gmail.com" | ||
}, | ||
{ | ||
"name": "Brett Zamir", | ||
"email": "brettz9@yahoo.com" | ||
}, | ||
{ | ||
"name": "Richard Schneider", | ||
"email": "makaretu@gmail.com" | ||
} | ||
], | ||
"license": "MIT", | ||
"version": "0.15.0", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/s3u/JSONPath.git" | ||
}, | ||
"bugs": "https://github.com/s3u/JSONPath/issues/", | ||
"homepage": "https://github.com/s3u/JSONPath", | ||
"main": "./lib/jsonpath", | ||
"dependencies": {}, | ||
"engines": { | ||
"node": ">=0.8" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^1.10.3", | ||
"eslint-config-standard": "^4.4.0", | ||
"eslint-plugin-standard": "^1.3.1", | ||
"nodeunit": "0.9.0", | ||
"remark-lint": "^3.0.0", | ||
"remark": "^4.1.2" | ||
}, | ||
"keywords": [ | ||
"json", | ||
"jsonpath" | ||
], | ||
"scripts": { | ||
"eslint": "./node_modules/.bin/eslint test lib test-helpers", | ||
"remark": "./node_modules/.bin/remark -q -f .", | ||
"lint": "npm run eslint && npm run remark", | ||
"nodeunit": "./node_modules/.bin/nodeunit test", | ||
"test": "npm run lint && npm run nodeunit", | ||
"browser-test": "npm run lint && node ./test-helpers/nodeunit-server" | ||
} | ||
} |
264
README.md
# JSONPath Plus [![build status](https://secure.travis-ci.org/s3u/JSONPath.png)](http://travis-ci.org/s3u/JSONPath) | ||
Analyse, transform, and selectively extract data from JSON documents (and JavaScript objects). | ||
Analyse, transform, and selectively extract data from JSON | ||
documents (and JavaScript objects). | ||
# Install | ||
npm install jsonpath-plus | ||
```shell | ||
npm install jsonpath-plus | ||
``` | ||
@@ -13,29 +16,40 @@ # Usage | ||
In node.js: | ||
In Node.js: | ||
```js | ||
var JSONPath = require('jsonpath-plus'); | ||
JSONPath({json: obj, path: path, callback: callback}); | ||
var JSONPath = require('jsonpath-plus'); | ||
var result = JSONPath({json: obj, path: path}); | ||
``` | ||
For browser usage you can directly include `lib/jsonpath.js`, no browserify | ||
magic necessary: | ||
For browser usage you can directly include `lib/jsonpath.js`; no Browserify | ||
magic is necessary: | ||
```html | ||
<script src="lib/jsonpath.js"></script> | ||
<script> | ||
JSONPath({path: path, json: obj, callback: callback, otherTypeCallback: otherTypeCallback}); | ||
</script> | ||
<script src="lib/jsonpath.js"></script> | ||
<script> | ||
var result = JSONPath({path: path, json: obj}); | ||
</script> | ||
``` | ||
An alternative syntax is available as: | ||
The full signature available is: | ||
```js | ||
JSONPath([options,] path, obj, callback, otherTypeCallback); | ||
var result = JSONPath([options,] path, json, callback, otherTypeCallback); | ||
``` | ||
The arguments `path`, `json`, `callback`, and `otherTypeCallback` | ||
can alternatively be expressed (along with any other of the | ||
available properties) on `options`. | ||
Note that `result` will contain all items found (optionally | ||
wrapped into an array) whereas `callback` can be used if you | ||
wish to perform some operation as each item is discovered, with | ||
the callback function being executed 0 to N times depending | ||
on the number of independent items to be found in the result. | ||
See the docs below for more on `JSONPath`'s available arguments. | ||
The following format is now deprecated: | ||
```js | ||
jsonPath.eval(options, obj, path); | ||
jsonPath.eval(options, json, path); | ||
``` | ||
@@ -45,69 +59,129 @@ | ||
The properties that can be supplied on the options object or evaluate method (as the first argument) include: | ||
The properties that can be supplied on the options object or | ||
evaluate method (as the first argument) include: | ||
- ***path*** (**required**) - The JSONPath expression as a (normalized or unnormalized) string or array | ||
- ***json*** (**required**) - The JSON object to evaluate (whether of null, boolean, number, string, object, or array type). | ||
- ***autostart*** (**default: true**) - If this is supplied as `false`, one may call the `evaluate` method manually. | ||
- ***flatten*** (**default: false**) - Whether the returned array of results will be flattened to a single dimension array. | ||
- ***resultType*** (**default: "value"**) - Can be case-insensitive form of "value", "path", "pointer", "parent", or "parentProperty" to determine respectively whether to return results as the values of the found items, as their absolute paths, as [JSON Pointers](http://www.rfc-base.org/txt/rfc-6901.txt) to the absolute paths, as their parent objects, or as their parent's property name. If set to "all", all of these types will be returned on an object with the type as key name. | ||
- ***sandbox*** (**default: {}**) - Key-value map of variables to be available to code evaluations such as filtering expressions. (Note that the current path and value will also be available to those expressions; see the Syntax section for details.) | ||
- ***wrap*** (**default: true**) - Whether or not to wrap the results in an array. If `wrap` is set to false, and no results are found, `undefined` will be returned (as opposed to an empty array with `wrap` set to true). If `wrap` is set to false and a single result is found, that result will be the only item returned (not within an array). An array will still be returned if multiple results are found, however. | ||
- ***preventEval*** (**default: false**) - Although JavaScript evaluation expressions are allowed by default, for security reasons (if one is operating on untrusted user input, for example), one may wish to set this option to `true` to throw exceptions when these expressions are attempted. | ||
- ***parent*** (**default: null**) - In the event that a query could be made to return the root node, this allows the parent of that root node to be returned within results. | ||
- ***parentProperty*** (**default: null**) - In the event that a query could be made to return the root node, this allows the parentProperty of that root node to be returned within results. | ||
- ***callback*** (**default: (none)**) - If supplied, a callback will be called immediately upon retrieval of an end point value. The three arguments supplied will be the value of the payload (according to `resultType`), the type of the payload (whether it is a normal "value" or a "property" name), and a full payload object (with all `resultType`s). | ||
- ***otherTypeCallback*** (**default: \<A function that throws an error when @other() is encountered\>**) - In the current absence of JSON Schema support, one can determine types beyond the built-in types by adding the operator `@other()` at the end of one's query. If such a path is encountered, the `otherTypeCallback` will be invoked with the value of the item, its path, its parent, and its parent's property name, and it should return a boolean indicating whether the supplied value belongs to the "other" type or not (or it may handle transformations and return false). | ||
- ***path*** (**required**) - The JSONPath expression as a (normalized | ||
or unnormalized) string or array | ||
- ***json*** (**required**) - The JSON object to evaluate (whether of | ||
null, boolean, number, string, object, or array type). | ||
- ***autostart*** (**default: true**) - If this is supplied as `false`, | ||
one may call the `evaluate` method manually. | ||
- ***flatten*** (**default: false**) - Whether the returned array of results | ||
will be flattened to a single dimension array. | ||
- ***resultType*** (**default: "value"**) - Can be case-insensitive form of | ||
"value", "path", "pointer", "parent", or "parentProperty" to determine | ||
respectively whether to return results as the values of the found items, | ||
as their absolute paths, as [JSON Pointers](http://www.rfc-base.org/txt/rfc-6901.txt) | ||
to the absolute paths, as their parent objects, or as their parent's | ||
property name. If set to "all", all of these types will be returned on | ||
an object with the type as key name. | ||
- ***sandbox*** (**default: {}**) - Key-value map of variables to be | ||
available to code evaluations such as filtering expressions. (Note | ||
that the current path and value will also be available to those | ||
expressions; see the Syntax section for details.) | ||
- ***wrap*** (**default: true**) - Whether or not to wrap the results | ||
in an array. If `wrap` is set to false, and no results are found, | ||
`undefined` will be returned (as opposed to an empty array with | ||
`wrap` set to true). If `wrap` is set to false and a single result | ||
is found, that result will be the only item returned (not within | ||
an array). An array will still be returned if multiple results are | ||
found, however. | ||
- ***preventEval*** (**default: false**) - Although JavaScript evaluation | ||
expressions are allowed by default, for security reasons (if one is | ||
operating on untrusted user input, for example), one may wish to | ||
set this option to `true` to throw exceptions when these expressions | ||
are attempted. | ||
- ***parent*** (**default: null**) - In the event that a query could be | ||
made to return the root node, this allows the parent of that root node | ||
to be returned within results. | ||
- ***parentProperty*** (**default: null**) - In the event that a query | ||
could be made to return the root node, this allows the `parentProperty` | ||
of that root node to be returned within results. | ||
- ***callback*** (**default: (none)**) - If supplied, a callback will be | ||
called immediately upon retrieval of an end point value. The three arguments | ||
supplied will be the value of the payload (according to `resultType`), | ||
the type of the payload (whether it is a normal "value" or a "property" | ||
name), and a full payload object (with all `resultType`s). | ||
- ***otherTypeCallback*** (**default: \<A function that throws an error** | ||
**when @other() is encountered\>**) - In the current absence of JSON | ||
Schema support, one can determine types beyond the built-in types by | ||
adding the operator `@other()` at the end of one's query. If such a | ||
path is encountered, the `otherTypeCallback` will be invoked with the | ||
value of the item, its path, its parent, and its parent's property name, | ||
and it should return a boolean indicating whether the supplied value | ||
belongs to the "other" type or not (or it may handle transformations and | ||
return false). | ||
## Instance methods | ||
- ***evaluate(path, json, callback, otherTypeCallback)*** OR ***evaluate({path: \<path\>, json: \<json object\>, callback: \<callback function\>, otherTypeCallback: \<otherTypeCallback function\>})*** - This method is only necessary if the `autostart` property is set to `false`. It can be used for repeated evaluations using the same configuration. Besides the listed properties, the latter method pattern can accept any of the other allowed instance properties (except for `autostart` which would have no relevance here). | ||
- ***evaluate(path, json, callback, otherTypeCallback)*** OR | ||
***evaluate({path: \<path\>, json: \<json object\>, callback:*** | ||
***\<callback function\>, otherTypeCallback:*** | ||
***\<otherTypeCallback function\>})*** - This method is only | ||
necessary if the `autostart` property is set to `false`. It | ||
can be used for repeated evaluations using the same configuration. | ||
Besides the listed properties, the latter method pattern can | ||
accept any of the other allowed instance properties (except | ||
for `autostart` which would have no relevance here). | ||
## Class properties and methods | ||
- ***JSONPath.cache*** - Exposes the cache object for those who wish to preserve and reuse it for optimization purposes. | ||
- ***JSONPath.toPathArray(pathAsString)*** - Accepts a normalized or unnormalized path as string and converts to an array: for example, `['$', 'aProperty', 'anotherProperty']`. | ||
- ***JSONPath.toPathString(pathAsArray)*** - Accepts a path array and converts to a normalized path string. The string will be in a form like: `$['aProperty']['anotherProperty][0]`. The JSONPath terminal constructions `~` and `^` and type operators like `@string()` are silently stripped. | ||
- ***JSONPath.toPointer(pathAsArray)*** - Accepts a path array and converts to a [JSON Pointer](http://www.rfc-base.org/txt/rfc-6901.txt). The string will be in a form like: `'/aProperty/anotherProperty/0` (with any `~` and `/` internal characters escaped as per the JSON Pointer spec). The JSONPath terminal constructions `~` and `^` and type operators like `@string()` are silently stripped. | ||
- ***JSONPath.cache*** - Exposes the cache object for those who wish | ||
to preserve and reuse it for optimization purposes. | ||
- ***JSONPath.toPathArray(pathAsString)*** - Accepts a normalized or | ||
unnormalized path as string and converts to an array: for | ||
example, `['$', 'aProperty', 'anotherProperty']`. | ||
- ***JSONPath.toPathString(pathAsArray)*** - Accepts a path array and | ||
converts to a normalized path string. The string will be in a form | ||
like: `$['aProperty']['anotherProperty][0]`. The JSONPath terminal | ||
constructions `~` and `^` and type operators like `@string()` are | ||
silently stripped. | ||
- ***JSONPath.toPointer(pathAsArray)*** - Accepts a path array and | ||
converts to a [JSON Pointer](http://www.rfc-base.org/txt/rfc-6901.txt). | ||
The string will be in a form like: `'/aProperty/anotherProperty/0` | ||
(with any `~` and `/` internal characters escaped as per the JSON | ||
Pointer spec). The JSONPath terminal constructions `~` and `^` and | ||
type operators like `@string()` are silently stripped. | ||
# Syntax through examples | ||
Given the following JSON, taken from http://goessner.net/articles/JsonPath/ : | ||
Given the following JSON, taken from <http://goessner.net/articles/JsonPath/>: | ||
```json | ||
{ | ||
"store": { | ||
"book": [ | ||
{ | ||
"category": "reference", | ||
"author": "Nigel Rees", | ||
"title": "Sayings of the Century", | ||
"price": 8.95 | ||
}, | ||
{ | ||
"category": "fiction", | ||
"author": "Evelyn Waugh", | ||
"title": "Sword of Honour", | ||
"price": 12.99 | ||
}, | ||
{ | ||
"category": "fiction", | ||
"author": "Herman Melville", | ||
"title": "Moby Dick", | ||
"isbn": "0-553-21311-3", | ||
"price": 8.99 | ||
}, | ||
{ | ||
"category": "fiction", | ||
"author": "J. R. R. Tolkien", | ||
"title": "The Lord of the Rings", | ||
"isbn": "0-395-19395-8", | ||
"price": 22.99 | ||
{ | ||
"store": { | ||
"book": [ | ||
{ | ||
"category": "reference", | ||
"author": "Nigel Rees", | ||
"title": "Sayings of the Century", | ||
"price": 8.95 | ||
}, | ||
{ | ||
"category": "fiction", | ||
"author": "Evelyn Waugh", | ||
"title": "Sword of Honour", | ||
"price": 12.99 | ||
}, | ||
{ | ||
"category": "fiction", | ||
"author": "Herman Melville", | ||
"title": "Moby Dick", | ||
"isbn": "0-553-21311-3", | ||
"price": 8.99 | ||
}, | ||
{ | ||
"category": "fiction", | ||
"author": "J. R. R. Tolkien", | ||
"title": "The Lord of the Rings", | ||
"isbn": "0-395-19395-8", | ||
"price": 22.99 | ||
} | ||
], | ||
"bicycle": { | ||
"color": "red", | ||
"price": 19.95 | ||
} | ||
], | ||
"bicycle": { | ||
"color": "red", | ||
"price": 19.95 | ||
} | ||
} | ||
} | ||
``` | ||
@@ -156,31 +230,32 @@ | ||
XPath | JSONPath | Result | Notes | ||
------------------- | ---------------------- | ------------------------------------- | ----- | ||
/store/book/author | $.store.book[*].author | The authors of all books in the store | Can also be represented without the `$.` as `store.book[*].author` (though this is not present in the original spec) | ||
| XPath | JSONPath | Result | Notes | | ||
| ----------------- | ---------------------- | ------------------------------------- | ----- | | ||
/store/book/author | $.store.book\[*].author | The authors of all books in the store | Can also be represented without the `$.` as `store.book[*].author` (though this is not present in the original spec) | ||
//author | $..author | All authors | | ||
/store/* | $.store.* | All things in store, which are its books (a book array) and a red bicycle (a bicycle object).| | ||
/store//price | $.store..price | The price of everything in the store. | | ||
//book[3] | $..book[2] | The third book (book object) | | ||
//book[last()] | $..book[(@.length-1)]<br>$..book[-1:] | The last book in order.| To access a property with a special character, utilize `[(@['...'])]` for the filter (this particular feature is not present in the original spec) | ||
//book[position()<3]| $..book[0,1]<br>$..book[:2]| The first two books | | ||
//book/*[self::category\|self::author] or //book/(category,author) in XPath 2.0 | $..book[0][category,author]| The categories and authors of all books | | ||
//book[isbn] | $..book[?(@.isbn)] | Filter all books with an ISBN number | To access a property with a special character, utilize `[?@['...']]` for the filter (this particular feature is not present in the original spec) | ||
//book[price<10] | $..book[?(@.price<10)] | Filter all books cheaper than 10 | | ||
| //\*[name() = 'price' and . != 8.95] | $..\*[?(@property === 'price' && @ !== 8.95)] | Obtain all property values of objects whose property is price and which does not equal 8.95 | | ||
//book\[3] | $..book\[2] | The third book (book object) | | ||
//book\[last()] | $..book\[(@.length-1)]<br>$..book\[-1:] | The last book in order.| To access a property with a special character, utilize `[(@['...'])]` for the filter (this particular feature is not present in the original spec) | ||
//book\[position()<3]| $..book\[0,1]<br>$..book\[:2]| The first two books | | ||
//book/*\[self::category\|self::author] or //book/(category,author) in XPath 2.0 | $..book\[0]\[category,author]| The categories and authors of all books | | ||
//book\[isbn] | $..book\[?(@.isbn)] | Filter all books with an ISBN number | To access a property with a special character, utilize `[?@['...']]` for the filter (this particular feature is not present in the original spec) | ||
//book\[price<10] | $..book\[?(@.price<10)] | Filter all books cheaper than 10 | | ||
| //\*\[name() = 'price' and . != 8.95] | $..\*\[?(@property === 'price' && @ !== 8.95)] | Obtain all property values of objects whose property is price and which does not equal 8.95 | | ||
/ | $ | The root of the JSON object (i.e., the whole object itself) | | ||
//\*/\*\|//\*/\*/text() | $..* | All Elements (and text) beneath root in an XML document. All members of a JSON structure beneath the root. | | ||
//* | $.. | All Elements in an XML document. All parent components of a JSON structure including root. | This behavior was not directly specified in the original spec | ||
//*[price>19]/.. | $..[?(@.price>19)]^ | Parent of those specific items with a price greater than 19 (i.e., the store value as the parent of the bicycle and the book array as parent of an individual book) | Parent (caret) not documented in the original spec | ||
//*\[price>19]/.. | $..\[?(@.price>19)]^ | Parent of those specific items with a price greater than 19 (i.e., the store value as the parent of the bicycle and the book array as parent of an individual book) | Parent (caret) not documented in the original spec | ||
/store/*/name() (in XPath 2.0) | $.store.*~ | The property names of the store sub-object ("book" and "bicycle"). Useful with wildcard properties. | Property name (tilde) is not present in the original spec | ||
/store/book\[not(. is /store/book\[1\])\] (in XPath 2.0) | $.store.book[?(@path !== "$[\'store\'][\'book\'][0]")] | All books besides that at the path pointing to the first | @path not present in the original spec | ||
//book[parent::\*/bicycle/color = "red"]/category | $..book[?(@parent.bicycle && @parent.bicycle.color === "red")].category | Grabs all categories of books where the parent object of the book has a bicycle child whose color is red (i.e., all the books) | @parent is not present in the original spec | ||
//book/*[name() != 'category'] | $..book.*[?(@property !== "category")] | Grabs all children of "book" except for "category" ones | @property is not present in the original spec | ||
//book/*[position() != 0] | $..book[?(@property !== 0)] | Grabs all books whose property (which, being that we are reaching inside an array, is the numeric index) is not 0 | @property is not present in the original spec | ||
/store/\*/\*[name(parent::*) != 'book'] | $.store.*[?(@parentProperty !== "book")] | Grabs the grandchildren of store whose parent property is not book (i.e., bicycle's children, "color" and "price") | @parentProperty is not present in the original spec | ||
//book[count(preceding-sibling::\*) != 0]/\*/text() | $..book.*[?(@parentProperty !== 0)] | Get the property values of all book instances whereby the parent property of these values (i.e., the array index holding the book item parent object) is not 0 | @parentProperty is not present in the original spec | ||
/store/book\[not(. is /store/book\[1\])\] (in XPath 2.0) | $.store.book\[?(@path !== "$\[\'store\']\[\'book\']\[0]")] | All books besides that at the path pointing to the first | @path not present in the original spec | ||
//book\[parent::\*/bicycle/color = "red"]/category | $..book\[?(@parent.bicycle && @parent.bicycle.color === "red")].category | Grabs all categories of books where the parent object of the book has a bicycle child whose color is red (i.e., all the books) | @parent is not present in the original spec | ||
//book/*\[name() != 'category'] | $..book.*\[?(@property !== "category")] | Grabs all children of "book" except for "category" ones | @property is not present in the original spec | ||
//book/*\[position() != 0] | $..book\[?(@property !== 0)] | Grabs all books whose property (which, being that we are reaching inside an array, is the numeric index) is not 0 | @property is not present in the original spec | ||
/store/\*/\*\[name(parent::*) != 'book'] | $.store.*\[?(@parentProperty !== "book")] | Grabs the grandchildren of store whose parent property is not book (i.e., bicycle's children, "color" and "price") | @parentProperty is not present in the original spec | ||
//book\[count(preceding-sibling::\*) != 0]/\*/text() | $..book.*\[?(@parentProperty !== 0)] | Get the property values of all book instances whereby the parent property of these values (i.e., the array index holding the book item parent object) is not 0 | @parentProperty is not present in the original spec | ||
//book/../\*\[. instance of element(\*, xs:decimal)\] (in XPath 2.0) | $..book..\*@number() | Get the numeric values within the book array | @number(), the other basic types (@boolean(), @string()), other low-level derived types (@null(), @object(), @array()), the JSONSchema-added type, @integer(), the compound type @scalar() (which also accepts `undefined` and non-finite numbers for JavaScript objects as well as all of the basic non-object/non-function types), the type, @other(), to be used in conjunction with a user-defined callback (see `otherTypeCallback`) and the following non-JSON types that can nevertheless be used with JSONPath when querying non-JSON JavaScript objects (@undefined(), @function(), @nonFinite()) are not present in the original spec | ||
Any additional variables supplied as properties on the optional "sandbox" | ||
object option are also available to (parenthetical-based) | ||
evaluations. | ||
Any additional variables supplied as properties on the optional "sandbox" object option are also available to (parenthetical-based) evaluations. | ||
# Potential sources of confusion for XPath users | ||
@@ -206,14 +281,17 @@ | ||
Running the tests on node: `npm test`. For in-browser tests: | ||
Running the tests on Node: | ||
* Ensure that nodeunit is browser-compiled: `cd node_modules/nodeunit; make browser;` | ||
* Serve the js/html files: | ||
```shell | ||
npm test | ||
``` | ||
```sh | ||
node -e "require('http').createServer(function(req,res) { \ | ||
var s = require('fs').createReadStream('.' + req.url); \ | ||
s.pipe(res); s.on('error', function() {}); }).listen(8082);" | ||
For in-browser tests: | ||
- Serve the js/html files: | ||
```shell | ||
npm run browser-test | ||
``` | ||
* To run the tests visit [http://localhost:8082/test/test.html](). | ||
- Visit [http://localhost:8082/test/test.html](http://localhost:8082/test/test.html). | ||
@@ -220,0 +298,0 @@ # License |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
41531
8
442
297
6