1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
# aeson-jsonpath
[](https://github.com/taimoorzaeem/aeson-jsonpath/actions/workflows/build.yml) [](https://hackage.haskell.org/package/aeson-jsonpath) [](https://www.patreon.com/taimoorzaeem) [](https://github.com/taimoorzaeem/aeson-jsonpath/actions/workflows/compliance.yml)
Run [RFC 9535](https://www.rfc-editor.org/rfc/rfc9535) compliant JSONPath queries on [Data.Aeson](https://hackage.haskell.org/package/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] Normalized Paths
- [ ] Function Extensions
I have decided not to implement Function Extension yet. Please open an issue or discussion if you'd like to see them implemented.
## Quick Start
```haskell
{-# 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
```haskell
{-# 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": "Laurence Anyways",
"director": "Xavier Dolan",
"year": 2012
}
]
}
}|]
```
### Child Segment
```haskell
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
```haskell
-- get all values with key "director", recursively
ghci> query "$..director" json
Right [
String "Panos Cosmatos",
String "Xavier Dolan"
]
```
### Slice Selector
```haskell
ghci> query "$[2:5]" [aesonQQ| [1,2,3,4,5,6] |]
Right [
Number 3.0,
Number 4.0,
Number 5.0
]
```
### Filter Selector
```haskell
ghci> query "$.shop.movies[?@.year < 2015]" json
Right [
Object (fromList [
("director",String "Xavier Dolan"),
("title",String "Laurence Anyways"),
("year",Number 2012.0)
])
]
ghci> queryLocated "$.shop.movies[?@.director == '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.
```haskell
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](https://github.com/jsonpath-standard/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.
|