Documentation
¶
Overview ¶
Package jsonpath implements RFC 9535 JSONPath query expressions.
Example ¶
Select all the authors of the books in a bookstore object.
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/theory/jsonpath"
)
func main() {
// Parse a jsonpath query.
p, err := jsonpath.Parse(`$.store.book[*].author`)
if err != nil {
log.Fatal(err)
}
// Select values from unmarshaled JSON input.
store := bookstore()
result := p.Select(store)
// Show the result.
items, err := json.Marshal(result)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", items)
}
// bookstore returns an unmarshaled JSON object.
func bookstore() any {
src := []byte(`{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 399
}
}
}`)
var value any
if err := json.Unmarshal(src, &value); err != nil {
log.Fatal(err)
}
return value
}
Output: ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ErrPathParse = parser.ErrPathParse
ErrPathParse errors are returned for path parse errors.
Functions ¶
This section is empty.
Types ¶
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser parses JSONPath strings into [*Path]s.
Example ¶
Use the Parser to parse a collection of paths.
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/theory/jsonpath"
)
func main() {
// Create a new parser using the default function registry.
parser := jsonpath.NewParser()
// Parse a list of paths.
paths := []*jsonpath.Path{}
for _, path := range []string{
"$.store.book[*].author",
"$..author",
"$.store..color",
"$..book[2].author",
"$..book[2].publisher",
"$..book[[email protected]].title",
"$..book[[email protected]<10].title",
} {
p, err := parser.Parse(path)
if err != nil {
log.Fatal(err)
}
paths = append(paths, p)
}
// Later, use the paths to select from JSON inputs.
store := bookstore()
for _, p := range paths {
items := p.Select(store)
array, err := json.Marshal(items)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", array)
}
}
// bookstore returns an unmarshaled JSON object.
func bookstore() any {
src := []byte(`{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 399
}
}
}`)
var value any
if err := json.Unmarshal(src, &value); err != nil {
log.Fatal(err)
}
return value
}
Output: ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"] ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"] ["red"] ["Herman Melville"] [] ["Moby Dick","The Lord of the Rings"] ["Sayings of the Century","Moby Dick"]
Example (FunctionExtension) ¶
The second use case for the Parser is to provide a registry.Registry containing function extensions, as defined by the standard. This example creates a function named "first" that returns the first item in a list of nodes.
package main
import (
"errors"
"fmt"
"log"
"github.com/theory/jsonpath"
"github.com/theory/jsonpath/registry"
"github.com/theory/jsonpath/spec"
)
func main() {
// Register the first function.
reg := registry.New()
err := reg.Register(
"first", // name
spec.FuncValue, // returns a single value
validateFirstArgs, // parse-time validation defined below
firstFunc, // function defined below
)
if err != nil {
log.Fatalf("Error %v", err)
}
// Create a parser with the registry that contains the extension.
parser := jsonpath.NewParser(jsonpath.WithRegistry(reg))
// Use the function to select lists that start with 6.
path, err := parser.Parse("$[? first(@.*) == 6]")
if err != nil {
log.Fatalf("Error %v", err)
}
// Do any of these arrays start with 6?
input := []any{
[]any{1, 2, 3, 4, 5},
[]any{6, 7, 8, 9},
[]any{4, 8, 12},
}
result := path.Select(input)
fmt.Printf("%v\n", result)
}
// validateFirstArgs validates that a single argument is passed to the first()
// function, and that it can be converted to [spec.PathNodes], so that first()
// can return the first node. It's called by the parser.
func validateFirstArgs(fea []spec.FunctionExprArg) error {
if len(fea) != 1 {
return fmt.Errorf("expected 1 argument but found %v", len(fea))
}
if !fea[0].ResultType().ConvertsTo(spec.PathNodes) {
return errors.New("cannot convert argument to PathNodes")
}
return nil
}
// firstFunc defines the custom first() JSONPath function. It converts its
// single argument to a [spec.NodesType] value and returns a [*spec.ValueType]
// that contains the first node. If there are no nodes it returns nil.
func firstFunc(jv []spec.JSONPathValue) spec.JSONPathValue {
nodes := spec.NodesFrom(jv[0])
if len(nodes) == 0 {
return nil
}
return spec.Value(nodes[0])
}
Output: [[6 7 8 9]]
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
Path represents a RFC 9535 JSONPath query.
func Parse ¶
Parse parses path, a JSONPath query string, into a Path. Returns an ErrPathParse on parse failure.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package parser parses RFC 9535 JSONPath queries into parse trees.
|
Package parser parses RFC 9535 JSONPath queries into parse trees. |
|
Package registry provides a RFC 9535 JSONPath function registry.
|
Package registry provides a RFC 9535 JSONPath function registry. |
|
Package spec provides object definitions and execution for RFC 9535 JSONPath query expressions.
|
Package spec provides object definitions and execution for RFC 9535 JSONPath query expressions. |
Click to show internal directories.
Click to hide internal directories.