JsonpathToAccess (jsonpath_to_access v0.1.0)
This module provides a function to convert a JSONPath expression into an access path. This library does not support all of jsonpath:
- the
..
operator is not supported because it can't be expressed using Access functions (that I know of) - all the functions like length for the same reason as above
There are two main methods:
Convert the JSONPath expression into an access path. This function is used by the get_in/2
function.
You have to specify upfront if the data contains atom keys or not.
You can cache or put the convert in a module attribute.
iex> path = JsonpathToAccess.convert!("$.store.book[0].author", to_atoms: true)
iex> JsonpathToAccess.get_in(%{store: %{book: [%{author: "Gandalf"}]}}, path)
"Gandalf"
defmodule MyModule do
@json_path JsonpathToAccess.convert!("$.store.book[0].author")
def my_lookup(data) do
# or you can use the normal get_in if you don't use absolute path filter.
JsonpathToAccess.get_in(data, @json_path)
end
end
Just lookup the value in a map using the JSONPath expression.
iex> JsonpathToAccess.lookup(%{store: %{book: [%{author: "Gandalf"}]}}, "$.store.book[0].author")
{:ok, "Gandalf"}
Summary
Functions
Converts a JSONPath into an Access path.
This can be used later with the JsonpathToAccess.get_in/2
function.
Converts a JSONPath into an Access path.
This can be used later with the JsonpathToAccess.get_in/2
function.
The missing fetch_in
function from Kernel
.
Similar to Kernel.get_in/2
, but it resolves the absolute values.
Looks up data using a JSONPath.
Types
access_path()
@type access_path() :: list()
operator()
@type operator() ::
:equals | :not_equals | :lesser | :greater | :lesser_equals | :greater_equals
options()
@type options() :: keyword()
Functions
convert(jsonpath, opts \\ [])
@spec convert(binary(), options()) :: {:ok, access_path()} | {:error, binary()}
Converts a JSONPath into an Access path.
This can be used later with the JsonpathToAccess.get_in/2
function.
iex> {:ok, access_path} = JsonpathToAccess.convert("$.a.b")
iex> JsonpathToAccess.get_in(%{"a" => %{"b" => "value"}}, access_path)
"value"
iex> {:ok, access_path} = JsonpathToAccess.convert("$.a.b", to_atoms: true)
iex> JsonpathToAccess.get_in(%{a: %{b: "value"}}, access_path)
"value"
convert!(jsonpath, opts \\ [])
@spec convert!(binary(), options()) :: access_path()
Converts a JSONPath into an Access path.
This can be used later with the JsonpathToAccess.get_in/2
function.
iex> access_path = JsonpathToAccess.convert!("$.a.b")
iex> JsonpathToAccess.get_in(%{"a" => %{"b" => "value"}}, access_path)
"value"
iex> access_path = JsonpathToAccess.convert!("$.a.b", to_atoms: true)
iex> JsonpathToAccess.get_in(%{a: %{b: "value"}}, access_path)
"value"
fetch_in(data, keys)
The missing fetch_in
function from Kernel
.
Probably not exactly what you want, internally used for looking up if a value exists in a nested map.
get_in(data, access)
@spec get_in(Access.t(), access_path()) :: term() | nil
Similar to Kernel.get_in/2
, but it resolves the absolute values.
lookup(data, jsonpath)
Looks up data using a JSONPath.
iex> JsonpathToAccess.lookup(%{"a" => %{"b" => 1}}, "$.a.b")
{:ok, 1}
iex> JsonpathToAccess.lookup(%{a: %{b: 1}}, "$.a.b")
{:ok, 1}
iex> JsonpathToAccess.lookup([a: [[b: 1], [b: 2], [b: 3]]], "$.a[?(@.b >= 2)].b")
{:ok, [2, 3]}