Documentation ¶
Overview ¶
Package jsonpath is a template engine using jsonpath syntax, which can be seen at http://goessner.net/articles/JsonPath/. In addition, it has {range} {end} function to iterate list and slice. This package is copied from repo kubernetes/client-go. See: https://kubernetes.io/docs/reference/kubectl/jsonpath/
Index ¶
- Variables
- func UnquoteExtend(s string) (string, error)
- type ArrayNode
- type BoolNode
- type FieldNode
- type FilterNode
- type FloatNode
- type IdentifierNode
- type IntNode
- type JSONPath
- func (j *JSONPath) AllowMissingKeys(allow bool) *JSONPath
- func (j *JSONPath) EvalResults(results []reflect.Value) ([]interface{}, error)
- func (*JSONPath) EvalToInterface(v reflect.Value) (interface{}, error)
- func (j *JSONPath) EvalToText(v reflect.Value) ([]byte, error)
- func (j *JSONPath) Execute(wr io.Writer, data interface{}) error
- func (j *JSONPath) ExecuteToInterface(data interface{}) (interface{}, error)
- func (j *JSONPath) FindResults(data interface{}) ([][]reflect.Value, error)
- func (j *JSONPath) Parse() error
- func (j *JSONPath) PrintResults(wr io.Writer, results []reflect.Value) error
- type ListNode
- type Node
- type NodeType
- type ParamsEntry
- type Parser
- type RecursiveNode
- type TextNode
- type UnionNode
- type WildcardNode
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrSyntax is used to indicate a syntax error while evaluating the expression ErrSyntax = errors.New("invalid syntax") )
var NodeTypeName = map[NodeType]string{ NodeText: "NodeText", NodeArray: "NodeArray", NodeList: "NodeList", NodeField: "NodeField", NodeIdentifier: "NodeIdentifier", NodeFilter: "NodeFilter", NodeInt: "NodeInt", NodeFloat: "NodeFloat", NodeWildcard: "NodeWildcard", NodeRecursive: "NodeRecursive", NodeUnion: "NodeUnion", NodeBool: "NodeBool", }
NodeTypeName maps node type code to node type text representation
Functions ¶
func UnquoteExtend ¶
UnquoteExtend is almost same as strconv.Unquote(), but it support parse single quotes as a string
Types ¶
type ArrayNode ¶
type ArrayNode struct { NodeType Params [3]ParamsEntry // start, end, step }
ArrayNode holds start, end, step information for array index selection
type FilterNode ¶
FilterNode holds operand and operator information for filter
func (*FilterNode) String ¶
func (f *FilterNode) String() string
type IdentifierNode ¶
IdentifierNode holds an identifier
func (*IdentifierNode) String ¶
func (f *IdentifierNode) String() string
type JSONPath ¶
type JSONPath struct {
// contains filtered or unexported fields
}
JSONPath represents the expression to evaluate
func (*JSONPath) AllowMissingKeys ¶
AllowMissingKeys allows a caller to specify whether they want an error if a field or map key cannot be located, or simply an empty result. The receiver is returned for chaining.
func (*JSONPath) EvalResults ¶
EvalResults writes the results into a slice of interfaces
Example (Array_filter) ¶
package main import ( "bytes" "fmt" "os" "github.com/VirtusLab/go-extended/pkg/json" "github.com/VirtusLab/go-extended/pkg/jsonpath" ) func main() { bs := []byte(`[ {"key":"a","value" : "I"}, {"key":"b","value" : "II"}, {"key":"c","value" : "III"} ]`) expression := `{$[?(@.key=="b")].value}` data, err := json.ToInterface(bytes.NewReader(bs)) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } results, err := jsonpath.New(expression).ExecuteToInterface(data) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } fmt.Println(results) }
Output: II
Example (Goessner) ¶
package main import ( "bytes" "fmt" "os" "strings" "github.com/VirtusLab/go-extended/pkg/json" "github.com/VirtusLab/go-extended/pkg/jsonpath" ) func main() { js := `{ "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": 19.95 } } }` expressions := []string{ `{$.store.book[*].author}`, `{$..author}`, `{$..book[2].title}`, `{$..book[-1:].title}`, `{$..book[0,1].title}`, `{$..book[:2].title}`, `{$..book[?(@.isbn)].title}`, `{$..book[?(@.price < 10.0)].title}`, `{$.store.bicycle.color}`, `{$..book[?(@.author=='J. R. R. Tolkien')].title}`, } data, err := json.ToInterface(strings.NewReader(js)) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } for _, expression := range expressions { writer := new(bytes.Buffer) err := jsonpath.New(expression).AllowMissingKeys(true).Execute(writer, data) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } fmt.Println(writer.String()) } }
Output: Nigel Rees Evelyn Waugh Herman Melville J. R. R. Tolkien Nigel Rees Evelyn Waugh Herman Melville J. R. R. Tolkien Moby Dick The Lord of the Rings Sayings of the Century Sword of Honour Sayings of the Century Sword of Honour Moby Dick The Lord of the Rings Sayings of the Century Moby Dick red The Lord of the Rings
Example (Kubectl_docs) ¶
package main import ( "fmt" "os" "strings" "github.com/VirtusLab/go-extended/pkg/json" "github.com/VirtusLab/go-extended/pkg/jsonpath" ) func main() { js := `{ "kind": "List", "items":[ { "kind":"None", "metadata":{"name":"127.0.0.1"}, "status":{ "capacity":{"cpu":"4"}, "addresses":[{"type": "LegacyHostIP", "address":"127.0.0.1"}] } }, { "kind":"None", "metadata":{"name":"127.0.0.2"}, "status":{ "capacity":{"cpu":"8"}, "addresses":[ {"type": "LegacyHostIP", "address":"127.0.0.2"}, {"type": "another", "address":"127.0.0.3"} ] } } ], "users":[ { "name": "myself", "user": {} }, { "name": "e2e", "user": {"username": "admin", "password": "secret"} } ] }` expressions := []string{ `{.kind}`, `{['kind']}`, `{.items[*].metadata.name}`, `{.users[0].name}`, `{.items[*]['metadata.name','status.capacity']}`, `{.users[?(@.name=="e2e")].user.password}`, `{range .items[*]}[{.metadata.name},{.status.capacity}]{end}`, } data, err := json.ToInterface(strings.NewReader(js)) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } for _, expression := range expressions { results, err := jsonpath.New(expression).ExecuteToInterface(data) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } fmt.Println(results) } }
Output: List List [127.0.0.1 127.0.0.2] myself [127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]] secret [[ 127.0.0.1 , map[cpu:4] ] [ 127.0.0.2 , map[cpu:8] ]]
Example (Simple) ¶
package main import ( "fmt" "os" "strings" "github.com/VirtusLab/go-extended/pkg/json" "github.com/VirtusLab/go-extended/pkg/jsonpath" ) func main() { js := `{ "welcome":{ "message":["Good Morning", "Hello World!"] } }` expression := "{$.welcome.message[1]}" data, err := json.ToInterface(strings.NewReader(js)) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } results, err := jsonpath.New(expression).ExecuteToInterface(data) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } fmt.Println(results) }
Output: Hello World!
Example (Yaml) ¶
package main import ( "fmt" "os" "strings" "github.com/VirtusLab/go-extended/pkg/jsonpath" "github.com/VirtusLab/go-extended/pkg/yaml" ) func main() { y := `--- welcome: message: - "Good Morning" - "Hello World!" ` expression := "{$.welcome.message[1]}" data, err := yaml.ToInterface(strings.NewReader(y)) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } results, err := jsonpath.New(expression).ExecuteToInterface(data) if err != nil { _, _ = fmt.Fprint(os.Stderr, err) } fmt.Println(results) }
Output: Hello World!
func (*JSONPath) EvalToInterface ¶
EvalToInterface translates reflect value to corresponding text
func (*JSONPath) EvalToText ¶
EvalToText translates reflect value to corresponding text
func (*JSONPath) ExecuteToInterface ¶
ExecuteToInterface bounds data into template and returns the result.
func (*JSONPath) FindResults ¶
FindResults searches recursively the data evaluating the path expression
type NodeType ¶
type NodeType int
NodeType identifies the type of a parse tree node.
const ( // NodeText is a text node type code NodeText NodeType = iota // NodeArray is an array node type code NodeArray // NodeList is a list node type code NodeList // NodeField is a field node type code NodeField // NodeIdentifier is an identifier node type code NodeIdentifier // NodeFilter is a filter node type code NodeFilter // NodeInt is an integer node type code NodeInt // NodeFloat is a float node type code NodeFloat // NodeWildcard is a wildcard node type code NodeWildcard // NodeRecursive is a recursive node type code NodeRecursive // NodeUnion is a union node type code NodeUnion // NodeBool is a boolean node type code NodeBool )
type ParamsEntry ¶
type ParamsEntry struct { Value int Known bool // whether the value is known when parse it Derived bool }
ParamsEntry holds param information for ArrayNode
type Parser ¶
Parser represents the JSONPath flavour syntax parser
type RecursiveNode ¶
type RecursiveNode struct {
NodeType
}
RecursiveNode means a recursive descent operator
func (*RecursiveNode) String ¶
func (r *RecursiveNode) String() string
type WildcardNode ¶
type WildcardNode struct {
NodeType
}
WildcardNode means a wildcard
func (*WildcardNode) String ¶
func (i *WildcardNode) String() string