aeson-jsonpath

Parse and run JSONPath queries on Aeson documents

https://github.com/taimoorzaeem/aeson-jsonpath

Version on this page:0.3.0.1
LTS Haskell 23.22:0.2.0.0
Stackage Nightly 2025-05-15:0.3.0.2
Latest on Hackage:0.3.0.2

See all snapshots aeson-jsonpath appears in

MIT licensed by Taimoor Zaeem
Maintained by Taimoor Zaeem
This version can be pinned in stack with:aeson-jsonpath-0.3.0.1@sha256:0b007506647136c2f1d8d104fe0d31894a4a5ecafb54299c0fef294608f04377,2764

aeson-jsonpath

ci-badge hackage-docs Donate Compliance

Run RFC 9535 compliant JSONPath queries on Data.Aeson.

Roadmap

  • [x] Selectors
    • [x] Name Selector
    • [x] Index Selector
    • [x] Slice Selector
    • [x] Wildcard Selector
    • [x] Filter Selector
  • [x] Segments
    • [x] Child Segment
    • [x] Descendant Segment
  • [x] Node Locations (Normalized Path)
  • [ ] Function Extensions
  • [ ] Setting Values (Non-RFC)

Quick Start

{-# LANGUAGE QuasiQuotes #-}
import Data.Aeson           (Value (..))
import Data.Aeson.QQ.Simple (aesonQQ)
import Data.Aeson.JSONPath  (query, queryLocated, jsonPath)

track = [aesonQQ| { "artist": "Duster", "title": "Earth Moon Transit" } |]

ghci> query "$.artist" track -- child member shorthand
Right [String "Duster"]

ghci> queryLocated "$.*" track -- child wildcard segment
Right [
  ("$['artist']", String "Duster"),
  ("$['title']", String "Earth Moon Transit")
]

More Examples

{-# LANGUAGE QuasiQuotes #-}
import Data.Aeson           (Value (..))
import Data.Aeson.QQ.Simple (aesonQQ)
import Data.Aeson.JSONPath  (query, queryLocated, jsonPath)

json = [aesonQQ| {
  "shop": {
    "movies": [
      {
        "title": "Mandy",
        "director": "Panos Cosmatos",
        "year": 2018
      },
      {
        "title": "Lawrence Anyways",
        "director": "Xavier Dolan",
        "year": 2012
      }
    ]
  }
}|]

Child Segment

ghci> query "$.shop.movies[0].title" json
Right [String "Mandy"]

ghci> query "$.shop.movies[0].*" json
Right [
  String "Mandy",
  String "Panos Cosmatos",
  Number 2018.0
]

ghci> query "$['shop']['new-movies']" json
Right []

Descendant Segment

-- get all values with key "director", recursively
ghci> query "$..director" json
Right [
  String "Panos Cosmatos",
  String "Xavier Dolan"
]

Slice Selector

ghci> query "$[2:5]" [aesonQQ| [1,2,3,4,5,6] |]
Right [
  Number 3.0,
  Number 4.0,
  Number 5.0
]

Filter Selector

ghci> query "$.shop.movies[[email protected] < 2015]" json
Right [
  Object (fromList [
    ("director",String "Xavier Dolan"),
    ("title",String "Lawrence Anyways"),
    ("year",Number 2012.0)
  ])
]

ghci> queryLocated "$.shop.movies[[email protected] == 'Panos Cosmatos']" json
Right [
  (
    "$['shop']['movies'][0]",
    Object (fromList [
      ("director",String "Panos Cosmatos"),
      ("title",String "Mandy"),
      ("year",Number 2018.0)
    ])
  )
]

QuasiQuoter

The functions queryQQ and queryLocatedQQ can be used with the jsonPath quasi quoter.

queryQQ [jsonPath|$.shop.movies|] json -- compiles successfully

queryQQ [jsonPath|$.shop$$movies|] json -- compilation error, doesn't parse

Testing

It is tested using 10000+ lines test suite given by jsonpath-compliance-test-suite :rocket:.

Note: All tests pass except tests related to function extensions which we have not implemented yet.

Development

Please report any bugs you encounter by opening an issue.

Changes

Change Log

All notable changes to this package are documented in this file. This project adheres to Haskell PVP versioning.

0.3.0.1

  • #31, Fix test/cts.json not included in hackage bundle

0.3.0.0

  • Always return Vector Value
  • Implement Filter Selector
  • Introduce JSONPath Standard Compliance Testing, See: test-suite
  • Add function queryLocated which also returns node locations

0.2.0.0

  • Remove dependency on protolude
  • Fix parsing bug with Wildcard Selector
  • Implement Descendant Segment
  • Fix allowed characters in the member-name-shorthand
  • Add QuasiQuoter for compile-time syntax checking

0.1.0.0

  • Initial Release