Documentation
¶
Overview ¶
Package spec provides the RFC 9535 JSONPath AST and execution for github.com/theory/jsonpath. It will mainly be of interest to those wishing to implement their own parsers, to convert from other JSON path-style languages, and to implement functions for github.com/theory/jsonpath/registry.
Stability ¶
The following types and constructors are considered stable:
- Index
- Name
- SliceSelector and Slice
- WildcardSelector and Wildcard
- FilterSelector
- Segment and Child and Descendant
- PathQuery and Query
- LocatedNode
- NormalizedPath
The rest of the structs, constructors, and methods in this package remain subject to change, although we anticipate no significant revisions.
Example ¶
Select all the authors of the books in a bookstore object.
package main import ( "encoding/json" "fmt" "log" "github.com/theory/jsonpath" "github.com/theory/jsonpath/spec" ) func main() { // Construct a jsonpath query. p := jsonpath.New(spec.Query( true, spec.Child(spec.Name("store")), spec.Child(spec.Name("book")), spec.Child(spec.Wildcard()), spec.Child(spec.Name("author")), )) // Select values from unmarshaled JSON input. store := bookstore() nodes := p.Select(store) // Show the selected values. items, err := json.Marshal(nodes) 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 ¶
- type BasicExpr
- type CompExpr
- type CompOp
- type CompVal
- type Evaluator
- type ExistExpr
- type FilterSelector
- type FuncExpr
- type FuncExprArg
- type FuncExtension
- type FuncType
- type Index
- type LiteralArg
- type LocatedNode
- type LogicalAnd
- type LogicalOr
- type LogicalType
- type Name
- type NodesType
- type NonExistExpr
- type NormalSelector
- type NormalizedPath
- type NotFuncExpr
- type NotParenExpr
- type ParenExpr
- type PathQuery
- func (q *PathQuery) ConvertsTo(ft FuncType) bool
- func (q *PathQuery) Expression() FuncExprArg
- func (q *PathQuery) ResultType() FuncType
- func (q *PathQuery) Segments() []*Segment
- func (q *PathQuery) Select(current, root any) []any
- func (q *PathQuery) SelectLocated(current, root any, parent NormalizedPath) []*LocatedNode
- func (q *PathQuery) Singular() *SingularQueryExpr
- func (q *PathQuery) String() string
- type PathValue
- type Segment
- type Selector
- type SingularQueryExpr
- type SliceSelector
- func (s SliceSelector) Bounds(length int) (int, int)
- func (s SliceSelector) End() int
- func (s SliceSelector) Select(input, _ any) []any
- func (s SliceSelector) SelectLocated(input, _ any, parent NormalizedPath) []*LocatedNode
- func (s SliceSelector) Start() int
- func (s SliceSelector) Step() int
- func (s SliceSelector) String() string
- type Validator
- type ValueType
- type WildcardSelector
Examples ¶
- Package
- CompExpr
- ExistExpr
- FilterSelector
- FuncExpr
- Index
- LiteralArg
- LocatedNode
- LogicalAnd
- LogicalFrom
- LogicalOr
- LogicalType
- Name
- NodesFrom
- NodesType
- NonExistExpr
- NormalizedPath
- NotFuncExpr
- NotParenExpr
- ParenExpr
- PathQuery
- PathValue
- Segment (Child)
- Segment (Descendant)
- SingularQueryExpr
- SliceSelector
- ValueFrom
- ValueType
- Wildcard
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BasicExpr ¶
type BasicExpr interface {
// contains filtered or unexported methods
}
BasicExpr defines the basic interface for filter expressions. Implementations:
type CompExpr ¶ added in v0.9.0
type CompExpr struct {
// contains filtered or unexported fields
}
CompExpr is a filter expression that compares two values, which themselves may themselves be the output of expressions. Interfaces implemented:
Example ¶
Create a comparison expression that compares a literal value to a path expression.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { cmp := spec.Comparison( spec.Literal(42), spec.EqualTo, spec.SingularQuery(false, spec.Name("age")), ) fmt.Printf("%v\n", cmp) }
Output: 42 == @["age"]
func Comparison ¶
Comparison creates and returns a new CompExpr that uses op to compare left and right.
type CompOp ¶
type CompOp uint8
CompOp defines the JSONPath filter comparison operators.
const ( // EqualTo is the == operator. EqualTo CompOp = iota + 1 // == // NotEqualTo is the != operator. NotEqualTo // != // LessThan is the < operator. LessThan // < // GreaterThan is the > operator. GreaterThan // > // LessThanEqualTo is the <= operator. LessThanEqualTo // <= // GreaterThanEqualTo is the >= operator. GreaterThanEqualTo // >= )
type CompVal ¶
type CompVal interface {
// contains filtered or unexported methods
}
CompVal defines the interface for comparable values in filter expressions. Implemented by:
type Evaluator ¶ added in v0.9.0
Evaluator functions execute a FuncExtension against the values returned by args and returns a result.
type ExistExpr ¶
type ExistExpr struct {
*PathQuery
}
ExistExpr represents a PathQuery used as a filter expression, in which context it returns true if the PathQuery selects at least one node. Interfaces implemented:
- BasicExpr
- Selector (via the underlying PathQuery)
- fmt.Stringer (via the underlying PathQuery)
Example ¶
Create an existence expression as a filter expression.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { filter := spec.Filter(spec.And( spec.Existence( spec.Query(false, spec.Child(spec.Name("x"))), ), )) fmt.Printf("%v\n", filter) }
Output: ?@["x"]
type FilterSelector ¶
type FilterSelector struct {
LogicalOr
}
FilterSelector is a filter selector, e.g., ?(), as defined by RFC 9535 Section 2.3.5. Interfaces implemented:
Example ¶
Create a filter selector that selects nodes with a descendant that contains an object field named "x".
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { f := spec.Filter(spec.And( spec.Existence( spec.Query(false, spec.Descendant(spec.Name("x"))), ), )) fmt.Printf("%v\n", f) }
Output: ?@..["x"]
func Filter ¶
func Filter(expr ...LogicalAnd) *FilterSelector
Filter returns a new FilterSelector that ORs the evaluation of each expr.
func (*FilterSelector) Eval ¶ added in v0.2.0
func (f *FilterSelector) Eval(node, root any) bool
Eval evaluates the f's LogicalOr expression against node and root. Uses FilterSelector.Select as it iterates over nodes, and always passes the root value($) for filter expressions that reference it.
func (*FilterSelector) Select ¶
func (f *FilterSelector) Select(current, root any) []any
Select selects and returns values that f filters from current. Filter expressions may evaluate the current value (@), the root value ($), or any path expression. Defined by the Selector interface.
func (*FilterSelector) SelectLocated ¶ added in v0.3.0
func (f *FilterSelector) SelectLocated(current, root any, parent NormalizedPath) []*LocatedNode
SelectLocated selects and returns LocatedNode values with values that f filters from current. Filter expressions may evaluate the current value (@), the root value ($), or any path expression. Defined by the Selector interface.
func (*FilterSelector) String ¶
func (f *FilterSelector) String() string
String returns a string representation of f.
type FuncExpr ¶ added in v0.9.0
type FuncExpr struct {
// contains filtered or unexported fields
}
FuncExpr represents a function expression, consisting of a named FuncExtension and its arguments. See github.com/theory/jsonpath/registry for an example defining a custom function. Interfaces Implemented:
Example ¶
Use the standard match() function in a function expression.
package main import ( "fmt" "github.com/theory/jsonpath/registry" "github.com/theory/jsonpath/spec" ) func main() { reg := registry.New() fe := spec.Function( reg.Get("match"), spec.Query(false, spec.Child(spec.Name("rating"))), spec.Literal("good$"), ) fmt.Printf("%v\n", fe) }
Output: match(@["rating"], "good$")
func Function ¶
func Function(fn *FuncExtension, args ...FuncExprArg) *FuncExpr
Function creates an returns a new FuncExpr that will execute fn against the return values of args.
func (*FuncExpr) ConvertsTo ¶ added in v0.9.0
ConvertsTo returns true if fe's result can be converted to ft.
func (*FuncExpr) ResultType ¶ added in v0.9.0
ResultType returns the result type of fe's FuncExtension. Defined by the FuncExprArg interface.
type FuncExprArg ¶ added in v0.9.0
type FuncExprArg interface { // ResultType returns the [FuncType] that defines the type of the return // value of the [FuncExprArg]. ResultType() FuncType // ConvertsTo returns true if the function expression's result can be // converted to ft. ConvertsTo(ft FuncType) bool // contains filtered or unexported methods }
FuncExprArg defines the interface for function argument expressions. Implementations:
type FuncExtension ¶ added in v0.9.0
type FuncExtension struct {
// contains filtered or unexported fields
}
FuncExtension defines a JSONPath function extension as defined in RFC 9535 Section 2.4. Use github.com/theory/jsonpath/registry.Registry.Register to construct and register a new FuncExtension.
func Extension ¶ added in v0.9.0
func Extension(name string, returnType FuncType, validator Validator, evaluator Evaluator) *FuncExtension
Extension creates a new JSONPath function extension. Created by github.com/theory/jsonpath/registry.Registry.Register. The parameters are:
- name: the name of the function extension as used in JSONPath queries.
- returnType: The data type of the function return value.
- validator: A validation function that will be called at parse time to validate that all the function args are compatible with the function.
- evaluator: The implementation of the function itself that executes against args and returns the result of the type defined by resultType.
func (*FuncExtension) Evaluate ¶ added in v0.9.0
func (f *FuncExtension) Evaluate(args []PathValue) PathValue
Evaluate executes the FuncExtension against args and returns a result of type [ResultType].
func (*FuncExtension) Name ¶ added in v0.9.0
func (f *FuncExtension) Name() string
Name returns the name of the FuncExtension.
func (*FuncExtension) ReturnType ¶ added in v0.9.0
func (f *FuncExtension) ReturnType() FuncType
ReturnType returns the data type of the FuncExtension return value.
func (*FuncExtension) Validate ¶ added in v0.9.0
func (f *FuncExtension) Validate(args []FuncExprArg) error
Validate executes at parse time to validate that all the args to the are compatible with the FuncExtension.
type FuncType ¶
type FuncType uint8
FuncType describes the types of function parameters and results as defined by RFC 9535 Section 2.4.1.
Implements fmt.Stringer.
type Index ¶
type Index int
Index is an array index selector, e.g., [3], as defined by RFC 9535 Section 2.3.3. Interfaces implemented:
Example ¶
Create a few index selectors.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { for _, indexSelector := range []any{ spec.Index(0), // first item spec.Index(3), // fourth item spec.Index(-1), // last item } { fmt.Printf("%v\n", indexSelector) } }
Output: 0 3 -1
func (Index) Select ¶
Select selects i from input and returns it as a single value in a slice. Returns an empty slice if input is not a slice or if i it outside the bounds of input. Defined by the Selector interface.
func (Index) SelectLocated ¶ added in v0.3.0
func (i Index) SelectLocated(input, _ any, parent NormalizedPath) []*LocatedNode
SelectLocated selects i from input and returns it with its normalized path as a single LocatedNode in a slice. Returns an empty slice if input is not a slice or if i it outside the bounds of input. Defined by the Selector interface.
type LiteralArg ¶
type LiteralArg struct {
// contains filtered or unexported fields
}
LiteralArg represents a literal JSON value, excluding objects and arrays. Its underlying value there must be one of string, integer, float, json.Number, nil, true, or false.
Interfaces implemented:
Example ¶
Pass a LiteralArg to a function.
package main import ( "fmt" "github.com/theory/jsonpath/registry" "github.com/theory/jsonpath/spec" ) func main() { reg := registry.New() fe := spec.Function( reg.Get("length"), spec.Literal("some string"), ) fmt.Printf("%v\n", fe) }
Output: length("some string")
func Literal ¶
func Literal(lit any) *LiteralArg
Literal creates and returns a new LiteralArg consisting of lit, which must ge one of string, integer, float, json.Number, nil, true, or false.
func (*LiteralArg) ConvertsTo ¶ added in v0.9.0
func (*LiteralArg) ConvertsTo(ft FuncType) bool
ConvertsTo returns true if the result of the LiteralArg can be converted to ft.
func (*LiteralArg) ResultType ¶
func (la *LiteralArg) ResultType() FuncType
ResultType returns FuncValue. Defined by the FuncExprArg interface.
func (*LiteralArg) String ¶ added in v0.9.0
func (la *LiteralArg) String() string
String returns the JSON string representation of la.
func (*LiteralArg) Value ¶
func (la *LiteralArg) Value() any
Value returns the underlying value of la.
type LocatedNode ¶ added in v0.3.0
type LocatedNode struct { // Node is the value selected from a JSON query argument. Node any `json:"node"` // Path is the normalized path that uniquely identifies the location of // Node in a JSON query argument. Path NormalizedPath `json:"path"` }
LocatedNode pairs a value with the NormalizedPath for its location within the JSON query argument from which it was selected. Returned by implementations of Selector's SelectLocated method.
Example ¶
package main import ( "encoding/json" "fmt" "log" "github.com/theory/jsonpath" "github.com/theory/jsonpath/spec" ) func main() { // Query all "author" object properties. p := jsonpath.New(spec.Query( true, spec.Descendant(spec.Name("author")), )) // Select LocatedNodes from unmarshaled JSON input. store := bookstore() nodes := p.SelectLocated(store) // Show the LocatedNodes. items, err := json.MarshalIndent(nodes, "", " ") 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: [ { "node": "Nigel Rees", "path": "$['store']['book'][0]['author']" }, { "node": "Evelyn Waugh", "path": "$['store']['book'][1]['author']" }, { "node": "Herman Melville", "path": "$['store']['book'][2]['author']" }, { "node": "J. R. R. Tolkien", "path": "$['store']['book'][3]['author']" } ]
type LogicalAnd ¶
type LogicalAnd []BasicExpr
LogicalAnd represents a list of one or more expressions ANDed together by the && operator. Evaluates to true if all of its expressions evaluate to true. Short-circuits and returns false for the first expression that returns false. Interfaces implemented:
Example ¶
Assemble a LogicalAnd consisting of multiple expressions.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { and := spec.And( spec.Value(42), spec.Existence( spec.Query(false, spec.Child(spec.Name("answer"))), ), ) fmt.Printf("%v\n", and) }
Output: 42 && @["answer"]
func And ¶ added in v0.9.0
func And(expr ...BasicExpr) LogicalAnd
And creates a LogicalAnd of all expr.
func (LogicalAnd) String ¶ added in v0.9.0
func (la LogicalAnd) String() string
String returns the string representation of la.
type LogicalOr ¶
type LogicalOr []LogicalAnd
LogicalOr represents a list of one or more expressions ORed together by the || operator. Evaluates to true if any of its expressions evaluates to true. Short-circuits and returns true for the first expression that returns true.
Interfaces implemented:
Example ¶
Assemble a LogicalOr consisting of multiple expressions.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { and := spec.Or( spec.And(spec.Existence( spec.Query(false, spec.Child(spec.Name("answer"))), )), spec.And(spec.Value(42)), ) fmt.Printf("%v\n", and) }
Output: @["answer"] || 42
func (LogicalOr) ConvertsTo ¶ added in v0.9.0
ConvertsTo returns true if the result of the LogicalOr can be converted to ft.
func (LogicalOr) ResultType ¶
ResultType returns FuncLogical. Defined by the FuncExprArg interface.
type LogicalType ¶
type LogicalType uint8
LogicalType encapsulates a true or false value for a function expression parameters or results, as defined by RFC 9535 Section 2.4.1. Interfaces implemented:
Example ¶
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { fmt.Printf("%v\n", spec.Logical(true)) fmt.Printf("%v\n", spec.Logical(false)) }
Output: true false
const ( // LogicalFalse represents a true [LogicalType]. LogicalFalse LogicalType = iota // false // LogicalTrue represents a true [LogicalType]. LogicalTrue // true )
func Logical ¶ added in v0.9.0
func Logical(boolean bool) LogicalType
Logical returns the LogicalType equivalent to boolean.
func LogicalFrom ¶
func LogicalFrom(value any) LogicalType
LogicalFrom converts value to a LogicalType and panics if it cannot. Use in github.com/theory/jsonpath/registry.Registry.Register Evaluator functions. Avoid the panic by returning an error from the accompanying Validator function when [FuncExprArg.ConvertsToLogical] returns false for the FuncExprArg that returns value.
Converts each implementation of PathValue as follows:
- LogicalType: returns value
- NodesType: Returns LogicalFalse if value is empty and LogicalTrue if it is not
- ValueType: Panics
- nil: Returns LogicalFalse
Example ¶
Of the implementations of PathValue, spec.LogicalType, spec.NodesType, and nil can be converted to spec.NodesType.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { for _, val := range []spec.PathValue{ spec.Nodes(1, 2, 3), // converts to logical (existence) spec.Logical(false), // converts to logical nil, } { fmt.Printf("logical: %v\n", spec.LogicalFrom(val)) } }
Output: logical: true logical: false logical: false
func (LogicalType) Bool ¶
func (lt LogicalType) Bool() bool
Bool returns the boolean equivalent to lt.
func (LogicalType) FuncType ¶
func (LogicalType) FuncType() FuncType
FuncType returns FuncLogical. Defined by the PathValue interface.
func (LogicalType) String ¶
func (i LogicalType) String() string
type Name ¶
type Name string
Name is a key name selector, e.g., .name or ["name"], as defined by RFC 9535 Section 2.3.1. Interfaces implemented:
Example ¶
Create a few name selectors.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { for _, nameSelector := range []any{ spec.Name("hello"), // ascii spec.Name(`Charlie "Bird" Parker`), // quoted spec.Name("އައްސަލާމް ޢަލައިކުމް"), // Unicode spec.Name("📡🪛🪤"), // emoji } { fmt.Printf("%v\n", nameSelector) } }
Output: "hello" "Charlie \"Bird\" Parker" "އައްސަލާމް ޢަލައިކުމް" "📡🪛🪤"
func (Name) Select ¶
Select selects n from input and returns it as a single value in a slice. Returns an empty slice if input is not a map[string]any or if it does not contain n. Defined by the Selector interface.
func (Name) SelectLocated ¶ added in v0.3.0
func (n Name) SelectLocated(input, _ any, parent NormalizedPath) []*LocatedNode
SelectLocated selects n from input and returns it with its normalized path as a single LocatedNode in a slice. Returns an empty slice if input is not a map[string]any or if it does not contain n. Defined by the Selector interface.
type NodesType ¶
type NodesType []any
NodesType defines a node list (a list of JSON values) for a function expression parameters or results, as defined by RFC 9535 Section 2.4.1. It can also be used in filter expressions. The underlying types should be string, integer, float, json.Number, nil, true, false, []any, or map[string]any. Interfaces implemented:
Example ¶
Use a spec.NodesType to create a list of nodes, a.k.a. a JSON array.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { fmt.Printf("%v\n", spec.Nodes("hi", 42, true)) }
Output: [hi 42 true]
func Nodes ¶ added in v0.9.0
Nodes creates a NodesType that contains val, all of which should be the Go equivalent of the JSON data types: string, integer, float, json.Number, nil, true, false, []any, or map[string]any.
func NodesFrom ¶
NodesFrom converts value to a NodesType and panics if it cannot. Use in github.com/theory/jsonpath/registry.Registry.Register Evaluator. Avoid the panic by returning an error from the accompanying Validator function when [FuncExprArg.ConvertsToNodes] returns false for the FuncExprArg that returns value.
Converts each implementation of PathValue as follows:
- NodesType: returns value
- ValueType: Returns a NodesType containing that single value
- LogicalType: Panics
- nil: Returns an empty NodesType
Example ¶
Of the implementations of PathValue, only spec.NodesType and nil can be converted to spec.NodesType.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { for _, val := range []spec.PathValue{ spec.Nodes(1, 2, 3), // no conversion nil, // converts to empty NodesType } { fmt.Printf("nodes: %v\n", spec.NodesFrom(val)) } }
Output: nodes: [1 2 3] nodes: []
type NonExistExpr ¶
type NonExistExpr struct {
*PathQuery
}
NonExistExpr represents a negated PathQuery used as a filter expression, in which context it returns true if the PathQuery selects no nodes. Interfaces implemented:
- BasicExpr
- Selector (via the underlying PathQuery)
- fmt.Stringer (via the underlying PathQuery)
Example ¶
Create a nonexistence expression as a filter expression.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { filter := spec.Filter(spec.And( spec.Nonexistence( spec.Query(false, spec.Child(spec.Name("x"))), ), )) fmt.Printf("%v\n", filter) }
Output: ?!@["x"]
func Nonexistence ¶
func Nonexistence(q *PathQuery) *NonExistExpr
Nonexistence creates a new NonExistExpr for q.
type NormalSelector ¶ added in v0.3.0
type NormalSelector interface {
// contains filtered or unexported methods
}
NormalSelector represents a single selector in a normalized path. Implemented by Name and Index.
type NormalizedPath ¶ added in v0.3.0
type NormalizedPath []NormalSelector
NormalizedPath represents a normalized path identifying a single value in a JSON query argument, as defined by RFC 9535. Defines a simplified string format that exclusively uses single quotation marks to quote names. Useful for converting to JSON Pointer (via NormalizedPath.Pointer) or other JSON pointer-type formats.
Interfaces implemented:
Example ¶
Compare a normalized JSONPath and its JSON Pointer equivalent.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { norm := spec.Normalized( spec.Name("x"), spec.Index(1), spec.Name("y"), ) fmt.Printf("%v\n", norm) fmt.Printf("%v\n", norm.Pointer()) }
Output: $['x'][1]['y'] /x/1/y
func Normalized ¶ added in v0.9.0
func Normalized(sel ...NormalSelector) NormalizedPath
Normalized creates and returns a NormalizedPath that contains sel.
func (NormalizedPath) Compare ¶ added in v0.3.0
func (np NormalizedPath) Compare(np2 NormalizedPath) int
Compare compares np to np2 and returns -1 if np is less than np2, 1 if it's greater than np2, and 0 if they're equal. Indexes are always considered less than names.
func (NormalizedPath) MarshalText ¶ added in v0.3.0
func (np NormalizedPath) MarshalText() ([]byte, error)
MarshalText marshals np into text. Implements encoding.TextMarshaler.
func (NormalizedPath) Pointer ¶ added in v0.4.0
func (np NormalizedPath) Pointer() string
Pointer returns an RFC 6901 JSON Pointer string representation of np.
func (NormalizedPath) String ¶ added in v0.3.0
func (np NormalizedPath) String() string
String returns the string representation of np.
type NotFuncExpr ¶
type NotFuncExpr struct {
*FuncExpr
}
NotFuncExpr represents a negated function expression. It reverses the result of the return value of the underlying FuncExpr. Interfaces implemented:
Example ¶
Use the standard count() function in a function expression.
package main import ( "fmt" "github.com/theory/jsonpath/registry" "github.com/theory/jsonpath/spec" ) func main() { reg := registry.New() nf := spec.NotFunction(spec.Function( reg.Get("length"), spec.Query(false, spec.Child(spec.Index(0))), )) fmt.Printf("%v\n", nf) }
Output: !length(@[0])
func NotFunction ¶
func NotFunction(fn *FuncExpr) NotFuncExpr
NotFunction creates and returns a new NotFuncExpr that will execute fn against the return values of args and return the inverse of its return value.
func (NotFuncExpr) String ¶ added in v0.9.0
func (nf NotFuncExpr) String() string
String returns the string representation of nf.
type NotParenExpr ¶
type NotParenExpr struct {
LogicalOr
}
NotParenExpr represents a negated parenthesized expression that groups the elements of a LogicalOr. Interfaces implemented (via the underlying LogicalOr):
Example ¶
Use a spec.NotParenExpr to negate the result of a LogicalOr expression.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { not := spec.NotParen( spec.And( spec.Existence( spec.Query(false, spec.Child(spec.Name("answer"))), ), ), spec.And( spec.Existence( spec.Query(false, spec.Child(spec.Name("question"))), ), ), ) fmt.Printf("%v\n", not) }
Output: !(@["answer"] || @["question"])
func NotParen ¶
func NotParen(expr ...LogicalAnd) *NotParenExpr
NotParen returns a new NotParenExpr that ORs each expr.
func (*NotParenExpr) String ¶ added in v0.9.0
func (np *NotParenExpr) String() string
String returns the string representation of np.
type ParenExpr ¶
type ParenExpr struct {
LogicalOr
}
ParenExpr represents a parenthesized expression that groups the elements of a LogicalOr. Interfaces implemented (via the underlying LogicalOr):
Example ¶
Use a spec.ParenExpr to group the result of a LogicalOr expression.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { paren := spec.Paren( spec.And( spec.Existence( spec.Query(false, spec.Child(spec.Name("answer"))), ), ), spec.And( spec.Existence( spec.Query(false, spec.Child(spec.Name("question"))), ), ), ) fmt.Printf("%v\n", paren) }
Output: (@["answer"] || @["question"])
func Paren ¶
func Paren(expr ...LogicalAnd) *ParenExpr
Paren returns a new ParenExpr that ORs the results of each expr.
type PathQuery ¶
type PathQuery struct {
// contains filtered or unexported fields
}
PathQuery represents a JSONPath query. Interfaces implemented:
Example ¶
Construct a couple of different path queries.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { // Create a query and its segments. q := spec.Query( true, spec.Child(spec.Name("store")), spec.Child(spec.Name("book")), spec.Child(spec.Wildcard()), spec.Child(spec.Name("author")), ) fmt.Printf("%v\n", q) // Create a query with multi-selector segments. q = spec.Query( true, spec.Child(spec.Name("profile")), spec.Descendant(spec.Name("email"), spec.Name("phone")), ) fmt.Printf("%v\n", q) }
Output: $["store"]["book"][*]["author"] $["profile"]..["email","phone"]
func Query ¶
Query returns a new PathQuery consisting of segments. When root is true it indicates a query from the root of a value. Set to false for filter subqueries.
func (*PathQuery) ConvertsTo ¶ added in v0.9.0
ConvertsTo returns true if fq's result can be converted to ft. A singular query can be converted to either FuncValue or FuncNodes. All other queries can only be converted to FuncNodes.
func (*PathQuery) Expression ¶
func (q *PathQuery) Expression() FuncExprArg
Expression returns a SingularQueryExpr variant of q if q is a singular query, and otherwise returns q.
func (*PathQuery) ResultType ¶ added in v0.9.0
ResultType returns FuncValue if fq is a singular query, and FuncNodes if it is not. Defined by the FuncExprArg interface.
func (*PathQuery) Select ¶
Select selects the values from current or root and returns the results. Returns just current if q has no segments. Defined by the Selector interface.
func (*PathQuery) SelectLocated ¶ added in v0.3.0
func (q *PathQuery) SelectLocated(current, root any, parent NormalizedPath) []*LocatedNode
SelectLocated values from current or root into LocatedNode values and returns the results. Returns just current if q has no segments. Defined by the Selector interface.
func (*PathQuery) Singular ¶
func (q *PathQuery) Singular() *SingularQueryExpr
Singular returns the SingularQueryExpr variant of q if q is a singular query. Otherwise it returns nil.
type PathValue ¶
type PathValue interface { // FuncType returns the PathValue's [FuncType]. FuncType() FuncType // contains filtered or unexported methods }
PathValue defines the interface for JSONPath values used as comparison operands, filter expression results, and function parameters & return values.
Implemented by the function types defined by RFC 9535 Section 2.4.1:
Example ¶
Print the spec.FuncType for each spec.PathValue implementation.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { fmt.Printf("Implementation FuncType\n") fmt.Printf("----------------- --------\n") for _, jv := range []spec.PathValue{ spec.Value(nil), spec.Nodes(1, 2), spec.Logical(true), } { fmt.Printf("%-17T %v\n", jv, jv.FuncType()) } }
Output: Implementation FuncType ----------------- -------- *spec.ValueType Value spec.NodesType Nodes spec.LogicalType Logical
type Segment ¶
type Segment struct {
// contains filtered or unexported fields
}
Segment represents a single segment as defined in RFC 9535 Section 1.4.2, consisting of a list of Selector values.
Example (Child) ¶
Create a child segment that selects the name "hi", th index 2, or slice 1-3.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { child := spec.Child( spec.Name("hi"), spec.Index(2), spec.Slice(1, 3, 1), ) fmt.Printf("%v\n", child) }
Output: ["hi",2,1:3]
Example (Descendant) ¶
Create a descendant segment that selects the name "email" or array index zero from a node or any of its descendant nodes.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { child := spec.Descendant( spec.Name("email"), spec.Index(0), ) fmt.Printf("%v\n", child) }
Output: ..["email",0]
func Child ¶
Child creates and returns a Segment that uses sel to select values from a JSON object or array.
func Descendant ¶
Descendant creates and returns a Segment that uses sel to select values from a JSON object or array or any of its descendant objects and arrays.
func (*Segment) IsDescendant ¶ added in v0.2.0
IsDescendant returns true if the segment is a Descendant selector that recursively select the children of a JSON value.
func (*Segment) Select ¶
Select selects and returns values from current or root, for each of s's selectors. Defined by the Selector interface.
func (*Segment) SelectLocated ¶ added in v0.3.0
func (s *Segment) SelectLocated(current, root any, parent NormalizedPath) []*LocatedNode
SelectLocated selects and returns values as LocatedNode values from current or root for each of seg's selectors. Defined by the Selector interface.
type Selector ¶
type Selector interface { // Select selects values from current and/or root and returns them. Select(current, root any) []any // SelectLocated selects values from current and/or root and returns them // in [LocatedNode] values with their located normalized paths SelectLocated(current, root any, parent NormalizedPath) []*LocatedNode // contains filtered or unexported methods }
Selector represents a single Selector in an RFC 9535 JSONPath query.
type SingularQueryExpr ¶
type SingularQueryExpr struct {
// contains filtered or unexported fields
}
SingularQueryExpr represents a query that produces a single ValueType (JSON value) or nothing. Used in contexts that require a singular value, such as comparison operations and function arguments. Interfaces implemented:
Example ¶
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { singular := spec.SingularQuery( true, spec.Name("profile"), spec.Name("contacts"), spec.Index(0), spec.Name("email"), ) fmt.Printf("%v\n", singular) }
Output: $["profile"]["contacts"][0]["email"]
func SingularQuery ¶
func SingularQuery(root bool, selectors ...Selector) *SingularQueryExpr
SingularQuery creates and returns a SingularQueryExpr that selects a single value at the path defined by selectors.
func (*SingularQueryExpr) ConvertsTo ¶ added in v0.9.0
func (*SingularQueryExpr) ConvertsTo(ft FuncType) bool
ConvertsTo returns true if the result of the SingularQueryExpr can be converted to ft.
func (*SingularQueryExpr) ResultType ¶
func (sq *SingularQueryExpr) ResultType() FuncType
ResultType returns FuncValue. Defined by the FuncExprArg interface.
func (*SingularQueryExpr) String ¶ added in v0.9.0
func (sq *SingularQueryExpr) String() string
String returns the string representation of sq.
type SliceSelector ¶
type SliceSelector struct {
// contains filtered or unexported fields
}
SliceSelector is a slice selector, e.g., [0:100:5], as defined by RFC 9535 Section 2.3.4. Interfaces implemented:
Example ¶
Create a few slice selectors.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { // Select all values in a slice. for _, sliceSelector := range []any{ spec.Slice(), // full slice spec.Slice(1, 4), // items 1-3 spec.Slice(nil, 8), // items 0-7 spec.Slice(4, -1, 3), // items 4-last step by 3 spec.Slice(5, 1, -2), // items 5-2, step by -2 } { fmt.Printf("%v\n", sliceSelector) } }
Output: : 1:4 :8 4:-1:3 5:1:-2
func Slice ¶
func Slice(args ...any) SliceSelector
Slice creates a new SliceSelector. Pass up to three integers or nils for the start, end, and step arguments. Subsequent arguments are ignored.
func (SliceSelector) Bounds ¶ added in v0.2.0
func (s SliceSelector) Bounds(length int) (int, int)
Bounds returns the lower and upper bounds for selecting from a slice of length.
func (SliceSelector) Select ¶
func (s SliceSelector) Select(input, _ any) []any
Select selects and returns the values from input for the indexes specified by s. Returns an empty slice if input is not a slice. Indexes outside the bounds of input will not be included in the return value. Defined by the Selector interface.
func (SliceSelector) SelectLocated ¶ added in v0.3.0
func (s SliceSelector) SelectLocated(input, _ any, parent NormalizedPath) []*LocatedNode
SelectLocated selects values from input for the indexes specified by s and returns thm with their normalized paths as LocatedNode values. Returns an empty slice if input is not a slice. Indexes outside the bounds of input will not be included in the return value. Defined by the Selector interface.
func (SliceSelector) String ¶
func (s SliceSelector) String() string
String returns a quoted string representation of s.
type Validator ¶ added in v0.9.0
type Validator func(args []FuncExprArg) error
Validator functions validate that the args expressions to a FuncExtension can be processed by the function.
type ValueType ¶
type ValueType struct {
// contains filtered or unexported fields
}
ValueType encapsulates a JSON value for a function expression parameter or result, as defined by RFC 9535 Section 2.4.1. It can also be used as in filter expression. The underlying value should be a string, integer, json.Number, float, nil, true, false, []any, or map[string]any. A nil ValueType pointer indicates no value. Interfaces implemented:
Example ¶
Create A spec.ValueType for each supported JSON type.
package main import ( "encoding/json" "fmt" "github.com/theory/jsonpath/spec" ) func main() { for _, val := range []any{ "hello", 42, 98.6, json.Number("1024"), true, nil, map[string]any{"x": true}, []any{1, 2, false}, } { fmt.Printf("%v\n", spec.Value(val)) } }
Output: hello 42 98.6 1024 true <nil> map[x:true] [1 2 false]
func Value ¶
Value returns a new ValueType for val, which must be the Go equivalent of a JSON data type: string, integer, float, json.Number, nil, true, false, []any, or map[string]any.
func ValueFrom ¶
ValueFrom converts value to a ValueType and panics if it cannot. Use in github.com/theory/jsonpath/registry.Registry.Register Evaluator functions. Avoid the panic by returning an error from the accompanying Validator function when [FuncExprArg.ConvertsToValue] returns false for the FuncExprArg that returns value.
Converts each implementation of PathValue as follows:
Example ¶
Of the implementations of PathValue, only spec.ValueType and nil can be converted to spec.ValueType.
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { for _, val := range []spec.PathValue{ spec.Value("hello"), // no conversion nil, // equivalent to no value } { fmt.Printf("val: %v\n", spec.ValueFrom(val)) } }
Output: val: hello val: <nil>
type WildcardSelector ¶ added in v0.2.0
type WildcardSelector struct{}
WildcardSelector is a wildcard selector, e.g., * or [*], as defined by RFC 9535 Section 2.3.2. Interfaces implemented:
func Wildcard ¶
func Wildcard() WildcardSelector
Wildcard returns a WildcardSelector singleton.
Example ¶
package main import ( "fmt" "github.com/theory/jsonpath/spec" ) func main() { fmt.Printf("%v\n", spec.Wildcard()) }
Output: *
func (WildcardSelector) Select ¶ added in v0.2.0
func (WildcardSelector) Select(input, _ any) []any
Select selects the values from input and returns them in a slice. Returns an empty slice if input is not []any map[string]any. Defined by the Selector interface.
func (WildcardSelector) SelectLocated ¶ added in v0.3.0
func (WildcardSelector) SelectLocated(input, _ any, parent NormalizedPath) []*LocatedNode
SelectLocated selects the values from input and returns them with their normalized paths in a slice of LocatedNode values. Returns an empty slice if input is not []any map[string]any. Defined by the Selector interface.
func (WildcardSelector) String ¶ added in v0.2.0
func (WildcardSelector) String() string
String returns "*".