JsonPath for Elixir
[!WARNING] This Package is EXPERIMENTAL and in development. It may not be suitable for production use.
A minimal JSONPath engine in Elixir using LEEX + YECC generated modules.
This library supports querying nested maps and lists using JSONPath syntax. It currently implements a partial subset of RFC 9535 and passes 400/702 compliance tests.
Features
-
Child selector (
.) and descendant selector (..) -
Wildcards (
*) for maps and arrays -
Array slices and indices (
[0:2],[-1]) -
Unions (
[0,2]) -
Basic filters (
[?@.price<20]) - Returns paths and values in evaluation
-
Convenience
query/2helper for automatic tokenize → parse → evaluate - Works with Elixir maps and lists
⚠️ Partial implementation: not all RFC 9535 features are implemented yet.
Installation
Add to your mix.exs:
def deps do
[
{:json_path, "~> 0.1.0"}
]
endThen fetch dependencies:
mix deps.getUsage
Basic Queries
data = %{
"store" => %{
"book" => [
%{"title" => "Elixir in Action", "price" => 15},
%{"title" => "Programming Phoenix", "price" => 20}
],
"bicycle" => %{"color" => "red", "price" => 100}
}
}
# Get all book prices
JsonPath.query(data, "$.store.book[*].price")
# => [{"$['store']['book'][0]['price']", 15}, {"$['store']['book'][1]['price']", 20}]
# Get bicycle color
JsonPath.query(data, "$.store.bicycle.color")
# => [{"$['store']['bicycle']['color']", "red"}]Advanced Queries
# Descendant selector
JsonPath.query(data, "$..price")
# => [{"$['store']['book'][0]['price']", 15}, {"$['store']['book'][1]['price']", 20}, {"$['store']['bicycle']['price']", 100}]
# Union selection
JsonPath.query(data, "$.store.book[0,1]")
# => [{"$['store']['book'][0]", ...}, {"$['store']['book'][1]", ...}]
# Array slice
JsonPath.query(data, "$.store.book[0:2]")
# => first two books
# Negative index
JsonPath.query(data, "$.store.book[-1]")
# => last book
# Filter with comparison
JsonPath.query(data, "$..book[?@.price<20]")
# => books with price < 20
# Logical filter (AND/OR)
JsonPath.query(data, "$..book[?@.price>10 && @.price<30]")
# => books with 10 < price < 30Functions
JsonPath.query(data, path_string)
Convenience function to tokenize → parse → evaluate in one call.
- Parameters:
data– Map or List to querypath_string– JSONPath string
- Returns:
-
List of
{path_string, value}or{:error, reason}
-
List of
JsonPath.tokenize(query)
Tokenizes a JSONPath string using the lexer.
- Returns:
{:ok, tokens, line}or{:error, reason}
JsonPath.parse(tokens)
Parses a token list into an AST.
- Returns:
{:ok, ast}or{:error, reason}
JsonPath.evaluate(ast, data)
Evaluates a parsed AST against data.
- Returns: List of
{path_string, value}
Compliance & Coverage
- Partial RFC 9535 implementation
- Passing 400/702 JSONPath compliance tests (link)
- Work in progress for full RFC coverage
Contributing
- Fork the repository
- Implement or improve features
-
Run tests:
mix test - Submit a pull request
License
Apache License 2.0 © Jacob Aronoff