json_data_extractor 0.0.8 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac39771f7b1358e30e26bfdc81b5b4ad5ac493238e84142e31331648f96fa37e
4
- data.tar.gz: 69a0d03f65e05dfb292ae01f950986822ec04991771968ede64c63c6f202d99f
3
+ metadata.gz: be51d8200f061eb267a9c591934a29072729462d242c349c6057e48cb5e77627
4
+ data.tar.gz: 88213a955399a735f2cd15546d9c0b9ad22ba38de8798e9070d5a35e4a47902f
5
5
  SHA512:
6
- metadata.gz: 403b5b95e7bfc0b7f530021980a10407f08be499092a80550a2dc55df7aeabc64197f68e6bf44f98c19be4ea8d57884db1205490970a57552ea924cf673c0f8a
7
- data.tar.gz: 58260729ea70e88fdd1937cbbac0cffac998ce9dab686dedbbcb110e7618edd72a9bd71e494bfdc7441665a306e3ead800d9558b4c80b2fce525de3c70f90eee
6
+ metadata.gz: f724f3a5b3542644abe1103d8831bdefa0e6bbf2f073d8bfe928cce6f8d42992ecf570527f4adceba4b8a01f12fe0146511ae2ef80301f1a48a52b7e0f5c697a
7
+ data.tar.gz: e4318e950ec778eb19558cc1a7da37234f730ba977b42ff19f5be4d5b86c8b7a4b8a7e50a85705fa38c89d41d9cb0f39493d8f6c0bfa1e79215956f2e9817528
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 straightforward syntax
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 and [jsonpath](https://github.com/joshbuddy/jsonpath).
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 schema that maps
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,15 +80,15 @@ 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 where to place it in
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 an optional
85
- modifier field that specifies one or more modifiers to apply to the extracted data. Modifiers are used to transform the
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 the one used in the
89
- previous example (here it's in YAML just for readability):
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 (here it's in YAML just for readability):
90
92
 
91
93
  ```yaml
92
94
  schemas:
@@ -116,23 +118,66 @@ The resulting json will be:
116
118
 
117
119
  ```
118
120
 
119
- Modifiers can be supplied on object creation and/or added later by calling `#add_modifier` method. Please see specs for
120
- examples.
121
+ ### Modifiers
122
+
123
+ Modifiers can be supplied on object creation and/or added later by calling `#add_modifier` method.
124
+ Please see specs for examples.
125
+ Modifiers allow you to perform transformations on the extracted data before it is returned. You can
126
+ use modifiers to clean up the data, format it, or apply any custom logic you need.
127
+
128
+ Modifiers can be defined in two ways: by providing a symbol corresponding to the name of the method
129
+ or lambda that should be called on each extracted value, or by providing an anonymous lambda. Here's
130
+ an example schema that uses both types of modifiers:
131
+
132
+ ```ruby
133
+ schema = {
134
+ name: '$.name',
135
+ age: { path: '$.age', modifier: :to_i },
136
+ email: { path: '$.contact.email', modifiers: [:downcase, lambda { |email| email.gsub(/\s/, '') }] }
137
+ }
138
+
139
+ ```
140
+
141
+ In this schema, the name value is simply extracted as-is. The age value is extracted from the JSON,
142
+ but it is modified with the `to_i` method, which converts the value to an integer. The email value
143
+ is extracted from a nested object, and then passed through two modifiers: first `downcase` is called
144
+ to convert the email address to all lowercase letters, and then an anonymous lambda is called to
145
+ remove any whitespace in the email address.
146
+
147
+ You can also define custom modifiers by passing a lambda to the `add_modifier` method on a
148
+ JsonDataExtractor instance:
149
+
150
+ ```ruby
151
+ extractor = JsonDataExtractor.new(json_data)
152
+ extractor.add_modifier(:remove_newlines) { |value| value.gsub("\n", '') }
153
+
154
+ schema = {
155
+ name: 'name',
156
+ bio: { path: 'bio', modifiers: [:remove_newlines] }
157
+ }
158
+
159
+ results = extractor.extract(schema)
160
+
161
+ ```
162
+
163
+ Modifiers are called in the order in which they are defined, so keep that in mind when defining your
164
+ schema.
121
165
 
122
166
  ### Nested schemas
123
167
 
124
- JDE supports nested schemas. Just provide your element with a type of `array` and add a `schema` key for its data.
168
+ JDE supports nested schemas. Just provide your element with a type of `array` and add a `schema` key
169
+ for its data.
125
170
 
126
171
  E.g. this is a valid real-life schema with nested data:
127
172
 
128
173
  ```json
129
174
  {
130
- "name": "$.Name",
131
- "code": "$.Code",
132
- "services": "$.Services[*].Code",
175
+ "name": "$.Name",
176
+ "code": "$.Code",
177
+ "services": "$.Services[*].Code",
133
178
  "locations": {
134
- "path": "$.Locations[*]",
135
- "type": "array",
179
+ "path": "$.Locations[*]",
180
+ "type": "array",
136
181
  "schema": {
137
182
  "name": "$.Name",
138
183
  "type": "$.Type",
@@ -148,25 +193,32 @@ Update this readme for better usage cases. Add info on arrays and modifiers.
148
193
 
149
194
  ## Development
150
195
 
151
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
196
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
197
+ the tests. You can
152
198
  also run `bin/console` for an interactive prompt that will allow you to experiment.
153
199
 
154
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
155
- version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
200
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new
201
+ version, update the
202
+ version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag
203
+ for the version,
156
204
  push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
157
205
 
158
206
  ## Contributing
159
207
 
160
- Bug reports and pull requests are welcome on GitHub at https://github.com/austerlitz/json_data_extractor. This project
161
- is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to
208
+ Bug reports and pull requests are welcome on GitHub
209
+ at https://github.com/austerlitz/json_data_extractor. This project
210
+ is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere
211
+ to
162
212
  the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
163
213
 
164
214
  ## License
165
215
 
166
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
216
+ The gem is available as open source under the terms of
217
+ the [MIT License](https://opensource.org/licenses/MIT).
167
218
 
168
219
  ## Code of Conduct
169
220
 
170
- Everyone interacting in the JsonDataExtractor project’s codebases, issue trackers, chat rooms and mailing lists is
221
+ Everyone interacting in the JsonDataExtractor project’s codebases, issue trackers, chat rooms and
222
+ mailing lists is
171
223
  expected to follow
172
224
  the [code of conduct](https://github.com/austerlitz/json_data_extractor/blob/master/CODE_OF_CONDUCT.md).
@@ -26,7 +26,7 @@ transformations. The schema is defined as a simple Ruby hash that maps keys to p
26
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
27
  spec.require_paths = ['lib']
28
28
 
29
- spec.add_development_dependency 'bundler', '~> 1.17'
29
+ spec.add_development_dependency 'bundler'
30
30
  spec.add_development_dependency 'rake', '~> 10.0'
31
31
  spec.add_development_dependency 'rspec', '~> 3.0'
32
32
  spec.add_development_dependency 'pry'
@@ -22,7 +22,16 @@ class JsonDataExtractor
22
22
  if val.is_a?(Hash)
23
23
  val.transform_keys!(&:to_sym)
24
24
  path = val[:path]
25
- modifiers = Array(val[:modifiers] || val[:modifier]).map(&:to_sym)
25
+ modifiers = Array(val[:modifiers] || val[:modifier]).map do |mod|
26
+ case mod
27
+ when Symbol, Proc
28
+ mod
29
+ when String
30
+ mod.to_sym
31
+ else
32
+ raise ArgumentError, "Invalid modifier: #{mod.inspect}"
33
+ end
34
+ end
26
35
  array_type = 'array' == val[:type]
27
36
  nested = val.dup.delete(:schema)
28
37
  else
@@ -37,20 +46,17 @@ class JsonDataExtractor
37
46
  else
38
47
  results[key] = apply_modifiers(extracted_data, modifiers)
39
48
 
40
- # TODO yeah, this looks ugly. Address it later.
41
- if !array_type
42
- if nested
43
- results[key] = self.class.new(results[key].first, @modifiers).extract(nested)
44
- # todo there might be a problem if results[key] yields more than 1 item
45
- # Yeah, we'll get back to it later. Or send your PRs
46
- else
47
- results[key] = results[key].first unless 1 < results[key].size
48
- end
49
- elsif nested
50
- results[key] = []
51
- Array(extracted_data).each do |item|
52
- results[key] << self.class.new(item, @modifiers).extract(nested)
53
- end
49
+ if array_type && nested
50
+ results[key] = extract_nested_data(results[key], nested)
51
+ elsif !array_type && nested
52
+ results[key] = extract_nested_data(results[key], nested).first
53
+ elsif !array_type && 1 < results[key].size
54
+ # TODO: handle case where results[key] has more than one item
55
+ # do nothing for now
56
+ elsif array_type && !nested
57
+ # do nothing, it is already an array
58
+ else
59
+ results[key] = results[key].first
54
60
  end
55
61
  end
56
62
  end
@@ -59,6 +65,12 @@ class JsonDataExtractor
59
65
 
60
66
  private
61
67
 
68
+ def extract_nested_data(data, schema)
69
+ Array(data).map do |item|
70
+ self.class.new(item, modifiers).extract(schema)
71
+ end
72
+ end
73
+
62
74
  def apply_modifiers(data, modifiers)
63
75
  data.map do |value|
64
76
  modified_value = value
data/lib/src/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class JsonDataExtractor
2
- VERSION = '0.0.8'
2
+ VERSION = '0.0.10'
3
3
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_data_extractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.10
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-05-10 00:00:00.000000000 Z
11
+ date: 2023-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement