jsonpath 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - jruby
6
+ - rbx-18mode
data/README.md CHANGED
@@ -1,9 +1,16 @@
1
- # Jsonpath
1
+ # JsonPath
2
2
 
3
3
  This is an implementation of http://goessner.net/articles/JsonPath/.
4
4
 
5
+ ## What is JsonPath?
6
+
7
+ JsonPath is a way of addressing elements within a JSON object. Similar to xpath of yore, JsonPath lets you
8
+ traverse a json object and manipulate or access it.
9
+
5
10
  ## Usage
6
11
 
12
+ ### Command-line
13
+
7
14
  There is stand-alone usage through the binary `jsonpath`
8
15
 
9
16
  jsonpath [expression] (file|string)
@@ -11,52 +18,115 @@ There is stand-alone usage through the binary `jsonpath`
11
18
  If you omit the second argument, it will read stdin, assuming one valid JSON object
12
19
  per line. Expression must be a valid jsonpath expression.
13
20
 
14
- As well, you can include it as a library.
21
+ ### Library
22
+
23
+ To use JsonPath as a library simply include and get goin'!
24
+
25
+ ~~~~~ {ruby}
26
+ require 'jsonpath'
27
+
28
+ json = <<-HERE_DOC
29
+ {"store":
30
+ {"bicycle":
31
+ {"price":19.95, "color":"red"},
32
+ "book":[
33
+ {"price":8.95, "category":"reference", "title":"Sayings of the Century", "author":"Nigel Rees"},
34
+ {"price":12.99, "category":"fiction", "title":"Sword of Honour", "author":"Evelyn Waugh"},
35
+ {"price":8.99, "category":"fiction", "isbn":"0-553-21311-3", "title":"Moby Dick", "author":"Herman Melville","color":"blue"},
36
+ {"price":22.99, "category":"fiction", "isbn":"0-395-19395-8", "title":"The Lord of the Rings", "author":"Tolkien"}
37
+ ]
38
+ }
39
+ }
40
+ HERE_DOC
41
+ ~~~~~
42
+
43
+ Now that we have a JSON object, let's get all the prices present in the object. We create an object for the path
44
+ in the following way.
45
+
46
+ ~~~~~ {ruby}
47
+ path = JsonPath.new('$..price')
48
+ ~~~~~
49
+
50
+ Now that we have a path, let's apply it to the object above.
51
+
52
+ ~~~~~ {ruby}
53
+ path.on(json)
54
+ # => [19.95, 8.95, 12.99, 8.99, 22.99]
55
+ ~~~~~
56
+
57
+ Or on some other object ...
58
+
59
+ ~~~~~ {ruby}
60
+ path.on('{"books":[{"title":"A Tale of Two Somethings","price":18.88}]}')
61
+ # => [18.88]
62
+ ~~~~~
63
+
64
+ You can also just combine this into one mega-call with the convenient `JsonPath.on` method.
15
65
 
16
66
  ~~~~~ {ruby}
17
- object = JSON.parse(<<-HERE_DOC)
18
- {"store":
19
- {"bicycle":
20
- {"price":19.95, "color":"red"},
21
- "book":[
22
- {"price":8.95, "category":"reference", "title":"Sayings of the Century", "author":"Nigel Rees"},
23
- {"price":12.99, "category":"fiction", "title":"Sword of Honour", "author":"Evelyn Waugh"},
24
- {"price":8.99, "category":"fiction", "isbn":"0-553-21311-3", "title":"Moby Dick", "author":"Herman Melville"},
25
- {"price":22.99, "category":"fiction", "isbn":"0-395-19395-8", "title":"The Lord of the Rings", "author":"J. R. R. Tolkien"}
26
- ]
27
- }
28
- }
29
- HERE_DOC
67
+ JsonPath.on(json, '$..author')
68
+ # => ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "Tolkien"]
69
+ ~~~~~
30
70
 
31
- JsonPath.new('$..price').on(object)
32
- # => [19.95, 8.95, 12.99, 8.99, 22.99]
71
+ Of course the full JsonPath syntax is supported, such as array slices
72
+
73
+ ~~~~~ {ruby}
74
+ JsonPath.new('$..book[::2]').on(json)
75
+ # => [
76
+ # {"price"=>8.95, "category"=>"reference", "author"=>"Nigel Rees", "title"=>"Sayings of the Century"},
77
+ # {"price"=>8.99, "category"=>"fiction", "author"=>"Herman Melville", "title"=>"Moby Dick", "isbn"=>"0-553-21311-3"}
78
+ # ]
79
+ ~~~~~
80
+
81
+ ...and evals.
82
+
83
+ ~~~~~ {ruby}
84
+ JsonPath.new('$..price[?(@ < 20)]').on(json)
85
+ # => [8.95, 8.99]
86
+ ~~~~~
33
87
 
