JSONPath の動作: ネストされた API 応答からデータを抽出する正しい方法

実際に発生した問題は「json { "code": 200, "data": { "user": { "profile": { "name": "Zhang San", "contacts": [ {"type": "email", "value": "zhangsan@example.

実際に発生した問題

{
  "code": 200,
  "data": {
    "user": {
      "profile": {
        "name": "张三",
        "contacts": [
          {"type": "email", "value": "[email protected]"},
          {"type": "phone", "value": "13800138000"}
        ]
      }
    },
    "orders": [
      {"id": 1, "amount": 99.99, "status": "paid"},
      {"id": 2, "amount": 199.99, "status": "pending"}
    ]
  }
}
抽出する必要があります:
  • ユーザー名
  • すべての電子メール アドレス
  • 支払われた注文金額
コードで多層ループと判断を記述していますか?いいえ、JSONPath を直接使用します。

正しい JSONPath 式

1。ユーザー名を抽出

$.data.user.profile.name
結果:"张三"

2。すべての電子メール アドレスを抽出します

$.data.user.profile.contacts[?(@.type=='email')].value
结果:["[email protected]"]

3.支払われた注文の金額を抽出します

$.data.orders[?(@.status=='paid')].amount
结果:[99.99]

4.すべての注文 ID と金額を抽出

$.data.orders[*].[id,amount]
结果:[[1,99.99],[2,199.99]]

Tools Obsession でテスト

開くJSONPath Tester し、左側に API 応答を貼り付け、右側に式を入力して、[テスト] をクリックします。 このツールは一致結果をすぐに表示し、式が正しいかどうかを確認するのに役立ちます。

一般的な JSONPath エラー

エラー 1: 忘れた $シンボル

❌ data.user.name
✅ $.data.user.name

エラー 2: 配列インデックスは 1 から始まります

❌ $.data.orders[1]  // 这是第二个元素
✅ $.data.orders[0]  // 这才是第一个元素

エラー 3: フィルター構文エラー

❌ $.data.orders[?(@.status=paid)]    // 单个等号
❌ $.data.orders[?(@.status==paid)]   // 没有引号
✅ $.data.orders[?(@.status=='paid')] // 正确

エラー 4: 再帰検索の使いすぎ

❌ $..name  // 会找所有层级的 name,可能匹配太多
✅ $.data.user.profile.name  // 明确路径更精确

エラー 5: 引用符の間違った使用

❌ $.data.orders[?(@.status=="paid")]  // 双引号在某些解析器中会出错
✅ $.data.orders[?(@.status=='paid')]  // 单引号更稳定

実践的なヒント

ヒント 1: 最初に親パスをテストします

データ構造がわからないですか?最初に親パスをテストします:
$.data              // 确认能取到 data
$.data.user         // 确认能取到 user
$.data.user.profile // 确认能取到 profile

ヒント 2: スライスを使用する

最初の 3 つの順序だけが必要ですか?
$.data.orders[0:3]

ヒント 3: 最後の要素を取得する

$.data.orders[-1:]

ヒント 4: 複数フィールドの選択

複数のフィールドを同時に取得する:
$.data.orders[*].[id,status]

ヒント 5: 複雑な条件フィルタリング

金額が 100 を超えており、ステータスは支払い済みです:
$.data.orders[?(@.amount>100 && @.status=='paid')]

FAQ

  • Q: JSONPath と JSON の違いは何ですか?
A: JSON はデータ形式で、JSONPath はクエリ言語です。 SQL がデータベース クエリ言語であるのと同様に、JSONPath は JSON クエリ言語です。
  • Q: すべての JSON ライブラリは JSONPath をサポートしていますか?
A: いいえ。Java の JsonPath ライブラリ、JavaScript の JSONPath-plus ライブラリ、および Python の jsonpath-ng ライブラリでサポートされています。使用する前にライブラリがそれをサポートしていることを確認してください。
  • Q: 私の式はツールでは機能するのに、コードでは機能しないのはなぜですか?
A: ライブラリごとに構文は若干異なります。 Tool Junkies は標準の JSONPath 構文を使用し、コード内で同じライブラリ (Java の com.jayway.jsonpath など) を使用することをお勧めします。
  • Q: JSON データは変更できますか?
A: JSONPath は読み取りのみ可能で、変更できません。これを変更するには、まずオブジェクトに解析し、変更後にシリアル化する必要があります。
  • Q: パフォーマンスはどうですか?
A: 単純な式は高速です。複雑な再帰検索 ($..name など) は、大きな JSON では遅くなる可能性があります。パスを明確にすることをお勧めします。
  • Q: NULL 値またはフィールドが欠落している場合はどうすればよいですか?
A: ?() を使用します。フィルター:
$.data.orders[?(@.amount)]
金額フィールドのある注文のみを返します。

完全な例

API 応答データ (簡易バージョン):
{
  "data": {
    "products": [
      {"id": 1, "name": "iPhone", "price": 999, "inStock": true},
      {"id": 2, "name": "MacBook", "price": 1999, "inStock": false},
      {"id": 3, "name": "iPad", "price": 799, "inStock": true}
    ]
  }
}
すべての在庫製品名を抽出:
$.data.products[?(@.inStock==true)].name
结果:["iPhone","iPad"]
複雑な JSON データを処理する必要がありますか? JSONPath Tester で式をリアルタイムでテストします。ツールマニア向け。