json_data_extractor 0.0.9 → 0.0.11
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/README.md +107 -32
- data/lib/json_data_extractor.rb +24 -1
- data/lib/src/configuration.rb +9 -0
- data/lib/src/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aeef2dddd8e11795c682d9db785b955164fbab87e4dc1c63843ba02a76b65905
|
4
|
+
data.tar.gz: e17a062f72e0ae56bc09b42ccaa237c12149b667b63dfb0e58a60dd3ea8e5830
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b574bc9f7c79a4405d7b86739e1bf50e0ccbc82f1016befedf3e5bbb0da040db263492ee8978cd3d83957546d47338980bcfba80770a620a9c637937675bad46
|
7
|
+
data.tar.gz: 2a83cf29049a8c4205851a83e12e0867f42ae684564c6bc7ae9e183b4399f9a2390f9be36724f137064bf8e76f74b30d977539fdb1c620972c05a949f19883f2
|
data/README.md
CHANGED
@@ -3,13 +3,15 @@
|
|
3
3
|
NOTE: This is still a very early beta.
|
4
4
|
|
5
5
|
Transform JSON data structures with the help of a simple schema and JsonPath expressions.
|
6
|
-
Use the JsonDataExtractor gem to extract and modify data from complex JSON structures using a
|
6
|
+
Use the JsonDataExtractor gem to extract and modify data from complex JSON structures using a
|
7
|
+
straightforward syntax
|
7
8
|
and a range of built-in or custom modifiers.
|
8
9
|
|
9
10
|
_Another try to make something for JSON that is XSLT for XML.
|
10
11
|
We transform one JSON into another JSON with the help of a third JSON!!!111!!eleventy!!_
|
11
12
|
|
12
|
-
Remap one JSON structure into another with some basic rules
|
13
|
+
Remap one JSON structure into another with some basic rules
|
14
|
+
and [jsonpath](https://github.com/joshbuddy/jsonpath).
|
13
15
|
|
14
16
|
Heavily inspired by [xml_data_extractor](https://github.com/monde-sistemas/xml_data_extractor).
|
15
17
|
|
@@ -32,8 +34,8 @@ Or install it yourself as:
|
|
32
34
|
## Usage
|
33
35
|
|
34
36
|
JsonDataExtractor allows you to remap one JSON structure into another with some basic rules
|
35
|
-
and [JSONPath](https://goessner.net/articles/JsonPath/) expressions. The process involves defining a
|
36
|
-
the input JSON structure to the desired output structure.
|
37
|
+
and [JSONPath](https://goessner.net/articles/JsonPath/) expressions. The process involves defining a
|
38
|
+
schema that maps the input JSON structure to the desired output structure.
|
37
39
|
|
38
40
|
We'll base our examples on the following source:
|
39
41
|
|
@@ -78,22 +80,24 @@ We'll base our examples on the following source:
|
|
78
80
|
|
79
81
|
### Defining a Schema
|
80
82
|
|
81
|
-
A schema consists of one or more mappings that specify how to extract data from the input JSON and
|
82
|
-
the output JSON.
|
83
|
+
A schema consists of one or more mappings that specify how to extract data from the input JSON and
|
84
|
+
where to place it in the output JSON.
|
83
85
|
|
84
|
-
Each mapping has a path field that specifies the JsonPath expression to use for data extraction, and
|
85
|
-
modifier field that specifies one or more modifiers to apply to the extracted data.
|
86
|
-
data in some way before placing it in the output JSON.
|
86
|
+
Each mapping has a path field that specifies the JsonPath expression to use for data extraction, and
|
87
|
+
an optional modifier field that specifies one or more modifiers to apply to the extracted data.
|
88
|
+
Modifiers are used to transform the data in some way before placing it in the output JSON.
|
87
89
|
|
88
|
-
Here's an example schema that extracts the authors and categories from a JSON structure similar to
|
89
|
-
|
90
|
+
Here's an example schema that extracts the authors and categories from a JSON structure similar to
|
91
|
+
the one used in the previous example:
|
90
92
|
|
91
|
-
```
|
92
|
-
|
93
|
-
authors:
|
94
|
-
path: $.store.book[*].author
|
95
|
-
modifier: downcase
|
96
|
-
|
93
|
+
```json
|
94
|
+
{
|
95
|
+
"authors": {
|
96
|
+
"path": "$.store.book[*].author",
|
97
|
+
"modifier": "downcase"
|
98
|
+
},
|
99
|
+
"categories": "$..category"
|
100
|
+
}
|
97
101
|
```
|
98
102
|
|
99
103
|
The resulting json will be:
|
@@ -116,23 +120,67 @@ The resulting json will be:
|
|
116
120
|
|
117
121
|
```
|
118
122
|
|
119
|
-
Modifiers
|
120
|
-
|
123
|
+
### Modifiers
|
124
|
+
|
125
|
+
Modifiers can be supplied on object creation and/or added later by calling `#add_modifier` method.
|
126
|
+
Please see specs for examples.
|
127
|
+
Modifiers allow you to perform transformations on the extracted data before it is returned. You can
|
128
|
+
use modifiers to clean up the data, format it, or apply any custom logic you need.
|
129
|
+
|
130
|
+
Modifiers can be defined in two ways: by providing a symbol corresponding to the name of the method
|
131
|
+
or lambda that should be called on each extracted value, or by providing an anonymous lambda. Here's
|
132
|
+
an example schema that uses both types of modifiers:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
schema = {
|
136
|
+
name: '$.name',
|
137
|
+
age: { path: '$.age', modifier: :to_i },
|
138
|
+
email: { path: '$.contact.email', modifiers: [:downcase, lambda { |email| email.gsub(/\s/, '') }] }
|
139
|
+
}
|
140
|
+
|
141
|
+
```
|
142
|
+
|
143
|
+
In this schema, the name value is simply extracted as-is. The age value is extracted from the JSON,
|
144
|
+
but it is modified with the `to_i` method, which converts the value to an integer. The email value
|
145
|
+
is extracted from a nested object, and then passed through two modifiers: first `downcase` is called
|
146
|
+
to convert the email address to all lowercase letters, and then an anonymous lambda is called to
|
147
|
+
remove any whitespace in the email address.
|
148
|
+
|
149
|
+
You can also define custom modifiers by passing a lambda to the `add_modifier` method on a
|
150
|
+
JsonDataExtractor instance:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
extractor = JsonDataExtractor.new(json_data)
|
154
|
+
extractor.add_modifier(:remove_newlines) { |value| value.gsub("\n", '') }
|
155
|
+
|
156
|
+
schema = {
|
157
|
+
name: 'name',
|
158
|
+
bio: { path: 'bio', modifiers: [:remove_newlines] }
|
159
|
+
}
|
160
|
+
|
161
|
+
results = extractor.extract(schema)
|
162
|
+
|
163
|
+
```
|
164
|
+
|
165
|
+
Modifiers are called in the order in which they are defined, so keep that in mind when defining your
|
166
|
+
schema. By default JDE raises an ArgumentError if a modifier is not applicable, but this behaviour
|
167
|
+
can be configured to ignore missing modifiers. See Configuration options for details
|
121
168
|
|
122
169
|
### Nested schemas
|
123
170
|
|
124
|
-
JDE supports nested schemas. Just provide your element with a type of `array` and add a `schema` key
|
171
|
+
JDE supports nested schemas. Just provide your element with a type of `array` and add a `schema` key
|
172
|
+
for its data.
|
125
173
|
|
126
174
|
E.g. this is a valid real-life schema with nested data:
|
127
175
|
|
128
176
|
```json
|
129
177
|
{
|
130
|
-
"name":
|
131
|
-
"code":
|
132
|
-
"services":
|
178
|
+
"name": "$.Name",
|
179
|
+
"code": "$.Code",
|
180
|
+
"services": "$.Services[*].Code",
|
133
181
|
"locations": {
|
134
|
-
"path":
|
135
|
-
"type":
|
182
|
+
"path": "$.Locations[*]",
|
183
|
+
"type": "array",
|
136
184
|
"schema": {
|
137
185
|
"name": "$.Name",
|
138
186
|
"type": "$.Type",
|
@@ -141,6 +189,26 @@ E.g. this is a valid real-life schema with nested data:
|
|
141
189
|
}
|
142
190
|
}
|
143
191
|
```
|
192
|
+
Nested schema can be also applied to objects, not arrays. See specs for more examples.
|
193
|
+
|
194
|
+
## Configuration Options
|
195
|
+
The JsonDataExtractor gem provides a configuration option to control the behavior when encountering invalid modifiers.
|
196
|
+
|
197
|
+
### Strict Modifiers
|
198
|
+
By default, the gem operates in strict mode, which means that if an invalid modifier is encountered, an `ArgumentError` will be raised. This ensures that only valid modifiers are applied to the extracted data.
|
199
|
+
|
200
|
+
To change this behavior and allow the use of invalid modifiers without raising an error, you can configure the gem to operate in non-strict mode.
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
JsonDataExtractor.configure do |config|
|
204
|
+
config.strict_modifiers = false
|
205
|
+
end
|
206
|
+
```
|
207
|
+
When `strict_modifiers` is set to `false`, any invalid modifiers will be ignored, and the original value will be returned without applying any modification.
|
208
|
+
|
209
|
+
It is important to note that enabling non-strict mode should be done with caution, as it can lead to unexpected behavior if there are typos or incorrect modifiers specified in the schema.
|
210
|
+
|
211
|
+
By default, `strict_modifiers` is set to `true`, providing a safe and strict behavior. However, you can customize this configuration option according to your specific needs.
|
144
212
|
|
145
213
|
## TODO
|
146
214
|
|
@@ -148,25 +216,32 @@ Update this readme for better usage cases. Add info on arrays and modifiers.
|
|
148
216
|
|
149
217
|
## Development
|
150
218
|
|
151
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
|
219
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
|
220
|
+
the tests. You can
|
152
221
|
also run `bin/console` for an interactive prompt that will allow you to experiment.
|
153
222
|
|
154
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new
|
155
|
-
version
|
223
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new
|
224
|
+
version, update the
|
225
|
+
version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag
|
226
|
+
for the version,
|
156
227
|
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
157
228
|
|
158
229
|
## Contributing
|
159
230
|
|
160
|
-
Bug reports and pull requests are welcome on GitHub
|
161
|
-
|
231
|
+
Bug reports and pull requests are welcome on GitHub
|
232
|
+
at https://github.com/austerlitz/json_data_extractor. This project
|
233
|
+
is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere
|
234
|
+
to
|
162
235
|
the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
163
236
|
|
164
237
|
## License
|
165
238
|
|
166
|
-
The gem is available as open source under the terms of
|
239
|
+
The gem is available as open source under the terms of
|
240
|
+
the [MIT License](https://opensource.org/licenses/MIT).
|
167
241
|
|
168
242
|
## Code of Conduct
|
169
243
|
|
170
|
-
Everyone interacting in the JsonDataExtractor project’s codebases, issue trackers, chat rooms and
|
244
|
+
Everyone interacting in the JsonDataExtractor project’s codebases, issue trackers, chat rooms and
|
245
|
+
mailing lists is
|
171
246
|
expected to follow
|
172
247
|
the [code of conduct](https://github.com/austerlitz/json_data_extractor/blob/master/CODE_OF_CONDUCT.md).
|
data/lib/json_data_extractor.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'src/version'
|
2
|
+
require 'src/configuration'
|
2
3
|
require 'jsonpath'
|
3
4
|
|
4
5
|
class JsonDataExtractor
|
@@ -22,7 +23,16 @@ class JsonDataExtractor
|
|
22
23
|
if val.is_a?(Hash)
|
23
24
|
val.transform_keys!(&:to_sym)
|
24
25
|
path = val[:path]
|
25
|
-
modifiers = Array(val[:modifiers] || val[:modifier]).map
|
26
|
+
modifiers = Array(val[:modifiers] || val[:modifier]).map do |mod|
|
27
|
+
case mod
|
28
|
+
when Symbol, Proc
|
29
|
+
mod
|
30
|
+
when String
|
31
|
+
mod.to_sym
|
32
|
+
else
|
33
|
+
raise ArgumentError, "Invalid modifier: #{mod.inspect}"
|
34
|
+
end
|
35
|
+
end
|
26
36
|
array_type = 'array' == val[:type]
|
27
37
|
nested = val.dup.delete(:schema)
|
28
38
|
else
|
@@ -79,8 +89,21 @@ class JsonDataExtractor
|
|
79
89
|
modifiers[modifier].call(value)
|
80
90
|
elsif value.respond_to?(modifier)
|
81
91
|
value.send(modifier)
|
92
|
+
elsif self.class.configuration.strict_modifiers
|
93
|
+
raise ArgumentError, "Invalid modifier: :#{modifier}"
|
82
94
|
else
|
83
95
|
value
|
84
96
|
end
|
85
97
|
end
|
98
|
+
|
99
|
+
|
100
|
+
class << self
|
101
|
+
def configuration
|
102
|
+
@configuration ||= Configuration.new
|
103
|
+
end
|
104
|
+
|
105
|
+
def configure
|
106
|
+
yield(configuration)
|
107
|
+
end
|
108
|
+
end
|
86
109
|
end
|
data/lib/src/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_data_extractor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Buslaev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -116,6 +116,7 @@ files:
|
|
116
116
|
- bin/setup
|
117
117
|
- json_data_extractor.gemspec
|
118
118
|
- lib/json_data_extractor.rb
|
119
|
+
- lib/src/configuration.rb
|
119
120
|
- lib/src/version.rb
|
120
121
|
homepage: https://github.com/austerlitz/json_data_extractor
|
121
122
|
licenses:
|