Elixpath (elixpath v0.1.0)
Extract data from nested Elixir data structure using JSONPath-like path expressions.
See this page for syntax.
Examples
# string
iex> Elixpath.query(%{:a => 1, "b" => 2}, ~S/."b"/)
{:ok, [2]}
# you can use Elixpath.get! if you want only a single match
iex> Elixpath.get!(%{:a => 1, "b" => 2}, ".*")
1
# unquoted string
iex> Elixpath.query(%{:a => 1, "b" => 2}, ".b")
{:ok, [2]}
# no match
iex> Elixpath.query(%{:a => 1, "b" => 2}, ".nonsense")
{:ok, []}
# no match w/ get!
iex> Elixpath.get!(%{:a => 1, "b" => 2}, ".nonsense", _default = :some_default_value)
:some_default_value
# atom
iex> Elixpath.query(%{:a => 1, "b" => 2}, ".:a")
{:ok, [1]}
# integer
iex> Elixpath.query(%{:a => [%{b: 2}, %{c: 3}]}, ".:a[-1]")
{:ok, [%{c: 3}]}
# descendant
iex> Elixpath.query(%{:a => [%{b: 2}, %{c: 3}]}, "..:c")
{:ok, [3]}
# wildcard
iex> Elixpath.query(%{:a => [%{b: 2}, %{c: 3}]}, ".*.*.*")
{:ok, [2, 3]}
# enable sigil_p/2, which parses Elixpath at compile time.
iex> import Elixpath
iex> Elixpath.query(%{:a => [%{b: 2}, %{c: 3}]}, ~p".:a.1.:c")
{:ok, [3]}
# path syntax error for normal string is detected at runtime.
iex> Elixpath.query(%{:a => [%{b: 2}, %{c: 3}]}, ".:atom:syntax:error")
{:error, "expected member_expression while processing path"}
# while sigil_p raises a compilation error:
# iex> Elixpath.query(%{:a => [%{b: 2}, %{c: 3}]}, ~p".:atom:syntax:error")
# == Compilation error in file test/elixpath_test.exs ==
# ** (Elixpath.Parser.ParseError) ...
Link to this section Summary
Types
Elixpath, already compiled by Elixpath.Parser.parse/2
or sigil_p/2
.
Functions
Get single data from nested data structure.
Returns default
when no match.
Raises on error.
Query data from nested data structure.
Returns list of matches, wrapped by :ok
.
When no match, {:ok, []}
is returned.
Compiles string to internal Elixpath representation.
Converts Elixpath to string.
Also available via Kernel.to_string/1
.
Link to this section Types
Specs
t() :: %Elixpath{path: [Elixpath.PathComponent.t()]}
Elixpath, already compiled by Elixpath.Parser.parse/2
or sigil_p/2
.
Link to this section Functions
get!(data, path_or_str, default \\ nil, opts \\ [])
Specs
get!(data :: term(), t() | String.t(), default, [Elixpath.Parser.option()]) :: term() | default | no_return() when default: term()
Get single data from nested data structure.
Returns default
when no match.
Raises on error.
query(data, path_or_str, opts \\ [])
Specs
query(data :: term(), t() | String.t(), [Elixpath.Parser.option()]) :: {:ok, [term()]} | {:error, reason :: term()}
Query data from nested data structure.
Returns list of matches, wrapped by :ok
.
When no match, {:ok, []}
is returned.
Options
For path parsing options, see Elixpath.Parser.parse/2
.
query!(data, path, opts \\ [])
Specs
Query data from nested data structure.
Same as query/3
, except that query!/3
raises on error.
Returns []
when no match.
Compiles string to internal Elixpath representation.
Warning: Do not specify unsafe_atom
modifier (u
) for untrusted input.
See String.to_atom/1
, which this function uses to create new atom, for details.
Modifiers
unsafe_atom
(u) - passesunsafe_atom: true
option toElixpath.Parser.parse/2
.atom_keys_preferred
(a) - passesprefer_keys: :atom
option toElixpath.Parser.parse/2
.
Examples
iex> import Elixpath, only: [sigil_p: 2]
iex> ~p/.string..:b[1]/
#Elixpath<[elixpath_child: "string", elixpath_descendant: :b, elixpath_child: 1]>
iex> ~p/.atom..:b[1]/a
#Elixpath<[elixpath_child: :atom, elixpath_descendant: :b, elixpath_child: 1]>
stringify(path)
Specs
Converts Elixpath to string.
Also available via Kernel.to_string/1
.
This function is named stringify/1
to avoid name collision
with Kernel.to_string/1
when the entire module is imported.
Examples
iex> import Elixpath, only: [sigil_p: 2]
iex> path = ~p/.1.child..:decendant/u
#Elixpath<[elixpath_child: 1, elixpath_child: "child", elixpath_descendant: :decendant]>
iex> path |> to_string()
"[1].\"child\"..:decendant"
iex> "interpolation: #{~p/..1[*]..*/}"
"interpolation: ..[1].*..*"