jsonpath

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2022 License: Apache-2.0 Imports: 12 Imported by: 4

Documentation

Overview

Package jsonpath implements a language that can process JSONPath expressions (https://goessner.net/articles/JsonPath/).

Example (Gval)
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/PaesslerAG/gval"
	"github.com/puppetlabs/leg/jsonutil/pkg/jsonpath"
)

func main() {
	builder := gval.Full(jsonpath.Language(jsonpath.WithPlaceholders{}))

	path, err := builder.NewEvaluable("{#1: $..[?(@.ping && @.speed > 100)].name}")
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	v := any(nil)
	err = json.Unmarshal([]byte(`{
		"device 1":{
			"name": "fancy device",
			"ping": true,
			"speed": 200,
				"subdevice 1":{
					"ping" : true,
					"speed" : 99,
					"name" : "boring subdevice"
				},
				"subdevice 2":{
					"ping" : true,
					"speed" : 150,
					"name" : "fancy subdevice"
				},
				"not an device":{
					"name" : "ping me but I have no speed property",
					"ping" : true
				}
			},
		"fictive device":{
			"ping" : false,
			"speed" : 1000,
			"name" : "dream device"
			}
		}`), &v)

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	devices, err := path(context.Background(), v)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	for device, name := range devices.(map[string]any) {
		fmt.Printf("%s -> %v\n", device, name)
	}

}
Output:

device 1 -> fancy device
subdevice 2 -> fancy subdevice
Example (VariableSelector)
package main

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"os"
	"strings"

	"github.com/PaesslerAG/gval"
	"github.com/puppetlabs/leg/jsonutil/pkg/jsonpath"
)

func main() {
	builder := gval.NewLanguage(
		jsonpath.Language(),
		gval.VariableSelector(jsonpath.ChildVariableSelector(func(ctx context.Context, v any, key any, next func(context.Context, jsonpath.PathValue) error) error {
			return jsonpath.DefaultVariableVisitor().VisitChild(ctx, v, key, func(ctx context.Context, pv jsonpath.PathValue) error {
				if s, ok := pv.Value.(string); ok && strings.HasPrefix(s, "base64:") {
					b, err := base64.StdEncoding.DecodeString(s[len("base64:"):])
					if err != nil {
						return fmt.Errorf("could not decode base64 value: %v", err)
					}

					pv.Value = string(b)
				}

				return next(ctx, pv)
			})
		})),
	)

	path, err := builder.NewEvaluable(`$.encoded`)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	var v any
	err = json.Unmarshal([]byte(`{
		"encoded": "base64:SGVsbG8sIHdvcmxkIQ=="
	}`), &v)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	decoded, err := path(context.Background(), v)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(decoded)

}
Output:

Hello, world!

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrMapperNotCombinable   = errors.New("jsonpath: mapper cannot be combined with range query")
	ErrRangeQueryOutOfBounds = errors.New("jsonpath: range query must be of the format [min:max:step]")
	ErrFilterOutOfBounds     = errors.New("jsonpath: filter needs exactly one key")
)

Functions

func ChildVariableSelector

func ChildVariableSelector(fn func(ctx context.Context, parameter any, key any, next func(context.Context, PathValue) error) error) func(path gval.Evaluables) gval.Evaluable

func DefaultVariableSelector

func DefaultVariableSelector() func(path gval.Evaluables) gval.Evaluable

func Get

func Get(path string, value any) (any, error)

Get executes given JSONPath on given value

Example
package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/puppetlabs/leg/jsonutil/pkg/jsonpath"
)

func main() {
	v := any(nil)

	_ = json.Unmarshal([]byte(`{
		"welcome":{
				"message":["Good Morning", "Hello World!"]
			}
		}`), &v)

	welcome, err := jsonpath.Get("$.welcome.message[1]", v)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	fmt.Println(welcome)

}
Output:

Hello World!
Example (Filter)
package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/puppetlabs/leg/jsonutil/pkg/jsonpath"
)

func main() {
	v := any(nil)

	_ = json.Unmarshal([]byte(`[
		{"key":"a","value" : "I"},
		{"key":"b","value" : "II"},
		{"key":"c","value" : "III"}
		]`), &v)

	values, err := jsonpath.Get(`$[?(@.key=="b")].value`, v)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	for _, value := range values.([]any) {
		fmt.Println(value)
	}

}
Output:

II
Example (Wildcard)
package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/puppetlabs/leg/jsonutil/pkg/jsonpath"
)

func main() {
	v := any(nil)

	_ = json.Unmarshal([]byte(`{
		"welcome":{
				"message":["Good Morning", "Hello World!"]
			}
		}`), &v)

	welcome, err := jsonpath.Get("$.welcome.message[*]", v)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	for _, value := range welcome.([]any) {
		fmt.Printf("%v\n", value)
	}

}
Output:

Good Morning
Hello World!

func Language

func Language(opts ...LanguageOption) gval.Language

Language is the JSONPath language.

func New

func New(path string) (gval.Evaluable, error)

New returns an selector for given JSONPath

func VariableSelector