34
- JsonPath.on(object, '$..author')
35
- # => ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"]
88
+ There is a convenience method, `#first` that gives you the first element for a JSON object and path.
36
89
 
37
- JsonPath.new('$..book[::2]').on(object)
38
- # => [{"price"=>8.95, "category"=>"reference", "author"=>"Nigel Rees", "title"=>"Sayings of the Century"}, {"price"=>8.99, "category"=>"fiction", "author"=>"Herman Melville", "title"=>"Moby Dick", "isbn"=>"0-553-21311-3"}]
90
+ ~~~~~ {ruby}
91
+ JsonPath.new('$..color').first(object)
92
+ # => "red"
93
+ ~~~~~
39
94
 
40
- JsonPath.new('$..color').first(object)
41
- # => "red"
95
+ As well, we can directly create an `Enumerable` at any time using `#[]`.
42
96
 
43
- # Lazy enumeration - only needs to find the first two matches
44
- JsonPath.new('$..price').enum_on(object).each do |match|
45
- break price if price < 15.0
46
- end
47
- # => 8.95
97
+ ~~~~~ {ruby}
98
+ enum = JsonPath.new('$..color')[object]
99
+ # => #<JsonPath::Enumerable:...>
100
+ enum.first
101
+ # => "red"
102
+ enum.any?{ |c| c == 'red' }
103
+ # => true
48
104
  ~~~~~
49
105
 
50
106
  You can optionally prevent eval from being called on sub-expressions by passing in :allow_eval => false to the constructor.
51
107
 
52
- If you'd like to do substitution in a json object, do this:
108
+ ### Manipulation
109
+
110
+ If you'd like to do substitution in a json object, you can use `#gsub` or `#gsub!` to modify the object in place.
53
111
 
54
112
  ~~~~~ {ruby}
55
- JsonPath.for({'test' => 'time'}).gsub('$..test') {|v| v << v}
113
+ JsonPath.for('{"candy":"lollipop"}').gsub('$..candy') {|v| "big turks" }.to_hash
56
114
  ~~~~~
57
115
 
58
116
  The result will be
59
117
 
60
118
  ~~~~~ {ruby}
61
- {'test' => 'timetime'}
119
+ {'candy' => 'big turks'}
120
+ ~~~~~
121
+
122
+ If you'd like to remove all nil keys, you can use `#compact` and `#compact!`. To remove all keys under a certain path, use `#delete` or `#delete!`. You can even chain these methods together as follows:
123
+
124
+ ~~~~~ {ruby}
125
+ json = '{"candy":"lollipop","noncandy":null,"other":"things"}'
126
+ o = JsonPath.for(json).
127
+ gsub('$..candy') {|v| "big turks" }.
128
+ compact.
129
+ delete('$..other').
130
+ to_hash
131
+ # => {"candy" => "big turks"}
62
132
  ~~~~~
data/Rakefile CHANGED
@@ -16,3 +16,5 @@ task :test do
16
16
  require 'jsonpath'
17
17
  Dir['./test/**/test_*.rb'].each { |test| require test }
18
18
  end
19
+
20
+ task :default => :test
data/lib/jsonpath.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  require 'strscan'
2
+ require 'multi_json'
2
3
  require 'jsonpath/proxy'
3
4
  require 'jsonpath/enumerable'
4
5
  require 'jsonpath/version'
5
6
 
6
7
  class JsonPath
7
8
 
9
+ PATH_ALL = '$..*'
10
+
8
11
  attr_reader :path
9
12
 
10
13
  def initialize(path, opts = nil)
@@ -49,23 +52,29 @@ class JsonPath
49
52
  end
50
53
  end
51
54
 
52
- def on(object)
53
- enum_on(object).to_a
55
+ def on(obj_or_str)
56
+ enum_on(obj_or_str).to_a
57
+ end
58
+
59
+ def first(obj_or_str, *args)
60
+ enum_on(obj_or_str).first(*args)
54
61
  end
55
62
 
56
- def first(object)
57
- enum_on(object).first
63
+ def enum_on(obj_or_str, mode = nil)
64
+ JsonPath::Enumerable.new(self, self.class.process_object(obj_or_str), mode, @opts)
58
65
  end
66
+ alias_method :[], :enum_on
59
67
 
