Class: JsonPath

Inherits:
Object
  • Object
show all
Defined in:
lib/jsonpath.rb,
lib/jsonpath/dig.rb,
lib/jsonpath/proxy.rb,
lib/jsonpath/parser.rb,
lib/jsonpath/version.rb,
lib/jsonpath/enumerable.rb

Overview

JsonPath: initializes the class with a given JsonPath and parses that path into a token array.

Defined Under Namespace

Modules: Dig Classes: Enumerable, Parser, Proxy

Constant Summary collapse

PATH_ALL =
'$..*'
MAX_NESTING_ALLOWED =
100
DEFAULT_OPTIONS =
{
  :default_path_leaf_to_null => false,
  :symbolize_keys => false,
  :use_symbols => false,
  :allow_send => true,
  :max_nesting => MAX_NESTING_ALLOWED
}
VERSION =
'1.1.5'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, opts = {}) ⇒ JsonPath



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/jsonpath.rb', line 27

def initialize(path, opts = {})
  @opts = DEFAULT_OPTIONS.merge(opts)
  set_max_nesting
  scanner = StringScanner.new(path.strip)
  @path = []
  until scanner.eos?
    if (token = scanner.scan(/\$\B|@\B|\*|\.\./))
      @path << token
    elsif (token = scanner.scan(/[$@\p{Alnum}:{}_ -]+/))
      @path << "['#{token}']"
    elsif (token = scanner.scan(/'(.*?)'/))
      @path << "[#{token}]"
    elsif (token = scanner.scan(/\[/))
      @path << find_matching_brackets(token, scanner)
    elsif (token = scanner.scan(/\]/))
      raise ArgumentError, 'unmatched closing bracket'
    elsif (token = scanner.scan(/\(.*\)/))
      @path << token
    elsif scanner.scan(/\./)
      nil
    elsif (token = scanner.scan(/[><=] \d+/))
      @path.last << token
    elsif (token = scanner.scan(/./))
      @path.last << token
    else
      raise ArgumentError, "character '#{scanner.peek(1)}' not supported in query"
    end
  end
end

Instance Attribute Details

#pathObject

Returns the value of attribute path.



25
26
27
# File 'lib/jsonpath.rb', line 25

def path
  @path
end

Class Method Details

.construct_path(table_row) ⇒ Object



116
117
118
119
120
121
122
# File 'lib/jsonpath.rb', line 116

def self.construct_path(table_row)
  if table_row[:index]
    return table_row[:root_key] + '['+ table_row[:index].to_s + ']'
  else
    return table_row[:root_key] + '.'+ table_row[:key]
  end
end

.fetch_all_path(obj) ⇒ Object



91
92
93
94
95
# File 'lib/jsonpath.rb', line 91

def self.fetch_all_path(obj)
  all_paths = ['$']
  find_path(obj, '$', all_paths, obj.class == Array)
  return all_paths
end

.find_path(obj, root_key, all_paths, is_array = false) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/jsonpath.rb', line 97

def self.find_path(obj, root_key, all_paths, is_array = false)
  obj.each do |key, value|
    table_params = { key: key, root_key: root_key}
    is_loop = value.class == Array || value.class == Hash
    if is_loop
      path_exp = construct_path(table_params)
      all_paths << path_exp
      find_path(value, path_exp, all_paths, value.class == Array)
    elsif is_array
      table_params[:index] = obj.find_index(key)
      path_exp = construct_path(table_params)
      find_path(key, path_exp, all_paths, key.class == Array) if key.class == Hash || key.class == Array
      all_paths << path_exp
    else
      all_paths << construct_path(table_params)
    end
  end
end

.for(obj_or_str) ⇒ Object



138
139
140
# File 'lib/jsonpath.rb', line 138

def self.for(obj_or_str)
  Proxy.new(process_object(obj_or_str))
end

.on(obj_or_str, path, opts = {}) ⇒ Object



134
135
136
# File 'lib/jsonpath.rb', line 134

def self.on(obj_or_str, path, opts = {})
  new(path, opts).on(process_object(obj_or_str))
end

Instance Method Details

#enum_on(obj_or_str, mode = nil) ⇒ Object Also known as: []



128
129
130
131
# File 'lib/jsonpath.rb', line 128

def enum_on(obj_or_str, mode = nil)
  JsonPath::Enumerable.new(self, self.class.process_object(obj_or_str, @opts), mode,
                           @opts)
end

#find_matching_brackets(token, scanner) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/jsonpath.rb', line 57

def find_matching_brackets(token, scanner)
  count = 1
  until count.zero?
    if (t = scanner.scan(/\[/))
      token << t
      count += 1
    elsif (t = scanner.scan(/\]/))
      token << t
      count -= 1
    elsif (t = scanner.scan(/[^\[\]]+/))
      token << t
    elsif scanner.eos?
      raise ArgumentError, 'unclosed bracket'
    end
  end
  token
end

#first(obj_or_str, *args) ⇒ Object



124
125
126
# File 'lib/jsonpath.rb', line 124

def first(obj_or_str, *args)
  enum_on(obj_or_str).first(*args)
end

#join(join_path) ⇒ Object



75
76
77
78
79
# File 'lib/jsonpath.rb', line 75

def join(join_path)
  res = deep_clone
  res.path += JsonPath.new(join_path).path
  res
end

#on(obj_or_str, opts = {}) ⇒ Object



81
82
83
84
85
86
87
88
89
# File 'lib/jsonpath.rb', line 81

def on(obj_or_str, opts = {})
  a = enum_on(obj_or_str).to_a
  if symbolize_keys?(opts)
    a.map! do |e|
      e.each_with_object({}) { |(k, v), memo| memo[k.to_sym] = v; }
    end
  end
  a
end