func VariableSelector(visitor VariableVisitor) func(path gval.Evaluables) gval.Evaluable

Types

type IndexParseError

type IndexParseError struct {
	Index int
	Cause error
}

func (*IndexParseError) Error

func (e *IndexParseError) Error() string

type KeyParseError

type KeyParseError struct {
	Key   string
	Cause error
}

func (*KeyParseError) Error

func (e *KeyParseError) Error() string

type LanguageOption

type LanguageOption interface {
	ApplyToLanguageOptions(target *LanguageOptions)
}

type LanguageOptions

type LanguageOptions struct {
	MissingKeysAllowed bool
	Placeholders       bool
	InitialPath        bool
}

func (*LanguageOptions) ApplyOptions

func (o *LanguageOptions) ApplyOptions(opts []LanguageOption)

type MixedSeparatorError

type MixedSeparatorError struct {
	A, B rune
}

func (*MixedSeparatorError) Error

func (e *MixedSeparatorError) Error() string

type PathResolutionError

type PathResolutionError struct {
	Path  []string
	Cause error
}

func (*PathResolutionError) Error

func (e *PathResolutionError) Error() string

type PathValue

type PathValue struct {
	Path  []string
	Value any
}

type PropagatableError

type PropagatableError interface {
	error
	Propagate() bool
}

PropagatableError allows an error to be propagated even when a selector would otherwise drop it, indicating, e.g., problems with the underlying data.

type UnexpectedSeparatorError

type UnexpectedSeparatorError struct {
	Separator rune
}

func (*UnexpectedSeparatorError) Error

func (e *UnexpectedSeparatorError) Error() string

type UnknownVariableTypeError

type UnknownVariableTypeError struct {
	Variable any
}

func (*UnknownVariableTypeError) Error

func (e *UnknownVariableTypeError) Error() string

func (*UnknownVariableTypeError) Propagate

func (e *UnknownVariableTypeError) Propagate() bool

type VarSelectorTypeError

type VarSelectorTypeError struct {
	Variable any
}

func (*VarSelectorTypeError) Error

func (e *VarSelectorTypeError) Error() string

func (*VarSelectorTypeError) Propagate

func (e *VarSelectorTypeError) Propagate() bool

type VariableVisitor

type VariableVisitor interface {
	VisitWildcard(ctx context.Context, parameter any, next func(context.Context, []PathValue) error) error
	VisitRecursiveDescent(ctx context.Context, parameter any, next func(context.Context, []PathValue) error) error
	VisitRange(ctx context.Context, parameter any, min, max, step int, next func(context.Context, []PathValue) error) error
	VisitChild(ctx context.Context, parameter any, key any, next func(context.Context, PathValue) error) error
}

func DefaultVariableVisitor

func DefaultVariableVisitor() VariableVisitor

type VariableVisitorFuncs

type VariableVisitorFuncs struct {
	VisitWildcardFunc         func(ctx context.Context, parameter any, next func(context.Context, []PathValue) error) error
	VisitRecursiveDescentFunc func(ctx context.Context, parameter any, next func(context.Context, []PathValue) error) error
	VisitRangeFunc            func(ctx context.Context, parameter any, min, max, step int, next func(context.Context, []PathValue) error) error
	VisitChildFunc            func(ctx context.Context, parameter any, key any, next func(context.Context, PathValue) error) error
}

func (VariableVisitorFuncs) VisitChild

func (vf VariableVisitorFuncs) VisitChild(c context.Context, v, key any, next func(context.Context, PathValue) error) error

func (VariableVisitorFuncs) VisitRange

func (vf VariableVisitorFuncs) VisitRange(c context.Context, v any, min, max, step int, next func(context.Context, []PathValue) error) error

func (VariableVisitorFuncs) VisitRecursiveDescent

func (vf VariableVisitorFuncs) VisitRecursiveDescent(c context.Context, v any, next func(context.Context, []PathValue) error) error

func (VariableVisitorFuncs) VisitWildcard

func (vf VariableVisitorFuncs) VisitWildcard(c context.Context, v any, next func(context.Context, []PathValue) error) error

type WithInitialPath

type WithInitialPath struct{}

WithInitialPath allows the path selector characters '.', '[', and '(' to begin a selector instead of just '$' or '@' ('$' is implied).

func (WithInitialPath) ApplyToLanguageOptions

func (WithInitialPath) ApplyToLanguageOptions(target *LanguageOptions)

type WithMissingKeysAllowed

type WithMissingKeysAllowed struct{}

WithMissingKeysAllowed causes the parser not to return an error when a selector key is not present in the document.

func (WithMissingKeysAllowed) ApplyToLanguageOptions

func (WithMissingKeysAllowed) ApplyToLanguageOptions(target *LanguageOptions)

type WithPlaceholders

type WithPlaceholders struct{}

WithPlaceholders enables the wildcard placeholder feature.

func (WithPlaceholders) ApplyToLanguageOptions

func (WithPlaceholders) ApplyToLanguageOptions(target *LanguageOptions)

Directories

Path Synopsis
Package template implements the JSONPath template format used by kubectl.
Package template implements the JSONPath template format used by kubectl.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL