[](https://www.npmjs.com/package/jsonpath-plus)
[](badges/tests-badge.svg)
[](badges/coverage-badge.svg)
[](https://snyk.io/test/github/s3u/JSONPath)
<!--[](LICENSE-MIT.txt)-->
[](badges/licenses-badge.svg)
[](https://github.com/JSONPath-Plus/JSONPath/actions/workflows/node.js.yml)
<small>(開発依存関係の[ライセンス](https://raw.githubusercontent.com/s3u/JSONPath/master/badges/licenses-badge-dev.svg?sanitize=true)も参照してください)</small>
# JSONPath Plus
JSONドキュメント(およびJavaScriptオブジェクト)からデータを分析、変換、選択的に抽出します。
`jsonpath-plus`は、元の仕様を拡張していくつかの追加演算子を加え、元の仕様では明示されていなかったいくつかの動作を明示します。
[ブラウザデモ](https://jsonpath-plus.github.io/JSONPath/demo/)または[Runkit (Node)](https://npm.runkit.com/jsonpath-plus)をお試しください。
***注意: このプロジェクトは現在積極的にメンテナンスされていません。十分に文書化されたPRや簡単な更新は受け入れる可能性がありますが、私たち自身で修正を行ったり新機能を追加したりする予定はありません。***
## 機能
* 元のjsonpath仕様に**準拠**
* 元の仕様にはない便利な**追加や詳細化**:
* 一致するアイテムの**親**を取得する`^`
* 一致するアイテムの**プロパティ名**を(配列として)取得する`~`
* 以下を取得するための**型セレクタ**:
* 基本的なJSON型: `@null()`、`@boolean()`、`@number()`、`@string()`、`@array()`、`@object()`
* `@integer()`
* 複合型`@scalar()`(JavaScriptオブジェクトをクエリする際に`undefined`や非有限数をはじめ、すべての基本的な非オブジェクト/非関数型も受け入れます)
* ユーザー定義の`otherTypeCallback`と組み合わせて使用できる`@other()`
* 非JSONのJavaScriptオブジェクトをクエリする際に使用できる非JSON型(`@undefined()`、`@function()`、`@nonFinite()`)
* フィルタ内の`@path`/`@parent`/`@property`/`@parentProperty`/`@root` **省略セレクタ**
* **エスケープ**
* 残りのシーケンスをエスケープする`` ` ``
* フィルタ内のプロパティ名の特殊文字をエスケープする`@['...']`/`?@['...']`構文
* `$..`(**すべての親コンポーネントを取得**)を文書化
* **ESM**および**UMD**エクスポート形式
* クエリされた値に加えて、値へのパスやポインタ、親オブジェクトや親プロパティ名(変更を可能にするため)など、**さまざまなメタ情報を返す**ことができます。
* パス、配列、ポインタ間の**変換ユーティリティ**
* 元の仕様で許可されている**評価を防止**するオプション、または評価される値に**サンドボックス**を提供するオプション。
* 結果が得られたときに**結果を処理するコールバック**のオプション。
## ベンチマーク
`jsonpath-plus`は、[json-querying-performance-testing](https://github.com/andykais/json-querying-performance-testing)によると、他のjsonクエリライブラリと比較して、大規模および小規模なデータセットの両方で一貫して高性能です。これらの結果は、[プロジェクトを自分で実行](https://github.com/andykais/json-querying-performance-testing#how-to-run)し、さらにパフォーマンスケースを追加することで確認できます。
## インストール
```shell
npm install jsonpath-plus
```
## セットアップ
### Node.js
```js
const {JSONPath} = require('jsonpath-plus');
const result = JSONPath({path: '...', json});
```
### ブラウザ
ブラウザで使用する場合は、`dist/index-browser-umd.cjs` を直接インクルードできます。Browserify の魔法は必要ありません:
```html
<script src="node_modules/jsonpath-plus/dist/index-browser-umd.cjs"></script>
<script>
const result = JSONPath.JSONPath({path: '...', json: {}});
</script>
```
### ESM(モダンブラウザ)
ES6モジュールインポート(モダンブラウザ向け)も使用できます:
```html
<script type="module">
import {
JSONPath
} from './node_modules/jsonpath-plus/dist/index-browser-esm.js';
const result = JSONPath({path: '...', json: {}});
</script>
```
### ESM (バンドラー)
または、JavaScript をバンドルしている場合 (例えば Rollup を使用)、以下を使用するだけで、
[`mainFields`](https://github.com/rollup/plugins/tree/master/packages/node-resolve#mainfields)
にはブラウザビルド用に `browser` を含める必要があることに注意してください (Node の場合、
デフォルトで `module` をチェックするので問題ありません):
```js
import {JSONPath} from 'jsonpath-plus';
const result = JSONPath({path: '...', json});
```
## 使用方法
利用可能な完全なシグネチャは次のとおりです:
```
const result = JSONPath([options,] path, json, callback, otherTypeCallback);
```
引数 `path`、`json`、`callback`、`otherTypeCallback` は、`options` 上で(利用可能な他のプロパティとともに)代わりに表現することもできます。
`result` には見つかったすべての項目が含まれる(オプションで配列にラップされる)のに対し、`callback` は、各項目が発見されるたびに何らかの操作を実行したい場合に使用でき、コールバック関数は結果内で見つかる独立した項目の数に応じて 0 回から N 回実行されることに注意してください。`JSONPath` で利用可能な引数の詳細については、以下のドキュメントを参照してください。
[API ドキュメント](https://jsonpath-plus.github.io/JSONPath/docs/ts/)も参照してください。
### プロパティ
options オブジェクトまたは evaluate メソッド(最初の引数として)に指定できるプロパティには、以下が含まれます:
- ***path***(**必須**)- JSONPath 式を(正規化または非正規化された)文字列または配列として指定します。
- ***json***(**必須**)- 評価する JSON オブジェクト(null、boolean、number、string、object、array のいずれの型でも可)。
- ***autostart***(**デフォルト: true**)- これを `false` として指定すると、`evaluate` メソッドを手動で呼び出すことができます。
- ***flatten***(**デフォルト: false**)- 返される結果の配列を一次元配列に平坦化するかどうか。
- ***resultType***(**デフォルト: "value"**)- "value"、"path"、"pointer"、"parent"、または "parentProperty" の大文字小文字を区別しない形式で指定でき、それぞれ見つかった項目の値として、その絶対パスとして、絶対パスへの [JSON Pointer](https://tools.ietf.org/html/rfc6901) として、その親オブジェクトとして、またはその親のプロパティ名として結果を返すかどうかを決定します。"all" に設定すると、これらすべての型が型名をキー名とするオブジェクト上で返されます。
- ***sandbox***(**デフォルト: {}**)- フィルタ式などのコード評価で利用可能にする変数のキーと値のマップ。(現在のパスと値もそれらの式で利用可能であることに注意してください。詳細は構文セクションを参照してください。)
- ***wrap***(**デフォルト: true**)- 結果を配列でラップするかどうか。`wrap` が `false` に設定され、結果が見つからない場合は、`undefined` が返されます(`wrap` が true の場合の空配列とは対照的です)。`wrap` が `false` に設定され、単一の非配列の結果が見つかった場合、その結果が唯一の返される項目となります(配列内には含まれません)。ただし、複数の結果が見つかった場合は依然として配列が返されます。曖昧さを避けるため(失敗である結果と空配列である結果を区別する必要がある場合)、デフォルトを `false` に切り替えることを推奨します。
- ***eval***(**デフォルト: "safe"**)- スクリプト評価メソッド。
`safe`: ブラウザでは、`eval` や `Function` を使用せず、Content Security Policy を満たす最小限のスクリプトエンジンを使用します。NodeJS では効果がなく、スクリプトが安全であるため native と同等です。
`native`: ネイティブのスクリプト機能を使用します。つまり、ブラウザでは安全でない `eval` または `Function`、nodejs では `vm.Script` を使用します。`false`: JavaScript 評価式を無効にし、これらの式が試行されたときに例外をスローします。
`callback [ (code, context) => value]`: `code` と `context` を引数として呼び出され、評価された値を返すカスタム実装。
`class`: `code` をコンストラクタ引数として作成され、`context` を指定して `runInNewContext` を呼び出すことでコードが評価されるクラス。
``
- ***ignoreEvalErrors***(**デフォルト: false**)- スクリプト評価中に発生したエラーを無視します。
- ***parent***(**デフォルト: null**)- クエリがルートノードを返す可能性がある場合に、そのルートノードの親を結果内で返せるようにします。
- ***parentProperty***(**デフォルト: null**)- クエリがルートノードを返す可能性がある場合に、そのルートノードの `parentProperty` を結果内で返せるようにします。これは文字列のプロパティ名または数値の配列インデックスである場合があります。
- ***callback***(**デフォルト: (なし)**)- 指定された場合、エンドポイント値の取得時に直ちにコールバックが呼び出されます。指定される 3 つの引数は、ペイロードの値(`resultType` に従う)、ペイロードの型(通常の "value" か "property" 名か)、および完全なペイロードオブジェクト(すべての `resultType` を含む)です。
- ***otherTypeCallback***(**デフォルト: \<@other() に遭遇したときにエラーをスローする関数\>**)- 現在 JSON Schema サポートが存在しないため、クエリの末尾に演算子 `@other()` を追加することで、組み込み型を超えた型を判定できます。そのようなパスに遭遇した場合、`otherTypeCallback` がその項目の値、そのパス、その親、およびその親のプロパティ名を引数として呼び出され、指定された値が "other" 型に属するかどうかを示す boolean を返す必要があります(または変換を処理して false を返してもかまいません)。
- ***customTypes***(**デフォルト: {}**)- 型名から関数へのキーと値のマップ。これにより、クエリで使用できるカスタム型演算子(例: `@myType()`)を作成できます。関数はその項目の値、そのパス、その親、およびその親のプロパティ名を引数として呼び出されます。指定された値がカスタム型に一致するかどうかを示す boolean を返す必要があります。以下のように設定することもできます:
1. インポート `jsonpath-plus/src/structuredCloningTypes.js` の値。これは以下の型を事前定義しています:
@NaN(), @BigIntObject(), @Date(), @Set(), @Map(), @RegExp(),
@Blob(optionalMimeType), @File(optionalMimeType), @Boolean(), @Number(),
@String(), @Infinity(), @negativeInfinity(), @negativeZero(),
@DOMException(), @Error(), @EvalError(), @RangeError(), @ReferenceError(),
@SyntaxError(), @TypeError(), @URIError(), @AggregateError(),
@QuotaExceededError(), @WebTransportError(), @FileList, @ArrayBuffer(),
@DataView(), @ImageData(), @ImageBitmap(), @Int8Array(), @Uint8Array(),
@Uint8ClampedArray(), @Int16Array(), @Uint16Array(), @Int32Array(),
@Uint32Array(), @Float32Array(), @Float64Array(), @BigInt64Array(),
@BigUint64Array(), @Float16Array, @DOMMatrix(), @DOMMatrixReadOnly(),
@DOMPoint(), @DOMPointReadOnly(), @DOMRect, @DOMRectReadOnly(),
@DOMQuad(), @CryptoKey(), @AudioData(), @EncodedAudioChunk(),
@EncodedVideoChunk(), @VideoFrame(), @CropTarget,
@FileSystemDirectoryHandle(), @FileSystemFileHandle(),
@GPUCompilationInfo(), @GPUCompilationMessage(),
@GPUPipelineError(), @RTCCertificate(), @RTCEncodedAudioFrame(),
@RTCEncodedVideoFrame()
2. インポート `jsonpath-plus/src/javascriptTypes.js` の値。これは以下の型を事前定義しています:
@Generator(), @AsyncGenerator(), @GeneratorFunction(),
@AsyncGeneratorFunction(), @Iterable(), @AsyncIterable(), @Iterator()
### インスタンスメソッド
- ***evaluate(path, json, callback, otherTypeCallback)*** または
***evaluate({path: \<path\>, json: \<json object\>, callback:***
***\<callback function\>, otherTypeCallback:***
***\<otherTypeCallback function\>})*** - このメソッドは、
`autostart` プロパティが `false` に設定されている場合にのみ必要です。
同じ設定を使用して繰り返し評価するために使用できます。
列挙されたプロパティに加えて、後者のメソッドパターンは
他の許可されたインスタンスプロパティのいずれかを受け入れることができます
(ここでは関連性のない `autostart` を除く)。
### クラスプロパティとメソッド
- ***JSONPath.clearCache()*** - 内部的にキャッシュされた解析済みパスと
コンパイル済みスクリプトをクリアします。キャッシュの内容は公開されません。
キャッシュの無効化が必要な場合にこのメソッドを呼び出してください。
- ***JSONPath.toPathArray(pathAsString)*** - 正規化または
非正規化されたパスを文字列として受け取り、配列に変換します:
例えば、`['$', 'aProperty', 'anotherProperty']`。
- ***JSONPath.toPathString(pathAsArray)*** - パス配列を受け取り、
正規化されたパス文字列に変換します。文字列は次のような形式になります:
`$['aProperty']['anotherProperty][0]`。JSONPath の終端構文
`~` と `^`、および `@string()` のような型演算子は
暗黙的に除去されます。
- ***JSONPath.toPointer(pathAsArray)*** - パス配列を受け取り、
[JSON Pointer](https://tools.ietf.org/html/rfc6901) に変換します。
文字列は次のような形式になります:`/aProperty/anotherProperty/0`
(`~` と `/` の内部文字は JSON Pointer 仕様に従ってエスケープされます)。
JSONPath の終端構文 `~` と `^`、および `@string()` のような
型演算子は暗黙的に除去されます。
## 例による構文
<http://goessner.net/articles/JsonPath/> から取得した以下の JSON が与えられた場合:
```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
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
```
および以下のXML表現:
```xml
<store>
<book>
<category>reference</category>
<author>Nigel Rees</author>
<title>Sayings of the Century</title>
<price>8.95</price>
</book>
<book>
<category>fiction</category>
<author>Evelyn Waugh</author>
<title>Sword of Honour</title>
<price>12.99</price>
</book>
<book>
<category>fiction</category>
<author>Herman Melville</author>
<title>Moby Dick</title>
<isbn>0-553-21311-3</isbn>
<price>8.99</price>
</book>
<book>
<category>fiction</category>
<author>J. R. R. Tolkien</author>
<title>The Lord of the Rings</title>
<isbn>0-395-19395-8</isbn>
<price>22.99</price>
</book>
<bicycle>
<color>red</color>
<price>19.95</price>
</bicycle>
</store>
```
以下のXPathの例では、要素の取得とそのテキスト内容の取得を区別していないことに注意してください(比較に有用な場合や曖昧さを避ける場合を除く)。注:XPathの例(2.0のものも含む)をテストするには、[このデモ](http://videlibri.sourceforge.net/cgi-bin/xidelcgi)が役立つかもしれません(`xml`または`xml-strict`に設定してください)。
| XPath | JSONPath | 結果 | 備考 |
|-------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/store/book/author` | `$.store.book[*].author` | ストア内のすべての書籍の著者 | `$.` を付けずに `store.book[*].author` と表すこともできる(ただしこれは元の仕様には存在しない);一部の文字リテラル(`$` と `@`)はエスケープが必要であることに注意 |
| `//author` | `$..author` | すべての著者 | |
| `/store/*` | `$.store.*` | ストア内のすべてのもの、すなわち書籍(書籍の配列)と赤い自転車(自転車オブジェクト) | |
| `/store//price` | `$.store..price` | ストア内のすべてのものの価格 | |
| `//book[3]` | `$..book[2]` | 3 番目の書籍(書籍オブジェクト) | |
| `//book[last()]` | `$..book[(@.length-1)]` <br> `$..book[-1:]` | 順序における最後の書籍 | 特殊文字を含むプロパティにアクセスするには、フィルターに `[(@['...'])]` を使用する(この特定の機能は元の仕様には存在しない) |
| `//book[position()<3]` | `$..book[0,1]` <br> `$..book[:2]` | 最初の 2 冊の書籍 | |
| `//book/*[self::category\|self::author]` または XPath 2.0 の `//book/(category,author)` | `$..book[0][category,author]` | すべての書籍のカテゴリと著者 | |
| `//book[isbn]` | `$..book[?(@.isbn)]` | ISBN 番号を持つすべての書籍をフィルタリング | 特殊文字を含むプロパティにアクセスするには、フィルターに `[?@['...']]` を使用する(この特定の機能は元の仕様には存在しない) |
| `//book[price<10]` | `$..book[?(@.price<10)]` | 10 未満のすべての書籍をフィルタリング | |
| `//*[name() = 'price' and . != 8.95]` | `$..*[?(@property === 'price' && @ !== 8.95)]` | プロパティが price であり、かつ 8.95 と等しくないオブジェクトのすべてのプロパティ値を取得 | 裸の `@` を使用するとプロパティ値でオブジェクトをフィルタリングできる(必ずしも配列内である必要はない);式の後に `^` を追加すると、フィルタリングされたプロパティを持つオブジェクトを取得できる |
| `/` | `$` | JSON オブジェクトのルート(すなわち、オブジェクト全体そのもの) | リテラルの `$`(単独またはパス内の任意の場所)を取得するには、バッククォートエスケープを使用する必要がある |
---
[Read more](https://github.com/jsonpath-plus/jsonpath)