60
- def enum_on(object)
61
- JsonPath::Enumerable.new(self, object, @opts)
68
+ def self.on(obj_or_str, path, opts = nil)
69
+ self.new(path, opts).on(process_object(obj_or_str))
62
70
  end
63
71
 
64
- def self.on(object, path, opts = nil)
65
- self.new(path, opts).on(object)
72
+ def self.for(obj_or_str)
73
+ Proxy.new(process_object(obj_or_str))
66
74
  end
67
75
 
68
- def self.for(obj)
69
- Proxy.new(obj)
76
+ private
77
+ def self.process_object(obj_or_str)
78
+ obj_or_str.is_a?(String) ? MultiJson.decode(obj_or_str) : obj_or_str
70
79
  end
71
80
  end
@@ -4,14 +4,14 @@ class JsonPath
4
4
  attr_reader :allow_eval
5
5
  alias_method :allow_eval?, :allow_eval
6
6
 
7
- def initialize(path, object, options = nil)
8
- @path, @object, @options = path.path, object, options
7
+ def initialize(path, object, mode, options = nil)
8
+ @path, @object, @mode, @options = path.path, object, mode, options
9
9
  @allow_eval = @options && @options.key?(:allow_eval) ? @options[:allow_eval] : true
10
- @mode = @options && @options[:mode]
11
10
  end
12
11
 
13
12
  def each(context = @object, key = nil, pos = 0, &blk)
14
13
  node = key ? context[key] : context
14
+ @_current_node = node
15
15
  return yield_value(blk, context, key) if pos == @path.size
16
16
  case expr = @path[pos]
17
17
  when '*', '..'
@@ -29,14 +29,21 @@ class JsonPath
29
29
  each(node, k, pos + 1, &blk) if node.key?(k)
30
30
  end
31
31
  when ??
32
- (node.is_a?(Hash) ? node.keys : (0..node.size)).each do |e|
33
- subenum = ::JsonPath.new(sub_path[2, sub_path.size - 3]).on(node[e])
34
- each(node, e, pos + 1, &blk) if subenum.any?{|n| true}
32
+ raise "Cannot use ?(...) unless eval is enabled" unless allow_eval?
33
+ case node
34
+ when Hash, Array
35
+ (node.is_a?(Hash) ? node.keys : (0..node.size)).each do |e|
36
+ each(node, e, pos + 1) { |n|
37
+ @_current_node = n
38
+ yield n if process_function_or_literal(sub_path[1, sub_path.size - 1])
39
+ }
40
+ end
41
+ else
42
+ yield node if process_function_or_literal(sub_path[1, sub_path.size - 1])
35
43
  end
36
44
  else
37
45
  if node.is_a?(Array)
38
- @obj = node
39
- array_args = sub_path.gsub('@','@obj').split(':')
46
+ array_args = sub_path.split(':')
40
47
  start_idx = process_function_or_literal(array_args[0], 0)
41
48
  next unless start_idx
42
49
  start_idx %= node.size
@@ -67,10 +74,13 @@ class JsonPath
67
74
 
68
75
  private
69
76
  def yield_value(blk, context, key)
70
- @substitute_with = nil
71
77
  case @mode
72
78
  when nil
73
79
  blk.call(key ? context[key] : context)
80
+ when :compact
81
+ context.delete(key) if key && context[key].nil?
82
+ when :delete
83
+ context.delete(key) if key
74
84
  when :substitute
75
85
  if key
76
86
  context[key] = blk.call(context[key])
@@ -80,11 +90,14 @@ class JsonPath
80
90
  end
81
91
  end
82
92
 
83
- def process_function_or_literal(exp, default)
93
+ def process_function_or_literal(exp, default = nil)
84
94
  if exp.nil?
85
95
  default
