jsonpath 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/lib/jsonpath/parser.rb +22 -14
- data/lib/jsonpath/proxy.rb +2 -2
- data/lib/jsonpath/version.rb +1 -1
- data/test/test_jsonpath.rb +29 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 762aacec760a67a4097f47df701a1cec0f3f524ae016a2b724873c625c25672d
|
4
|
+
data.tar.gz: a3076196bc9d30f4cad3ee9c0ab3d58f9bedef4b7d17d7934e7e930c351ee1c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7894391f0693b7ebb3f3d8bca20dcf2eeb54af85e6ca268ff75fe120c64ae5e8ff09fa9a7b82cacbb8a5776d03dfa0f9bcc1f4716eea63988910cbb501d64236
|
7
|
+
data.tar.gz: c0f5c57d5c527a432a1c02fa728e32f8f8a7009efd0a31778b2766d97eba1e752ec1779e2d725fc233731f64541be72c9e896a511f312f8b5e3a4a1ed3e31a8d
|
data/.gitignore
CHANGED
data/lib/jsonpath/parser.rb
CHANGED
@@ -46,18 +46,29 @@ class JsonPath
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
#
|
49
|
+
# Using a scanner break down the individual expressions and determine if
|
50
50
|
# there is a match in the JSON for it or not.
|
51
51
|
def parse_exp(exp)
|
52
52
|
exp = exp.sub(/@/, '').gsub(/^\(/, '').gsub(/\)$/, '').tr('"', '\'').strip
|
53
|
+
exp.scan(/^\[(\d+)\]/) do |i|
|
54
|
+
next if i.empty?
|
55
|
+
|
56
|
+
index = Integer(i[0])
|
57
|
+
raise ArgumentError, 'Node does not appear to be an array.' unless @_current_node.is_a?(Array)
|
58
|
+
raise ArgumentError, "Index out of bounds for nested array. Index: #{index}" if @_current_node.size < index
|
59
|
+
|
60
|
+
@_current_node = @_current_node[index]
|
61
|
+
# Remove the extra '' and the index.
|
62
|
+
exp = exp.gsub(/^\[\d+\]|\[''\]/, '')
|
63
|
+
end
|
53
64
|
scanner = StringScanner.new(exp)
|
54
65
|
elements = []
|
55
66
|
until scanner.eos?
|
56
|
-
if t = scanner.scan(/\['[a-zA-Z
|
67
|
+
if (t = scanner.scan(/\['[a-zA-Z@&*\/$%^?_]+'\]|\.[a-zA-Z0-9_]+[?!]?/))
|
57
68
|
elements << t.gsub(/[\[\]'\.]|\s+/, '')
|
58
|
-
elsif t = scanner.scan(/(\s+)?[<>=!\-+][=~]?(\s+)?/)
|
69
|
+
elsif (t = scanner.scan(/(\s+)?[<>=!\-+][=~]?(\s+)?/))
|
59
70
|
operator = t
|
60
|
-
elsif t = scanner.scan(/(\s+)?'?.*'?(\s+)?/)
|
71
|
+
elsif (t = scanner.scan(/(\s+)?'?.*'?(\s+)?/))
|
61
72
|
# If we encounter a node which does not contain `'` it means
|
62
73
|
# that we are dealing with a boolean type.
|
63
74
|
operand = if t == 'true'
|
@@ -67,8 +78,8 @@ class JsonPath
|
|
67
78
|
else
|
68
79
|
operator.to_s.strip == '=~' ? t.to_regexp : t.gsub(%r{^'|'$}, '').strip
|
69
80
|
end
|
70
|
-
elsif t = scanner.scan(/\/\w+\//)
|
71
|
-
elsif t = scanner.scan(/.*/)
|
81
|
+
elsif (t = scanner.scan(/\/\w+\//))
|
82
|
+
elsif (t = scanner.scan(/.*/))
|
72
83
|
raise "Could not process symbol: #{t}"
|
73
84
|
end
|
74
85
|
end
|
@@ -78,9 +89,7 @@ class JsonPath
|
|
78
89
|
elsif @_current_node.is_a?(Hash)
|
79
90
|
@_current_node.dig(*elements)
|
80
91
|
else
|
81
|
-
elements.inject(@_current_node
|
82
|
-
agg.__send__(key)
|
83
|
-
end
|
92
|
+
elements.inject(@_current_node, &:__send__)
|
84
93
|
end
|
85
94
|
|
86
95
|
return (el ? true : false) if el.nil? || operator.nil?
|
@@ -117,10 +126,9 @@ class JsonPath
|
|
117
126
|
top = top.map(&:strip)
|
118
127
|
res = bool_or_exp(top.shift)
|
119
128
|
top.each_with_index do |item, index|
|
120
|
-
|
121
|
-
when '&&'
|
129
|
+
if item == '&&'
|
122
130
|
res &&= top[index + 1]
|
123
|
-
|
131
|
+
elsif item == '||'
|
124
132
|
res ||= top[index + 1]
|
125
133
|
end
|
126
134
|
end
|
@@ -129,9 +137,9 @@ class JsonPath
|
|
129
137
|
# and the closing index will be the last index. To avoid
|
130
138
|
# off-by-one errors we simply return the result at that point.
|
131
139
|
if closing_index + 1 >= str.length && opening_index == 0
|
132
|
-
|
140
|
+
res.to_s
|
133
141
|
else
|
134
|
-
|
142
|
+
"#{str[0..opening_index - 1]}#{res}#{str[closing_index + 1..str.length]}"
|
135
143
|
end
|
136
144
|
end
|
137
145
|
|
data/lib/jsonpath/proxy.rb
CHANGED
@@ -10,11 +10,11 @@ class JsonPath
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def gsub(path, replacement = nil, &replacement_block)
|
13
|
-
_gsub(_deep_copy, path, replacement ? proc
|
13
|
+
_gsub(_deep_copy, path, replacement ? proc(&method(:replacement)) : replacement_block)
|
14
14
|
end
|
15
15
|
|
16
16
|
def gsub!(path, replacement = nil, &replacement_block)
|
17
|
-
_gsub(@obj, path, replacement ? proc
|
17
|
+
_gsub(@obj, path, replacement ? proc(&method(:replacement)) : replacement_block)
|
18
18
|
end
|
19
19
|
|
20
20
|
def delete(path = JsonPath::PATH_ALL)
|
data/lib/jsonpath/version.rb
CHANGED
data/test/test_jsonpath.rb
CHANGED
@@ -804,6 +804,35 @@ class TestJsonpath < MiniTest::Unit::TestCase
|
|
804
804
|
assert_equal expected, JsonPath.for(a.to_json).delete('$.itemList[1:6:2]').to_hash
|
805
805
|
end
|
806
806
|
|
807
|
+
def test_nested_values
|
808
|
+
json = '
|
809
|
+
{
|
810
|
+
"phoneNumbers": [
|
811
|
+
[{
|
812
|
+
"type" : "iPhone",
|
813
|
+
"number": "0123-4567-8888"
|
814
|
+
}],
|
815
|
+
[{
|
816
|
+
"type" : "home",
|
817
|
+
"number": "0123-4567-8910"
|
818
|
+
}]
|
819
|
+
]
|
820
|
+
}
|
821
|
+
'.to_json
|
822
|
+
assert_equal [[{ 'type' => 'home', 'number' => '0123-4567-8910' }]], JsonPath.on(json, "$.phoneNumbers[?(@[0].type == 'home')]")
|
823
|
+
assert_equal [], JsonPath.on(json, "$.phoneNumbers[?(@[2].type == 'home')]")
|
824
|
+
json = '
|
825
|
+
{
|
826
|
+
"phoneNumbers":
|
827
|
+
{
|
828
|
+
"type" : "iPhone",
|
829
|
+
"number": "0123-4567-8888"
|
830
|
+
}
|
831
|
+
}
|
832
|
+
'.to_json
|
833
|
+
assert_equal [], JsonPath.on(json, "$.phoneNumbers[?(@[0].type == 'home')]")
|
834
|
+
end
|
835
|
+
|
807
836
|
def example_object
|
808
837
|
{ 'store' => {
|
809
838
|
'book' => [
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonpath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Hull
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-05-
|
12
|
+
date: 2019-05-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0'
|
160
160
|
requirements: []
|
161
|
-
rubygems_version: 3.0.
|
161
|
+
rubygems_version: 3.0.3
|
162
162
|
signing_key:
|
163
163
|
specification_version: 4
|
164
164
|
summary: Ruby implementation of http://goessner.net/articles/JsonPath/
|