lib/jsonpath.rb in jsonpath-0.5.8 vs lib/jsonpath.rb in jsonpath-0.7.0
- old
+ new
@@ -2,61 +2,60 @@
require 'multi_json'
require 'jsonpath/proxy'
require 'jsonpath/enumerable'
require 'jsonpath/version'
+# JsonPath: initializes the class with a given JsonPath and parses that path
+# into a token array.
class JsonPath
+ PATH_ALL = '$..*'.freeze
- PATH_ALL = '$..*'
-
attr_accessor :path
def initialize(path, opts = nil)
@opts = opts
scanner = StringScanner.new(path)
@path = []
- while not scanner.eos?
- if token = scanner.scan(/\$/)
+ until scanner.eos?
+ if token = scanner.scan(/\$|@\B|\*|\.\./)
@path << token
- elsif token = scanner.scan(/@/)
- @path << token
- elsif token = scanner.scan(/[a-zA-Z0-9_-]+/)
+ elsif token = scanner.scan(/[\$@a-zA-Z0-9:_-]+/)
@path << "['#{token}']"
elsif token = scanner.scan(/'(.*?)'/)
@path << "[#{token}]"
elsif token = scanner.scan(/\[/)
- count = 1
- while !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
- @path << token
+ @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(/\*/)
- @path << token
elsif token = scanner.scan(/[><=] \d+/)
@path.last << token
elsif token = scanner.scan(/./)
@path.last << token
end
end
end
+ 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
+
def join(join_path)
res = deep_clone
res.path += JsonPath.new(join_path).path
res
end
@@ -68,22 +67,24 @@
def first(obj_or_str, *args)
enum_on(obj_or_str).first(*args)
end
def enum_on(obj_or_str, mode = nil)
- JsonPath::Enumerable.new(self, self.class.process_object(obj_or_str), mode, @opts)
+ JsonPath::Enumerable.new(self, self.class.process_object(obj_or_str), mode,
+ @opts)
end
alias_method :[], :enum_on
def self.on(obj_or_str, path, opts = nil)
- self.new(path, opts).on(process_object(obj_or_str))
+ new(path, opts).on(process_object(obj_or_str))
end
def self.for(obj_or_str)
Proxy.new(process_object(obj_or_str))
end
private
+
def self.process_object(obj_or_str)
obj_or_str.is_a?(String) ? MultiJson.decode(obj_or_str) : obj_or_str
end
def deep_clone