igoldchluk

igoldchluk

JSONPath - RFC9535 compliant JSON Path library

Hi everyone

I needed a way to evaluate arbitrary JSON Path expressions, and I could not find any existing library that was fully complaint with RFC-9535. The two most popular libraries I found (ExJsonPath and Warpath) predate the RFC and, while sufficient for most common cases, they still contained some incompatible behavior, so I decided to implement a new one from scratch.

Introducing JSONPath, an RFC-9535 compliant JSON Path query evaluator.

Features

  • Passes 100% of the JSONPath Compliance Test Suite.
  • Supports all function extensions: length, count, match, search, value.
  • No external dependencies.
  • Does not support additional function extensions, for example sum, common in pre RFC9535 implementations.
  • Does not support atom keys.

The only discrepancy with RFC9535 is regarding regular expressions. For match and search, the standard expects I-RegExp style expressions, while in JSONPath library any valid Elixir regular expression are accepted.

If you need any of the non-standarised functions/behaviors I would recommend to use any of the pre-RFC libraries. If you need to follow the standard as strictly as possible then consider giving JSONPath a try :grinning_face:

Basic usage

document = [
      %{"name" => "Alice", "age" => 20},
      %{"name" => "Bob", "age" => 30},
      %{"name" => "Charlie", "age" => 25}
    ]
query = "$[?@.age < 27].name"
JSONPath.evaluate(document, query)
# {:ok, ["Alice", "Charlie"]}

Links

Most Liked

krasenyp

krasenyp

That’s a great feature but I have a question. Do you think encoding the different result formats in a single struct makes sense? Changing the return type through a flag argument is a smell in my opinion.

krasenyp

krasenyp

Congratulations on the release. Do you plan on implementing the ability to validate JSON Path expressions at compile time?

Edit:
I ask because there are PostgreSQL functions which work with JSON Path and it’d be cool to write Ecto helpers which can, at compile time, tell you “hey, this path is wrong”.

igoldchluk

igoldchluk

New version 0.3 released

JSONPath.evaluate/3 now takes an optional 3rd argument to specify the returned type. Possible values are:

  • :values - Returns the node values, same as previous versions
  • :paths - Returns the normalized paths
  • :values_and_paths - Returns a list of 2-element tuples {node_value, normalized_path}

Examples:

root = %{"people" => [%{"name" => "Alice", "age" => 20}, %{"name" => "Bob", "age" => 30}]}
query = "$.people[?@.age > 25]"
JSONPath.evaluate(root, query, :values)
# {:ok, [%{"name" => "Bob", "age" => 30}]}

JSONPath.evaluate(root, query, :paths)
# {:ok, ["$['people'][1]"]}

JSONPath.evaluate(root, query, :values_and_paths)
#{:ok, [{%{"name" => "Bob", "age" => 30}, "$['people'][1]"}]}

Where Next?

Popular in Announcing Top

martinthenth
Hello everybody :wave: Recently, some of my colleagues talked about database ids and uuids and their problems, and I remembered the pain...
New
pkrawat1
Presenting Aviacommerce, open source e-commerce platform in Elixir Aviacommerce is an open source e-commerce platform in Elixir. We at...
New
ostinelli
Let’s write a database! Well not really, but I think it’s a little sad that there doesn’t seem to be a simple in-memory distributed KV da...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
Crowdhailer
Experimenting with this code. OK.try do user &lt;- fetch_user(1) cart &lt;- fetch_cart(1) order = checkout(cart, user) save_orde...
New
Qqwy
Hello everyone, I wrote a small library today called MapDiff. It returns a map listing the (smallest amount of) changes to get from map...
New
mindok
What is ContEx? A pure Elixir server-side data plotting/charting library outputting SVG. It has nice barcharts in particular and works g...
New
woylie
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries. offset-based pagination with...
New
trisolaran
Hi! :waving_hand: I would like to present LiveSelect, a little library that I wrote to easily add a dynamic selection input to your LV f...
198 10858 107
New
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

We're in Beta

About us Mission Statement