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

t()

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.

Query data from nested data structure. Same as query/3, except that query!/3raises on error. Returns [] when no match.

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

Link to this function

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.

Link to this function

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.

Link to this function

query!(data, path, opts \\ [])

Specs

query!(data :: term(), t() | String.t(), [Elixpath.Parser.option()]) ::
  [term()] | no_return()

Query data from nested data structure. Same as query/3, except that query!/3raises on error. Returns [] when no match.

Link to this macro

sigil_p(arg, modifiers)

(macro)

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

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]>
Link to this function

stringify(path)

Specs

stringify(t()) :: String.t()

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].*..*"