Welcome to Part 4 of our JSON tutorial series. Having learned about JSON’s basics (Part 1: Understanding JSON), best practices and conventions (Part 2: Best Practices & Conventions) and advanced data structures(Part 3: Advanced Data Structures in JSON), we now turn our attention to accessing and manipulating this data. Efficiently extracting specific pieces of information or transforming JSON documents is crucial for many applications.
Accessing Specific Parts of a JSON Document
When working with complex JSON documents, you often need to pinpoint a particular value or a set of values within the structure. Manually traversing large JSON objects or arrays in code can be cumbersome and error-prone.
Topics covered in this article:
- Navigating JSON with JSON Pointer (RFC 6901)
- Querying JSON with JSONPath
- Programmatic Access and Transformation
Navigating JSON with JSON Pointer (RFC 6901)
JSON Pointer is a standardized string syntax used to identify a specific value within a JSON document. Think of it as an address to a particular piece of data.
What is JSON Pointer?
A JSON Pointer string consists of a sequence of zero or more tokens, each prefixed by a / character. These tokens represent keys in objects or indices in arrays.
Syntax
- Tokens are separated by /.
- An empty JSON pointer expression refers to the entire document.
- To represent a literal ~ character in a token, use ~0.
- To represent a literal / character in a token, use ~1.
- A pointer like /foo/4 means: access the key “foo” in the root object, then access the element at index 4 of the array that is the value of “foo”. Indexes are 0 based.
Examples
Let’s use the following JSON document for our examples:
{
"storeName": "My Awesome Gadgets",
"locations": [
{
"city": "Techville",
"zipCode": "98765"
},
{
"city": "Steamville",
"zipCode": "12345"
}
]
"contact/email": "info@example.com",
"numberOfEmplyees": 4
}
Here are some JSON Pointers and the values they would resolve to:
| JSON Pointer | Value Resolved |
| “” | The entire document itself |
| “/storeName” | “My Awesome Gadgets” |
| “/locations/0/city” | “Techville” |
| “/locations/1” | { “city”: “Steamville”, “zipCode”: “12345” } |
| “/locations” | [ { “city”: “Techville”, “zipCode”: “98765” }, { “city”: “Steamville”, “zipCode”: “12345” } ] |
| “/numberOfEmplyeesemplomanager” | 4 |
| “/contact~1email” | “info@example.com” (resolves to key “contact/email”) |
| “/products/2” | Error (index out of bounds) |
| “/nonExistentKey” | Error (key does not exist) |
Use Cases
JSON Pointers are particularly useful in:
- JSON Schema: The $ref keyword often uses JSON Pointers to reference other parts of a schema document (e.g., “$ref”: “#/definitions/address”).
- JSON Patch: Operations like “add”, “remove”, or “replace” use JSON Pointers to specify where in the document the patch should be applied.
- API Design: For identifying specific fields within a larger JSON payload.
JSON Pointer provides a standardized and unambiguous way to address specific values. This is crucial for tools and specifications that need to refer to parts of a JSON document reliably. Unlike more complex query languages, a JSON Pointer always resolves to a single value or indicates an error if the path is invalid; it doesn’t return multiple results.
Querying JSON with JSONPath
While JSON Pointer is for addressing a single specific value, JSONPath is an expression language designed for selecting and extracting data from a JSON document. It’s conceptually similar to XPath for XML.
What is JSONPath?
JSONPath expressions allow you to navigate through the JSON structure and retrieve multiple values based on various criteria, such as key names, array indices, or conditions on values.
Important Note: Unlike JSON Pointer, JSONPath does not have a single, universally agreed-upon formal standard. This means that different implementations might have slight variations in supported syntax or behavior. However, a common set of features is generally supported.
Key Syntax Elements (Commonly Supported)
- $ : The root object in the JSON document. All JSONPath expressions start with this.
- . or “ (Dot notation or Bracket notation): Child operator.
- $.store.books
- $[‘store’][‘books’] (Bracket notation is useful for keys with special characters or spaces).
- .. : Recursive descent. Searches for the specified key name at any level of nesting.
- $.store..price (Finds all price keys under store and its descendants).
- [] : Subscript operator.
- Array indices: $.store.books[0] (First book).
- Array indices: $.store.books[-1] (Last book).
- Array indices: $.store.books[*] (all books).Array slice (support varies): $.store.books[2:10:3] (The parameters are [start:end:step], so this will start at index 2, and then return every 3rd item where the index is less than 10, so it will return index 2, 5, 8).
- Array stepped slice : $.store.books[:10:3] (if a parameter is omitted then it is defaulted start=0, end=-1, step=1, so [:10:3] is the same as [1:10:3]).
- Array slices : $.store.books[0:2] (The books at index 0 & 1).
- Union of multiple indices/keys: $.store.books[2,4].title (The title of the books at index 2 and 4).
- Union of multiple indices/keys: $.store.books[0,3:5].title (The title of the books at index 0 and 3,4).
- * : Wildcard. Selects all elements within an object or array.
- $.store.books[*].author (Selects all authors of all books in the store).
- $.store.* (Selects all properties authors on the store object).
- ?() : Filter expression. Allows selecting elements based on a condition. The @ symbol represents the current item being processed.
- $.store.book[?(@.price < 10)] (All books with price less than 10).
- $.store.book[?(@.isbn)] (All books that have an ISBN property).
| JSONPath Filter Expression | Description |
| $ or @ | nested JSONPath (returns true if any match exists; otherwise, returns false) |
| =, !=, >=, <= >, < | binary operator, where left- and right-hand operands are nested JSONPaths or JSON values (returns true if any match exists; otherwise, returns false) |
| and, or, not | Boolean operator, where operands are JSONPath filter expressions |
| contains | Checks if a string contains the specified substring (case-sensitive), or an array contains the specified element. |
| ( … ) | parentheses |
Functions:
The following built in functions can be used within the expressions.
length, count, match, search, value
Support for these varies between implementation, but the following are typically implemented.
See RFC9535 for details
Examples
Let’s use this JSON document for JSONPath examples:
{
"library": {
"name": "City Central Library",
"location": "123 Main Street, Anytown",
"books": [
{
"title": "The Hitchhiker's Guide to the Galaxy",
"author": "Douglas Adams",
"genre": "Fiction",
"publication_year": 1979,
"is_available": true
},
{
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"genre": "Classic",
"publication_year": 1925,
"is_available": false
},
{
"title": "The Hobbit",
"author": "J.R.R. Tolkien",
"genre": "Fantasy",
"publication_year": 1937,
"is_available": true
},
{
"title": "To Kill a Mockingbird",
"author": "Harper Lee",
"genre": "Fiction",
"publication_year": 1960,
"is_available": true
}
]
}
}
Here are some JSONPath expressions and their likely results (syntax based on common implementations):
| JSONPath Expression | Description |
| $.library.book[*].author | [ “Douglas Adams”, “F. Scott Fitzgerald”, “J.R.R. Tolkien”, “Harper Lee” ] |
| $.library.books[0].title | [ “The Hitchhiker’s Guide to the Galaxy” ] |
| $.library.books[?(@.is_available == true)].title | [ “The Hitchhiker’s Guide to the Galaxy”, “The Hobbit”, “To Kill a Mockingbird” ] |
| $..genre | [ “Fiction”, “Classic”, “Fantasy”, “Fiction” ] |
| $.library.books[?(length(@.title) > 25)].title | [ “The Hitchhiker’s Guide to the Galaxy” ] |
JSONPath offers a powerful and flexible way to query JSON data, especially when dealing with complex or variable structures. Its ability to filter and select multiple elements makes it invaluable for data extraction and transformation tasks. However, because there isn’t one single, authoritative JSONPath standard, developers should be mindful of the specific implementation they are using, as features like script expressions, slice notation, or even some filter operators can vary. This lack of a unified standard is a key difference from the more rigidly defined JSON Pointer. Development environments like Liquid Studio include tools to help test and debug JSONPath expressions against your data.
Programmatic Access and Transformation
Beyond specialized query languages, JSON data is most commonly accessed and manipulated directly within programming languages using built-in modules or third-party libraries.3
Common Libraries
- JavaScript:
- Natively supports JSON through the global objects.
- JSON.parse(jsonString): Converts a JSON string into a JavaScript object or array.4
- JSON.stringify(value): Converts a JavaScript value (object, array, etc.) into a JSON string.
- Python:
- Uses the built-in json module.
- json.loads(json_string): Parses a JSON string into Python dictionaries, lists, etc..21
- json.dumps(python_object): Serializes a Python object into a JSON formatted string.
- Java: Libraries like Jackson, Gson, and org.json are popular.
- C#:(System.Text.Json) (built-in) or(NewtonSoft.Json).
- PHP: json_decode() and json_encode().
Summary & What’s Next
In this part, we’ve explored various methods for querying and transforming JSON data. JSON Pointer offers a standard way to address specific values, while JSONPath provides powerful querying capabilities for extracting data. Most commonly, however, JSON is manipulated programmatically using built-in language features and libraries.
Understanding these techniques is essential for effectively working with the JSON data that flows through modern applications. As you work with querying and transforming JSON, remember that powerful tools can simplify these tasks. Liquid Technologies provides resources and tools like Liquid Studio and a JSON Editor that can aid in efficiently handling JSON data.
In the our next series, we’ll be doing a detail JSON Schema Tutorial, a vocabulary for describing the structure and constraints of JSON documents, enabling robust validation and documentation.
Navigate This Series:
- Part 1: Introduction to JSON
- Part 2: JSON Best Practices and Conventions
- Part 3: Advanced Data Structures in JSON
- Part 4: Querying and Transforming JSON Data (This post)

