path.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package json
  2. import (
  3. "reflect"
  4. "github.com/goccy/go-json/internal/decoder"
  5. )
  6. // CreatePath creates JSON Path.
  7. //
  8. // JSON Path rule
  9. // $ : root object or element. The JSON Path format must start with this operator, which refers to the outermost level of the JSON-formatted string.
  10. // . : child operator. You can identify child values using dot-notation.
  11. // .. : recursive descent.
  12. // [] : subscript operator. If the JSON object is an array, you can use brackets to specify the array index.
  13. // [*] : all objects/elements for array.
  14. //
  15. // Reserved words must be properly escaped when included in Path.
  16. //
  17. // Escape Rule
  18. // single quote style escape: e.g.) `$['a.b'].c`
  19. // double quote style escape: e.g.) `$."a.b".c`
  20. func CreatePath(p string) (*Path, error) {
  21. path, err := decoder.PathString(p).Build()
  22. if err != nil {
  23. return nil, err
  24. }
  25. return &Path{path: path}, nil
  26. }
  27. // Path represents JSON Path.
  28. type Path struct {
  29. path *decoder.Path
  30. }
  31. // RootSelectorOnly whether only the root selector ($) is used.
  32. func (p *Path) RootSelectorOnly() bool {
  33. return p.path.RootSelectorOnly
  34. }
  35. // UsedSingleQuotePathSelector whether single quote-based escaping was done when building the JSON Path.
  36. func (p *Path) UsedSingleQuotePathSelector() bool {
  37. return p.path.SingleQuotePathSelector
  38. }
  39. // UsedSingleQuotePathSelector whether double quote-based escaping was done when building the JSON Path.
  40. func (p *Path) UsedDoubleQuotePathSelector() bool {
  41. return p.path.DoubleQuotePathSelector
  42. }
  43. // Extract extracts a specific JSON string.
  44. func (p *Path) Extract(data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) {
  45. return extractFromPath(p, data, optFuncs...)
  46. }
  47. // PathString returns original JSON Path string.
  48. func (p *Path) PathString() string {
  49. return p.path.String()
  50. }
  51. // Unmarshal extract and decode the value of the part corresponding to JSON Path from the input data.
  52. func (p *Path) Unmarshal(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
  53. contents, err := extractFromPath(p, data, optFuncs...)
  54. if err != nil {
  55. return err
  56. }
  57. results := make([]interface{}, 0, len(contents))
  58. for _, content := range contents {
  59. var result interface{}
  60. if err := Unmarshal(content, &result); err != nil {
  61. return err
  62. }
  63. results = append(results, result)
  64. }
  65. if err := decoder.AssignValue(reflect.ValueOf(results), reflect.ValueOf(v)); err != nil {
  66. return err
  67. }
  68. return nil
  69. }
  70. // Get extract and substitute the value of the part corresponding to JSON Path from the input value.
  71. func (p *Path) Get(src, dst interface{}) error {
  72. return p.path.Get(reflect.ValueOf(src), reflect.ValueOf(dst))
  73. }