JSONPath is a query language for JSON, similar to XPath for XML. It lets you extract and filter specific parts of a JSON document using path expressions.
This is a real-world e-commerce user data JSON:
{
  "users": [
    {
      "id": 1,
      "name": "Alice",
      "email": "alice@example.com",
      "roles": ["admin", "editor"],
      "orders": [
        { "id": 1001, "amount": 250, "status": "shipped" },
        { "id": 1002, "amount": 120, "status": "processing" }
      ]
    },
    {
      "id": 2,
      "name": "Bob",
      "email": "bob@example.com",
      "roles": ["viewer"],
      "orders": [
        { "id": 1003, "amount": 300, "status": "shipped" }
      ]
    },
    {
      "id": 3,
      "name": "Charlie",
      "email": "charlie@example.com",
      "roles": [],
      "orders": []
    }
  ]
}Query:
$
Goal: Select the full root JSON object.
Result:
{ "users": [...] }Query:
$.users[*].name
Goal: Fetch the name field of every user in the array.
Result:
["Alice", "Bob", "Charlie"]Query:
$.users[0]
Goal: Return the first user in the users array.
Result:
{
  "id": 1,
  "name": "Alice",
  ...
}Query:
$.users[-1:].name
Goal: Return the name of the last user.
Result:
["Charlie"]Query:
$.users[?(@.roles.length == 0)].name
Goal: Return names of users where the roles array is empty.
Result:
["Charlie"]Query:
$..orders[?(@.amount > 200)].id
Goal: Get IDs of orders where amount > 200.
Result:
[1001, 1003]Query:
$..orders[?(@.status == 'shipped')]
Goal: Return order objects where status is "shipped".
Result:
[ 
  { "id": 1001, "amount": 250, "status": "shipped" },
  { "id": 1003, "amount": 300, "status": "shipped" }
]Query:
$..orders[*].amount
Goal: List the amount of every order from all users.
Result:
[250, 120, 300]Query:
$..orders[0]
Goal: Return the first order from each user's orders array (if any).
Result:
[ 
  { "id": 1001, "amount": 250, "status": "shipped" },
  { "id": 1003, "amount": 300, "status": "shipped" }
]Query:
$..[?(@.email)]
Goal: Filter and return only objects that contain an email key.
Result:
[ 
  { "id": 1, "name": "Alice", "email": "alice@example.com", ... },
  { "id": 2, "name": "Bob", "email": "bob@example.com", ... },
  { "id": 3, "name": "Charlie", "email": "charlie@example.com", ... }
]Query:
$.users[?(@.roles.indexOf('admin') != -1)].name
Goal: Return names of users who have the admin role in their roles array.
Result:
["Alice"]Query:
$..orders[?(@.status =~ /ship/i)]
Goal: Use regex to find all orders whose status contains "ship" (case-insensitive).
Result:
[ 
  { "id": 1001, "amount": 250, "status": "shipped" },
  { "id": 1003, "amount": 300, "status": "shipped" }
]
β οΈ Note: Regex filters like=~are supported injsonpath-plus,Jayway, but not all engines.
Query:
$.users[?(
  @.orders[?(@.status == 'shipped')] &&
  @.orders[?(@.status == 'processing')]
)]
Goal:
Return user objects where the user has both shipped and processing orders.
Result:
[ 
  {
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com",
    "roles": ["admin", "editor"],
    "orders": [
      { "id": 1001, "amount": 250, "status": "shipped" },
      { "id": 1002, "amount": 120, "status": "processing" }
    ]
  }
]Query:
$..orders[?(@.status == 'shipped' || @.status == 'processing')]
Goal:
Return only the order objects where the status is either shipped or processing.
Result:
[ 
  { "id": 1001, "amount": 250, "status": "shipped" },
  { "id": 1002, "amount": 120, "status": "processing" },
  { "id": 1003, "amount": 300, "status": "shipped" }
]Query:
$..orders[?(@.status == 'shipped' || @.status == 'processing')]
Goal:
Return only the order objects that have a status of either shipped or processing.
Explanation:
- The ||(OR) operator is used to ensure that thestatusof the order matches eithershippedorprocessing.
- This query filters out all orders that do not meet either of these two conditions.
Result:
[
  { "id": 1001, "amount": 250, "status": "shipped" },
  { "id": 1002, "amount": 120, "status": "processing" },
  { "id": 1003, "amount": 300, "status": "shipped" }
]Explanation:
- The query returns all orders with a status of shippedorprocessing, regardless of which user made them.
- All three orders are returned, as their statuses are either shippedorprocessing.
| Syntax | Description | 
|---|---|
| $ | Root of the document | 
| . | Child element | 
| .. | Recursive search | 
| [*] | All elements | 
| [n] | Array index | 
| [-1:] | Slice (e.g., last item) | 
| [?(@.key)] | Filter: has property | 
| [?(@.key == value)] | Filter: equals | 
| [?(@.array.length == 0)] | Filter: empty array | 
| [?(@.status =~ /.../)] | Regex filter | 
| @ | Refers to current node in filter | 
For .NET developers working with JSONPath, there are a couple of tools you can use:
- Description: A .NET library for querying JSON data using JSONPath expressions.
- GitHub Repository: JsonPath.Net GitHub
- NuGet Package: JsonPath.Net NuGet
Usage Example (C#):
using JsonPath;
var json = @"{
    'users': [
        { 'name': 'Alice', 'age': 30 },
        { 'name': 'Bob', 'age': 25 }
    ]
}";
var path = "$.users[?(@.age > 26)]";
var result = JsonPath.Parse(json).SelectTokens(path);- Description: While Newtonsoft.Jsonis primarily known for JSON parsing and manipulation in .NET, it also supports JSONPath queries using theSelectToken()method.
- NuGet Package: Newtonsoft.Json NuGet
Usage Example (C#):
using Newtonsoft.Json.Linq;
var json = @"{
    'users': [
        { 'name': 'Alice', 'age': 30 },
        { 'name': 'Bob', 'age': 25 }
    ]
}";
var jObject = JObject.Parse(json);
var result = jObject.SelectTokens("$.users[?(@.age > 26)]");
foreach (var item in result)
{
    Console.WriteLine(item);
}Note: Newtonsoft.Json is a very popular library for working with JSON in .NET, and its built-in support for JSONPath makes it easy to perform queries on JSON data.
- Description: JPath is another JSONPath library designed specifically for .NET.
- GitHub Repository: JPath GitHub
- NuGet Package: JPath NuGet
Usage Example:
using JPath;
using Newtonsoft.Json.Linq;
var json = @"{
    'users': [
        { 'name': 'Alice', 'age': 30 },
        { 'name': 'Bob', 'age': 25 }
    ]
}";
var jObject = JObject.Parse(json);
var result = jObject.SelectTokens("$.users[?(@.age > 26)]");
foreach (var item in result)
{
    Console.WriteLine(item);
}- 
For most .NET developers, the Newtonsoft.Json library is the go-to choice due to its extensive functionality, wide usage, and built-in JSONPath support through the SelectTokens()method. It's a versatile and robust library for working with JSON in .NET.
- 
If you prefer a dedicated JSONPath implementation with an API tailored for querying JSON, you can consider JsonPath.Net or JPath. 
- https://jsonpath.com
- https://jsonformatter.org/jsonpath
- NPM: jsonpath-plus
- Python: jsonpath-ng
- Java: Jayway JSONPath