alltools.one
JSON
2025-07-04
8 min
alltools.one Team
JSONJSONPathQueryData ExtractionAPI

JSONPathクエリガイド:プロのようにデータを抽出する

JSONPathはJSONのクエリ言語で、XMLに対するXPathと同様の役割を果たします。APIからの複雑で深くネストされたJSONレスポンスを扱う場合、JSONPathを使えばループや条件分岐を書かずに必要なデータを正確に抽出できます。このガイドでは、構文、演算子、実践的なパターンを解説します。

なぜJSONPathか?

ネストされたデータを持つ典型的なAPIレスポンスを考えてみましょう:

{
  "store": {
    "books": [
      { "title": "Clean Code", "author": "Robert Martin", "price": 32.99, "tags": ["programming", "best-practices"] },
      { "title": "Design Patterns", "author": "Gang of Four", "price": 44.99, "tags": ["programming", "architecture"] },
      { "title": "The Pragmatic Programmer", "author": "Hunt & Thomas", "price": 39.99, "tags": ["programming", "career"] }
    ],
    "music": [
      { "title": "Kind of Blue", "artist": "Miles Davis", "price": 12.99 }
    ]
  }
}

すべての本のタイトルを取得するには、ループを書くこともできますが、JSONPathなら $.store.books[*].title で済みます。

基本構文

説明
$ルートオブジェクト
.子演算子
..再帰降下(すべてのレベルを検索)
[*]ワイルドカード(すべての要素)
[n]配列インデックス(0始まり)
[n,m]複数インデックス
[start:end:step]配列スライス
[?()]フィルター式
@現在の要素(フィルター内)

ドット記法 vs ブラケット記法

どちらの記法もプロパティにアクセスしますが、特殊文字にはブラケット記法が必要です:

# ドット記法
$.store.books[0].title

# ブラケット記法(同等)
$['store']['books'][0]['title']

# 特殊文字を含むキーには必須
$['store']['price-range']

配列操作

インデックス指定

$.store.books[0]          # 最初の本
$.store.books[-1]         # 最後の本
$.store.books[0,2]        # 最初と3番目の本

スライス

$.store.books[0:2]        # 最初の2冊(インデックス0と1)
$.store.books[1:]         # 最初を除くすべての本
$.store.books[:2]         # 最初の2冊
$.store.books[::2]        # 1つおきの本

ワイルドカード

$.store.books[*].title    # すべての本のタイトル
$.store.*                 # すべてのストアコレクション(books、music)
$..title                  # あらゆる深さのすべてのタイトル
$..price                  # あらゆる深さのすべての価格

再帰降下演算子(..)は、階層内の位置に関係なく値を抽出する場合に特に強力です。

フィルター式

フィルターは条件に基づいて要素を選択します:

# $40未満の本
$.store.books[?(@.price < 40)]

# 特定の著者の本
$.store.books[?(@.author == 'Robert Martin')]

# タグが2つ以上の本
$.store.books[?(@.tags.length > 2)]

# 'price'プロパティを持つ本
$.store.books[?(@.price)]

フィルターの組み合わせ

# $40未満でprogrammingタグの本
$.store.books[?(@.price < 40 && @.tags[0] == 'programming')]

実践的な例

APIレスポンスからの抽出

GitHub API — すべてのリポジトリ名を取得:

$[*].name

天気API — 今日の気温を取得:

$.daily[0].temp.day

ECサイトAPI — すべての商品画像を取得:

$.products[*].images[0].url

設定の抽出

Docker Compose — すべてのサービス名を取得:

$.services.*~

Package.json — すべての依存関係名を取得:

$.dependencies.*~

JSONPath vs jq

JSONPathとjqはどちらもJSONクエリツールですが、使用コンテキストが異なります:

機能JSONPathjq
環境ライブラリ、APIコマンドライン
構文XPathインスパイアカスタム関数型
変換クエリのみクエリ + 変換
標準RFC 9535デファクトスタンダード

コマンドラインでのJSON処理にはjqの方が強力です。アプリケーションへのクエリ埋め込みやWebツールでの使用には、JSONPathの方が広くサポートされています。

JSON Path ExplorerでJSONPath式をインタラクティブに試せます。JSONを貼り付け、クエリを書き、結果を即座に確認できます。

実装例

JavaScript(jsonpath-plus)

const { JSONPath } = require('jsonpath-plus');
const result = JSONPath({
  path: '$.store.books[?(@.price < 40)].title',
  json: data
});
// ["Clean Code", "The Pragmatic Programmer"]

Python(jsonpath-ng)

from jsonpath_ng import parse
expr = parse('$.store.books[*].title')
titles = [match.value for match in expr.find(data)]

RFC 9535:JSONPath標準

2024年2月、JSONPathはRFC 9535として正式に標準化されました。これにより実装間の歴史的な不整合が解消されます。標準化された主な動作:

  • 配列インデックスは0始まり
  • フィルター式は現在の要素に @ を使用
  • 文字列比較は大文字小文字を区別
  • 結果は常にマッチした値の配列

JSONPathライブラリを選ぶ際は、一貫した動作のためにRFC 9535をサポートするものを優先してください。

FAQ

JSONPathとJSON Pointerの違いは何ですか?

JSONPathはワイルドカードとフィルターを使用して複数の値にマッチできるクエリ言語です。JSON Pointer(RFC 6901)は正確に1つの値をアドレスするシンプルなパス構文です:/store/books/0/title。検索やフィルタリングが必要な場合はJSONPathを、正確なパスがわかっている場合はJSON Pointerを使用してください。

JSONPathでJSONデータを変更できますか?

標準のJSONPathは読み取り専用で、抽出はしますが変更はしません。一部のライブラリはset/delete操作でJSONPathを拡張していますが、これらは非標準です。変換にはjq(コマンドライン)を使用するか、アプリケーションコードを書いてください。JSON構造の表示と探索には、クエリを書く前にデータを理解するためにJSONフォーマッターが役立ちます。

関連リソース

Published on 2025-07-04
JSONPath Query Guide: Extracting Data Like a Pro | alltools.one