86
96
  elsif exp[0] == ?(
87
- allow_eval? ? eval(exp) : nil
97
+ #p @_current_node
98
+ #p exp.gsub(/@/, '@_current_node')
99
+ #p eval(exp.gsub(/@/, '@_current_node'))
100
+ allow_eval? ? @_current_node && eval(exp.gsub(/@/, '@_current_node')) : nil
88
101
  elsif exp.empty?
89
102
  default
90
103
  else
@@ -1,25 +1,54 @@
1
1
  class JsonPath
2
2
  class Proxy
3
+ attr_reader :obj
4
+ alias_method :to_hash, :obj
5
+
3
6
  def initialize(obj)
4
7
  @obj = obj
5
8
  end
6
9
 
7
10
  def gsub(path, replacement = nil, &replacement_block)
8
- _gsub(deep_copy, path, replacement ? proc{replacement} : replacement_block)
11
+ _gsub(_deep_copy, path, replacement ? proc{replacement} : replacement_block)
9
12
  end
10
13
 
11
14
  def gsub!(path, replacement = nil, &replacement_block)
12
15
  _gsub(@obj, path, replacement ? proc{replacement} : replacement_block)
13
16
  end
14
17
 
18
+ def delete(path = JsonPath::PATH_ALL)
19
+ _delete(_deep_copy, path)
20
+ end
21
+
22
+ def delete!(path = JsonPath::PATH_ALL)
23
+ _delete(@obj, path)
24
+ end
25
+
26
+ def compact(path = JsonPath::PATH_ALL)
27
+ _compact(_deep_copy, path)
28
+ end
29
+
30
+ def compact!(path = JsonPath::PATH_ALL)
31
+ _compact(@obj, path)
32
+ end
33
+
15
34
  private
16
- def deep_copy
35
+ def _deep_copy
17
36
  Marshal::load(Marshal::dump(@obj))
18
37
  end
19
38
 
20
39
  def _gsub(obj, path, replacement)
21
- JsonPath.new(path, :mode => :substitute).enum_on(obj).each(&replacement)
22
- obj
40
+ JsonPath.new(path)[obj, :substitute].each(&replacement)
41
+ Proxy.new(obj)
42
+ end
43
+
44
+ def _delete(obj, path)
45
+ JsonPath.new(path)[obj, :delete].each
46
+ Proxy.new(obj)
47
+ end
48
+
49
+ def _compact(obj, path)
50
+ JsonPath.new(path)[obj, :compact].each
51
+ Proxy.new(obj)
23
52
  end
24
53
  end
25
54
  end
@@ -1,3 +1,3 @@
1
1
  class JsonPath
2
- VERSION = '0.4.2' unless const_defined?(:VERSION)
2
+ VERSION = '0.5.0'
3
3
  end
@@ -46,7 +46,12 @@ class TestJsonpath < MiniTest::Unit::TestCase
46
46
  assert_equal [@object['store']['book'][0], @object['store']['book'][2]], JsonPath.new("$..book[?(@['price'] < 10)]").on(@object)
47
47
  assert_equal [@object['store']['book'][0], @object['store']['book'][2]], JsonPath.new("$..book[?(@['price'] == 9)]").on(@object)
48
48
  assert_equal [@object['store']['book'][3]], JsonPath.new("$..book[?(@['price'] > 20)]").on(@object)
49
- assert_equal [@object['store']['book'][2], @object['store']['book'][3]], JsonPath.new("$..book[?(@.isbn)]").on(@object)
49
+ end
50
+
51
+ if RUBY_VERSION[/^1\.9/]
52
+ def test_recognize_filters_on_val
53
+ assert_equal [@object['store']['book'][1]['price'], @object['store']['book'][3]['price'], @object['store']['bicycle']['price']], JsonPath.new("$..price[?(@ > 10)]").on(@object)
54
+ end
50
55
  end
51
56
 
52
57
  def test_no_eval
@@ -87,7 +92,7 @@ class TestJsonpath < MiniTest::Unit::TestCase
87
92
  @object2['store']['book'][1]['price'] += 10
88
93
  @object2['store']['book'][2]['price'] += 10
89
94
  @object2['store']['book'][3]['price'] += 10
90
- assert_equal @object2, JsonPath.for(@object).gsub('$..price') { |p| p + 10 }
95
+ assert_equal @object2, JsonPath.for(@object).gsub('$..price') { |p| p + 10 }.to_hash
91
96
  end
92
97
 
93
98
  def test_gsub!
@@ -105,6 +110,18 @@ class TestJsonpath < MiniTest::Unit::TestCase
105
110
  assert_equal h, @object
106
111
  end
107
112
 
113
+ def test_compact
114
+ h = {'hi' => 'there', 'you' => nil}
115
+ JsonPath.for(h).compact!
116
+ assert_equal({'hi' => 'there'}, h)
117
+ end
118
+
119
+ def test_delete
120
+ h = {'hi' => 'there', 'you' => nil}
121
+ JsonPath.for(h).delete!('*.hi')
122
+ assert_equal({'you' => nil}, h)
123
+ end
124
+
108
125
  def example_object
109
126
  { "store"=> {
110
127
  "book" => [
metadata CHANGED
@@ -1,123 +1,94 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: jsonpath
3
- version: !ruby/object:Gem::Version
4
- hash: 11
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 4
9
- - 2
10
- version: 0.4.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Joshua Hull
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-07-26 00:00:00 -07:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2012-02-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: multi_json
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70241925955780 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
33
22
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: code_stats
37
23
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70241925955780
25
+ - !ruby/object:Gem::Dependency
26
+ name: code_stats
27
+ requirement: &70241925955060 !ruby/object:Gem::Requirement
39
28
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
47
33
  type: :development
48
- version_requirements: *id002
49
- - !ruby/object:Gem::Dependency
50
- name: rake
51
34
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70241925955060
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70241925954420 !ruby/object:Gem::Requirement
53
39
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- hash: 3
58
- segments:
59
- - 0
60
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
61
44
  type: :development
62
- version_requirements: *id003
63
- - !ruby/object:Gem::Dependency
64
- name: minitest
65
45
  prerelease: false
66
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70241925954420
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest
49
+ requirement: &70241925953660 !ruby/object:Gem::Requirement
67
50
  none: false
68
- requirements:
51
+ requirements:
69
52
  - - ~>
70
- - !ruby/object:Gem::Version
71
- hash: 7
72
- segments:
73
- - 2
74
- - 2
75
- - 0
53
+ - !ruby/object:Gem::Version
76
54
  version: 2.2.0
77
55
  type: :development
78
- version_requirements: *id004
79
- - !ruby/object:Gem::Dependency
80
- name: phocus
81
56
  prerelease: false
82
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *70241925953660
58
+ - !ruby/object:Gem::Dependency
59
+ name: phocus
60
+ requirement: &70241925953100 !ruby/object:Gem::Requirement
83
61
  none: false
84
- requirements:
85
- - - ">="
86
- - !ruby/object:Gem::Version
87
- hash: 3
88
- segments:
89
- - 0
90
- version: "0"
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
91
66
  type: :development
92
- version_requirements: *id005
93
- - !ruby/object:Gem::Dependency
94
- name: bundler
95
67
  prerelease: false
96
- requirement: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *70241925953100
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: &70241926010900 !ruby/object:Gem::Requirement
97
72
  none: false
98
- requirements:
73
+ requirements:
99
74
  - - ~>
100
- - !ruby/object:Gem::Version
101
- hash: 3
102
- segments:
103
- - 1
104
- - 0
105
- - 10
75
+ - !ruby/object:Gem::Version
106
76
  version: 1.0.10
107
77
  type: :development
108
- version_requirements: *id006
78
+ prerelease: false
79
+ version_requirements: *70241926010900
109
80
  description: Ruby implementation of http://goessner.net/articles/JsonPath/.
110
81
  email: joshbuddy@gmail.com
111
- executables:
82
+ executables:
112
83
  - jsonpath
113
84
  extensions: []
114
-
115
- extra_rdoc_files:
85
+ extra_rdoc_files:
116
86
  - README.md
117
- files:
87
+ files:
118
88
  - .gemtest
119
89
  - .gitignore
120
90
  - .rspec
91
+ - .travis.yml
121
92
  - Gemfile
122
93
  - README.md
123
94
  - Rakefile
@@ -129,39 +100,30 @@ files:
129
100
  - lib/jsonpath/version.rb
130
101
  - test/test_jsonpath.rb
131
102
  - test/test_jsonpath_bin.rb
132
- has_rdoc: true
133
103
  homepage: http://github.com/joshbuddy/jsonpath
134
104
  licenses: []
135
-
136
105
  post_install_message:
137
- rdoc_options:
106
+ rdoc_options:
138
107
  - --charset=UTF-8
139
- require_paths:
108
+ require_paths:
140
109
  - lib
141
- required_ruby_version: !ruby/object:Gem::Requirement
110
+ required_ruby_version: !ruby/object:Gem::Requirement
142
111
  none: false
143
- requirements:
144
- - - ">="
145
- - !ruby/object:Gem::Version
146
- hash: 3
147
- segments:
148
- - 0
149
- version: "0"
150
- required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
117
  none: false
152
- requirements:
153
- - - ">="
154
- - !ruby/object:Gem::Version
155
- hash: 3
156
- segments:
157
- - 0
158
- version: "0"
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
159
122
  requirements: []
160
-
161
123
  rubyforge_project: jsonpath
162
- rubygems_version: 1.6.2
124
+ rubygems_version: 1.8.15
163
125
  signing_key:
164
126
  specification_version: 3
165
127
  summary: Ruby implementation of http://goessner.net/articles/JsonPath/
166
128
  test_files: []
167
-
129
+ has_rdoc: