shale 0.6.0 → 0.8.0
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/CHANGELOG.md +27 -0
- data/LICENSE.txt +1 -1
- data/README.md +222 -30
- data/lib/shale/adapter/json.rb +3 -3
- data/lib/shale/adapter/nokogiri.rb +6 -5
- data/lib/shale/adapter/ox.rb +5 -4
- data/lib/shale/adapter/rexml/document.rb +1 -1
- data/lib/shale/adapter/rexml.rb +5 -4
- data/lib/shale/error.rb +8 -3
- data/lib/shale/mapper.rb +5 -1
- data/lib/shale/mapping/descriptor/dict.rb +21 -1
- data/lib/shale/mapping/descriptor/xml.rb +20 -2
- data/lib/shale/mapping/dict.rb +14 -40
- data/lib/shale/mapping/dict_base.rb +73 -0
- data/lib/shale/mapping/dict_group.rb +41 -0
- data/lib/shale/mapping/group/dict.rb +55 -0
- data/lib/shale/mapping/group/dict_grouping.rb +41 -0
- data/lib/shale/mapping/group/xml.rb +43 -0
- data/lib/shale/mapping/group/xml_grouping.rb +27 -0
- data/lib/shale/mapping/xml.rb +53 -154
- data/lib/shale/mapping/xml_base.rb +227 -0
- data/lib/shale/mapping/xml_group.rb +70 -0
- data/lib/shale/schema/json_generator.rb +1 -3
- data/lib/shale/schema/xml_generator/import.rb +2 -2
- data/lib/shale/schema/xml_generator.rb +4 -6
- data/lib/shale/type/complex.rb +469 -84
- data/lib/shale/type/date.rb +2 -2
- data/lib/shale/type/time.rb +2 -2
- data/lib/shale/type/value.rb +10 -10
- data/lib/shale/version.rb +1 -1
- data/shale.gemspec +1 -1
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76c0022b3d2d42be143362c84c6697628781acdce7694fb9bc0f305d3f854964
|
4
|
+
data.tar.gz: 0b0b1b060eab81ebfae80afa3c31c809280b66ebd77e413c5908c4bbd09a081a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43bc9188d1f07c5c367a8ed94e2a3da6b878a7b7b86773d7898697abbd3937d4de6ae0471f9362c72e8a6be2cc5e5100a5206b2f2cc7155ff2ff8784953ef702
|
7
|
+
data.tar.gz: 0e610703cc73809a78007785962d9a322e515b88ab143a55adfeaa1a0da5961f14d8768a3dec4ad797070bbab165c238123702cbc671f522f86e2934968ff78b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
## [0.8.0] - 2022-08-30
|
2
|
+
|
3
|
+
### Added
|
4
|
+
- Allow to group mappings using `group` block
|
5
|
+
- Bring back Ruby 2.6 support
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
- Use anonymous module for attributes definition.
|
9
|
+
It allows to override accessors and `super` works as expected.
|
10
|
+
|
11
|
+
## [0.7.1] - 2022-08-12
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
- Fix broken handling of Date and Time types
|
15
|
+
|
16
|
+
## [0.7.0] - 2022-08-09
|
17
|
+
|
18
|
+
### Added
|
19
|
+
- `only: []` and `except: []` options that allow to controll what attributes are rendered/parsed
|
20
|
+
- `render_nil: true` option that allows to render nil values
|
21
|
+
- Allow to pass a context object to extractor/generator methods
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
- Pass whole document to methods for JSON/YAML/TOML so its behavior is consistent with XML mapping
|
25
|
+
- Convert splat arguments to keyword arguments
|
26
|
+
- RSpec: enable random spec execution and warnings
|
27
|
+
|
1
28
|
## [0.6.0] - 2022-07-05
|
2
29
|
|
3
30
|
### Added
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -12,12 +12,12 @@ Documentation with interactive examples is available at [Shale website](https://
|
|
12
12
|
* Convert Ruby data model to JSON, YAML, TOML and XML
|
13
13
|
* Generate JSON and XML Schema from Ruby models
|
14
14
|
* Compile JSON and XML Schema into Ruby models
|
15
|
-
* Out of the box support for JSON, YAML, toml-rb, Nokogiri, REXML and Ox parsers
|
15
|
+
* Out of the box support for JSON, YAML, Tomlib, toml-rb, Nokogiri, REXML and Ox parsers
|
16
16
|
* Support for custom adapters
|
17
17
|
|
18
18
|
## Installation
|
19
19
|
|
20
|
-
Shale supports Ruby (MRI) 2.
|
20
|
+
Shale supports Ruby (MRI) 2.6+
|
21
21
|
|
22
22
|
Add this line to your application's Gemfile:
|
23
23
|
|
@@ -57,8 +57,9 @@ $ gem install shale
|
|
57
57
|
* [Mapping Hash keys to object attributes](#mapping-hash-keys-to-object-attributes)
|
58
58
|
* [Mapping XML elements and attributes to object attributes](#mapping-xml-elements-and-attributes-to-object-attributes)
|
59
59
|
* [Using XML namespaces](#using-xml-namespaces)
|
60
|
+
* [Rendering nil values](#rendering-nil-values)
|
60
61
|
* [Using methods to extract and generate data](#using-methods-to-extract-and-generate-data)
|
61
|
-
* [
|
62
|
+
* [Additional options](#additional-options)
|
62
63
|
* [Using custom models](#using-custom-models)
|
63
64
|
* [Supported types](#supported-types)
|
64
65
|
* [Writing your own type](#writing-your-own-type)
|
@@ -202,18 +203,23 @@ person.to_yaml
|
|
202
203
|
### Converting TOML to object
|
203
204
|
|
204
205
|
To use TOML with Shale you have to set adapter you want to use.
|
205
|
-
|
206
|
+
Out of the box Shale suports [Tomlib](https://github.com/kgiszczak/tomlib).
|
207
|
+
It also comes with adapter for [toml-rb](https://github.com/emancu/toml-rb) if you prefer that.
|
206
208
|
For details see [Adapters](#adapters) section.
|
207
209
|
|
208
|
-
To set it, first make sure
|
210
|
+
To set it, first make sure Tomlib gem is installed:
|
209
211
|
|
210
212
|
```
|
211
|
-
$ gem install
|
213
|
+
$ gem install tomlib
|
212
214
|
```
|
213
215
|
|
214
216
|
then setup adapter:
|
215
217
|
|
216
218
|
```ruby
|
219
|
+
require 'tomlib'
|
220
|
+
Shale.toml_adapter = Tomlib
|
221
|
+
|
222
|
+
# Alternatively if you'd like to use toml-rb, use:
|
217
223
|
require 'shale/adapter/toml_rb'
|
218
224
|
Shale.toml_adapter = Shale::Adapter::TomlRB
|
219
225
|
```
|
@@ -241,18 +247,16 @@ person.to_toml
|
|
241
247
|
|
242
248
|
# =>
|
243
249
|
#
|
244
|
-
#
|
245
|
-
#
|
246
|
-
#
|
247
|
-
#
|
248
|
-
#
|
249
|
-
#
|
250
|
-
#
|
251
|
-
#
|
252
|
-
#
|
253
|
-
#
|
254
|
-
# street: Oxford Street
|
255
|
-
# zip: E1 6AN
|
250
|
+
# first_name = "John"
|
251
|
+
# last_name = "Doe"
|
252
|
+
# age = 50
|
253
|
+
# married = false
|
254
|
+
# hobbies = [ "Singing", "Dancing" ]
|
255
|
+
#
|
256
|
+
# [address]
|
257
|
+
# city = "London"
|
258
|
+
# street = "Oxford Street"
|
259
|
+
# zip = "E1 6AN"
|
256
260
|
```
|
257
261
|
|
258
262
|
### Converting Hash to object
|
@@ -555,6 +559,52 @@ person = Person.from_xml(<<~DATA)
|
|
555
559
|
DATA
|
556
560
|
```
|
557
561
|
|
562
|
+
### Rendering nil values
|
563
|
+
|
564
|
+
By default elements with `nil` value are not rendered. You can change this behavior
|
565
|
+
by using `render_nil: true` on a mapping.
|
566
|
+
|
567
|
+
```ruby
|
568
|
+
class Person < Shale::Mapper
|
569
|
+
attribute :first_name, Shale::Type::String
|
570
|
+
attribute :last_name, Shale::Type::String
|
571
|
+
attribute :age, Shale::Type::Integer
|
572
|
+
|
573
|
+
json do
|
574
|
+
map 'first_name', to: :first_name, render_nil: true
|
575
|
+
map 'last_name', to: :last_name, render_nil: false
|
576
|
+
map 'age', to: :age, render_nil: true
|
577
|
+
end
|
578
|
+
|
579
|
+
xml do
|
580
|
+
root 'person'
|
581
|
+
|
582
|
+
map_element 'first_name', to: :first_name, render_nil: true
|
583
|
+
map_element 'last_name', to: :last_name, render_nil: false
|
584
|
+
map_attribute 'age', to: :age, render_nil: true
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
person = Person.new(first_name: nil, last_name: nil, age: nil)
|
589
|
+
|
590
|
+
puts person.to_json(pretty: true)
|
591
|
+
|
592
|
+
# =>
|
593
|
+
#
|
594
|
+
# {
|
595
|
+
# "first_name": null,
|
596
|
+
# "age": "null"
|
597
|
+
# }
|
598
|
+
|
599
|
+
puts person.to_xml(pretty: true)
|
600
|
+
|
601
|
+
# =>
|
602
|
+
#
|
603
|
+
# <person age="">
|
604
|
+
# <first_name/>
|
605
|
+
# </person>
|
606
|
+
```
|
607
|
+
|
558
608
|
### Using methods to extract and generate data
|
559
609
|
|
560
610
|
If you need full controll over extracting and generating data from/to document,
|
@@ -582,8 +632,8 @@ class Person < Shale::Mapper
|
|
582
632
|
model.hobbies = value.split(',').map(&:strip)
|
583
633
|
end
|
584
634
|
|
585
|
-
def hobbies_to_json(model)
|
586
|
-
model.hobbies.join(', ')
|
635
|
+
def hobbies_to_json(model, doc)
|
636
|
+
doc['hobbies'] = model.hobbies.join(', ')
|
587
637
|
end
|
588
638
|
|
589
639
|
def address_from_json(model, value)
|
@@ -591,8 +641,8 @@ class Person < Shale::Mapper
|
|
591
641
|
model.city = value['city']
|
592
642
|
end
|
593
643
|
|
594
|
-
def address_to_json(model)
|
595
|
-
{ 'street' => model.street, 'city' => model.city }
|
644
|
+
def address_to_json(model, doc)
|
645
|
+
doc['address'] = { 'street' => model.street, 'city' => model.city }
|
596
646
|
end
|
597
647
|
|
598
648
|
def hobbies_from_xml(model, value)
|
@@ -649,12 +699,149 @@ DATA
|
|
649
699
|
# @city="London">
|
650
700
|
```
|
651
701
|
|
652
|
-
|
702
|
+
You can also pass a `context` object that will be available in extractor/generator methods:
|
653
703
|
|
654
|
-
|
704
|
+
```ruby
|
705
|
+
class Person < Shale::Mapper
|
706
|
+
attribute :password, Shale::Type::String
|
707
|
+
|
708
|
+
json do
|
709
|
+
map 'password', using: { from: :password_from_json, to: :password_to_json }
|
710
|
+
end
|
711
|
+
|
712
|
+
def password_from_json(model, value, context)
|
713
|
+
if context.admin?
|
714
|
+
model.password = value
|
715
|
+
else
|
716
|
+
model.password = '*****'
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
720
|
+
def password_to_json(model, doc, context)
|
721
|
+
if context.admin?
|
722
|
+
doc['password'] = model.password
|
723
|
+
else
|
724
|
+
doc['password'] = '*****'
|
725
|
+
end
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
Person.new(password: 'secret').to_json(context: current_user)
|
730
|
+
```
|
731
|
+
|
732
|
+
If you want to work on multiple elements at a time you can group them using `group` block:
|
655
733
|
|
656
734
|
```ruby
|
657
|
-
|
735
|
+
class Person < Shale::Mapper
|
736
|
+
attribute :name, Shale::Type::String
|
737
|
+
|
738
|
+
json do
|
739
|
+
group from: :name_from_json, to: :name_to_json do
|
740
|
+
map 'first_name'
|
741
|
+
map 'last_name'
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
xml do
|
746
|
+
group from: :name_from_xml, to: :name_to_xml do
|
747
|
+
map_content
|
748
|
+
map_element 'first_name'
|
749
|
+
map_attribute 'last_name'
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
def name_from_json(model, value)
|
754
|
+
model.name = "#{value['first_name']} #{value['last_name']}"
|
755
|
+
end
|
756
|
+
|
757
|
+
def name_to_json(model, doc)
|
758
|
+
doc['first_name'] = model.name.split(' ')[0]
|
759
|
+
doc['last_name'] = model.name.split(' ')[1]
|
760
|
+
end
|
761
|
+
|
762
|
+
def name_from_xml(model, value)
|
763
|
+
# value => { content: ..., attributes: {}, elements: {} }
|
764
|
+
end
|
765
|
+
|
766
|
+
def name_to_xml(model, element, doc)
|
767
|
+
# ...
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
Person.from_json(<<~DATA)
|
772
|
+
{
|
773
|
+
"first_name": "John",
|
774
|
+
"last_name": "Doe"
|
775
|
+
}
|
776
|
+
DATA
|
777
|
+
|
778
|
+
# => #<Person:0x00007f9bc3086d60 @name="John Doe">
|
779
|
+
```
|
780
|
+
|
781
|
+
### Additional options
|
782
|
+
|
783
|
+
You can control which attributes to render and parse by
|
784
|
+
using `only: []` and `except: []` parameters.
|
785
|
+
|
786
|
+
```ruby
|
787
|
+
# e.g. if you have this model graph:
|
788
|
+
person = Person.new(
|
789
|
+
first_name: 'John'
|
790
|
+
last_name: 'Doe',
|
791
|
+
address: Address.new(city: 'London', street: 'Oxford Street')
|
792
|
+
)
|
793
|
+
|
794
|
+
# if you want to render only `first_name` and `address.city` do:
|
795
|
+
person.to_json(only: [:first_name, address: [:city]], pretty: true)
|
796
|
+
|
797
|
+
# =>
|
798
|
+
#
|
799
|
+
# {
|
800
|
+
# "first_name": "John",
|
801
|
+
# "address": {
|
802
|
+
# "city": "London"
|
803
|
+
# }
|
804
|
+
# }
|
805
|
+
|
806
|
+
# and if you don't need an address you can do:
|
807
|
+
person.to_json(except: [:address], pretty: true)
|
808
|
+
|
809
|
+
# =>
|
810
|
+
#
|
811
|
+
# {
|
812
|
+
# "first_name": "John",
|
813
|
+
# "last_name": "Doe"
|
814
|
+
# }
|
815
|
+
```
|
816
|
+
|
817
|
+
It works the same for parsing:
|
818
|
+
|
819
|
+
```ruby
|
820
|
+
# e.g. if you want to parse only `address.city` do:
|
821
|
+
Person.from_json(doc, only: [address: [:city]])
|
822
|
+
|
823
|
+
# =>
|
824
|
+
#
|
825
|
+
# #<Person:0x0000000113d7a488
|
826
|
+
# @first_name=nil,
|
827
|
+
# @last_name=nil,
|
828
|
+
# @address=#<Address:0x0000000113d7a140 @street=nil, @city="London">>
|
829
|
+
|
830
|
+
# and if you don't need an `address`:
|
831
|
+
Person.from_json(doc, except: [:address])
|
832
|
+
|
833
|
+
# =>
|
834
|
+
#
|
835
|
+
# #<Person:0x0000000113d7a488
|
836
|
+
# @first_name="John",
|
837
|
+
# @last_name="Doe",
|
838
|
+
# @address=nil>
|
839
|
+
```
|
840
|
+
|
841
|
+
If you need formatted output you can pass `pretty: true` parameter to `#to_json` and `#to_xml`
|
842
|
+
|
843
|
+
```ruby
|
844
|
+
person.to_json(pretty: true)
|
658
845
|
|
659
846
|
# =>
|
660
847
|
#
|
@@ -666,10 +853,10 @@ person.to_json(:pretty)
|
|
666
853
|
# }
|
667
854
|
```
|
668
855
|
|
669
|
-
You can also add an XML declaration by passing
|
856
|
+
You can also add an XML declaration by passing `declaration: true` to `#to_xml`
|
670
857
|
|
671
858
|
```ruby
|
672
|
-
person.to_xml(:
|
859
|
+
person.to_xml(pretty: true, declaration: true)
|
673
860
|
|
674
861
|
# =>
|
675
862
|
#
|
@@ -726,7 +913,7 @@ DATA
|
|
726
913
|
# @last_name="Doe",
|
727
914
|
# @address=#<Address:0x0000000113d7a140 @street="Oxford Street", @city="London">>
|
728
915
|
|
729
|
-
PersonMapper.to_json(person, :
|
916
|
+
PersonMapper.to_json(person, pretty: true)
|
730
917
|
|
731
918
|
# =>
|
732
919
|
#
|
@@ -781,12 +968,17 @@ Shale.json_adapter = MultiJson
|
|
781
968
|
Shale.yaml_adapter = MyYamlAdapter
|
782
969
|
```
|
783
970
|
|
784
|
-
To handle TOML documents you have to set TOML adapter.
|
785
|
-
Shale provides adapter for `toml-rb`
|
971
|
+
To handle TOML documents you have to set TOML adapter. Out of the box `Tomlib` is supported.
|
972
|
+
Shale also provides adapter for `toml-rb` parser:
|
786
973
|
|
787
974
|
```ruby
|
788
975
|
require 'shale'
|
789
976
|
|
977
|
+
# if you want to use Tomlib
|
978
|
+
require 'tomlib'
|
979
|
+
Shale.toml_adapter = Tomlib
|
980
|
+
|
981
|
+
# if you want to use toml-rb
|
790
982
|
require 'shale/adapter/toml_rb'
|
791
983
|
Shale.toml_adapter = Shale::Adapter::TomlRB
|
792
984
|
```
|
data/lib/shale/adapter/json.rb
CHANGED
@@ -22,13 +22,13 @@ module Shale
|
|
22
22
|
# Serialize Hash into JSON
|
23
23
|
#
|
24
24
|
# @param [Hash] obj Hash object
|
25
|
-
# @param [
|
25
|
+
# @param [true, false] pretty
|
26
26
|
#
|
27
27
|
# @return [String]
|
28
28
|
#
|
29
29
|
# @api private
|
30
|
-
def self.dump(obj,
|
31
|
-
if
|
30
|
+
def self.dump(obj, pretty: false)
|
31
|
+
if pretty
|
32
32
|
::JSON.pretty_generate(obj)
|
33
33
|
else
|
34
34
|
::JSON.generate(obj)
|
@@ -36,25 +36,26 @@ module Shale
|
|
36
36
|
# Serialize Nokogiri document into XML
|
37
37
|
#
|
38
38
|
# @param [::Nokogiri::XML::Document] doc Nokogiri document
|
39
|
-
# @param [
|
39
|
+
# @param [true, false] pretty
|
40
|
+
# @param [true, false] declaration
|
40
41
|
#
|
41
42
|
# @return [String]
|
42
43
|
#
|
43
44
|
# @api private
|
44
|
-
def self.dump(doc,
|
45
|
+
def self.dump(doc, pretty: false, declaration: false)
|
45
46
|
save_with = ::Nokogiri::XML::Node::SaveOptions::AS_XML
|
46
47
|
|
47
|
-
if
|
48
|
+
if pretty
|
48
49
|
save_with |= ::Nokogiri::XML::Node::SaveOptions::FORMAT
|
49
50
|
end
|
50
51
|
|
51
|
-
unless
|
52
|
+
unless declaration
|
52
53
|
save_with |= ::Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
|
53
54
|
end
|
54
55
|
|
55
56
|
result = doc.to_xml(save_with: save_with)
|
56
57
|
|
57
|
-
unless
|
58
|
+
unless pretty
|
58
59
|
result = result.sub(/\n/, '')
|
59
60
|
end
|
60
61
|
|
data/lib/shale/adapter/ox.rb
CHANGED
@@ -30,19 +30,20 @@ module Shale
|
|
30
30
|
# Serialize Ox document into XML
|
31
31
|
#
|
32
32
|
# @param [::Ox::Document, ::Ox::Element] doc Ox document
|
33
|
-
# @param [
|
33
|
+
# @param [true, false] pretty
|
34
|
+
# @param [true, false] declaration
|
34
35
|
#
|
35
36
|
# @return [String]
|
36
37
|
#
|
37
38
|
# @api private
|
38
|
-
def self.dump(doc,
|
39
|
+
def self.dump(doc, pretty: false, declaration: false)
|
39
40
|
opts = { indent: -1, with_xml: false }
|
40
41
|
|
41
|
-
if
|
42
|
+
if pretty
|
42
43
|
opts[:indent] = 2
|
43
44
|
end
|
44
45
|
|
45
|
-
if
|
46
|
+
if declaration
|
46
47
|
doc[:version] = '1.0'
|
47
48
|
opts[:with_xml] = true
|
48
49
|
end
|
data/lib/shale/adapter/rexml.rb
CHANGED
@@ -31,19 +31,20 @@ module Shale
|
|
31
31
|
# Serialize REXML document into XML
|
32
32
|
#
|
33
33
|
# @param [::REXML::Document] doc REXML document
|
34
|
-
# @param [
|
34
|
+
# @param [true, false] pretty
|
35
|
+
# @param [true, false] declaration
|
35
36
|
#
|
36
37
|
# @return [String]
|
37
38
|
#
|
38
39
|
# @api private
|
39
|
-
def self.dump(doc,
|
40
|
-
if
|
40
|
+
def self.dump(doc, pretty: false, declaration: false)
|
41
|
+
if declaration
|
41
42
|
doc.add(::REXML::XMLDecl.new)
|
42
43
|
end
|
43
44
|
|
44
45
|
io = StringIO.new
|
45
46
|
|
46
|
-
if
|
47
|
+
if pretty
|
47
48
|
formatter = ::REXML::Formatters::Pretty.new
|
48
49
|
formatter.compact = true
|
49
50
|
else
|
data/lib/shale/error.rb
CHANGED
@@ -7,6 +7,11 @@ module Shale
|
|
7
7
|
TOML Adapter is not set.
|
8
8
|
To use Shale with TOML documents you have to install parser and set adapter.
|
9
9
|
|
10
|
+
# To use Tomlib:
|
11
|
+
# Make sure tomlib is installed eg. execute: gem install tomlib
|
12
|
+
Shale.toml_adapter = Tomlib
|
13
|
+
|
14
|
+
# To use toml-rb:
|
10
15
|
# Make sure toml-rb is installed eg. execute: gem install toml-rb
|
11
16
|
require 'shale/adapter/toml_rb'
|
12
17
|
Shale.toml_adapter = Shale::Adapter::TomlRB
|
@@ -18,16 +23,16 @@ module Shale
|
|
18
23
|
XML Adapter is not set.
|
19
24
|
To use Shale with XML documents you have to install parser and set adapter.
|
20
25
|
|
21
|
-
To use REXML:
|
26
|
+
# To use REXML:
|
22
27
|
require 'shale/adapter/rexml'
|
23
28
|
Shale.xml_adapter = Shale::Adapter::REXML
|
24
29
|
|
25
|
-
To use Nokogiri:
|
30
|
+
# To use Nokogiri:
|
26
31
|
# Make sure Nokogiri is installed eg. execute: gem install nokogiri
|
27
32
|
require 'shale/adapter/nokogiri'
|
28
33
|
Shale.xml_adapter = Shale::Adapter::Nokogiri
|
29
34
|
|
30
|
-
To use OX:
|
35
|
+
# To use OX:
|
31
36
|
# Make sure Ox is installed eg. execute: gem install ox
|
32
37
|
require 'shale/adapter/ox'
|
33
38
|
Shale.xml_adapter = Shale::Adapter::Ox
|
data/lib/shale/mapper.rb
CHANGED
@@ -98,6 +98,10 @@ module Shale
|
|
98
98
|
def inherited(subclass)
|
99
99
|
super
|
100
100
|
|
101
|
+
attributes_module = Module.new
|
102
|
+
subclass.instance_variable_set('@attributes_module', attributes_module)
|
103
|
+
subclass.include(attributes_module)
|
104
|
+
|
101
105
|
subclass.instance_variable_set('@model', subclass)
|
102
106
|
subclass.instance_variable_set('@attributes', @attributes.dup)
|
103
107
|
|
@@ -171,7 +175,7 @@ module Shale
|
|
171
175
|
@toml_mapping.map(name.to_s, to: name) unless @toml_mapping.finalized?
|
172
176
|
@xml_mapping.map_element(name.to_s, to: name) unless @xml_mapping.finalized?
|
173
177
|
|
174
|
-
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
178
|
+
@attributes_module.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
175
179
|
attr_reader :#{name}
|
176
180
|
|
177
181
|
def #{name}=(val)
|
@@ -35,22 +35,42 @@ module Shale
|
|
35
35
|
# @api private
|
36
36
|
attr_reader :method_to
|
37
37
|
|
38
|
+
# Return group name
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
attr_reader :group
|
44
|
+
|
38
45
|
# Initialize instance
|
39
46
|
#
|
40
47
|
# @param [String] name
|
41
48
|
# @param [Symbol, nil] attribute
|
42
49
|
# @param [Hash, nil] methods
|
50
|
+
# @param [String, nil] group
|
51
|
+
# @param [true, false] render_nil
|
43
52
|
#
|
44
53
|
# @api private
|
45
|
-
def initialize(name:, attribute:, methods:)
|
54
|
+
def initialize(name:, attribute:, methods:, group:, render_nil:)
|
46
55
|
@name = name
|
47
56
|
@attribute = attribute
|
57
|
+
@group = group
|
58
|
+
@render_nil = render_nil
|
48
59
|
|
49
60
|
if methods
|
50
61
|
@method_from = methods[:from]
|
51
62
|
@method_to = methods[:to]
|
52
63
|
end
|
53
64
|
end
|
65
|
+
|
66
|
+
# Check render_nil
|
67
|
+
#
|
68
|
+
# @return [true, false]
|
69
|
+
#
|
70
|
+
# @api private
|
71
|
+
def render_nil?
|
72
|
+
@render_nil == true
|
73
|
+
end
|
54
74
|
end
|
55
75
|
end
|
56
76
|
end
|
@@ -28,12 +28,21 @@ module Shale
|
|
28
28
|
# @param [String] name
|
29
29
|
# @param [Symbol, String] attribute
|
30
30
|
# @param [Hash, nil] methods
|
31
|
+
# @param [String, nil] group
|
31
32
|
# @param [Shale::Mapping::XmlNamespace] namespace
|
32
33
|
# @param [true, false] cdata
|
34
|
+
# @param [true, false] render_nil
|
33
35
|
#
|
34
36
|
# @api private
|
35
|
-
def initialize(name:, attribute:, methods:, namespace:, cdata:)
|
36
|
-
super(
|
37
|
+
def initialize(name:, attribute:, methods:, group:, namespace:, cdata:, render_nil:)
|
38
|
+
super(
|
39
|
+
name: name,
|
40
|
+
attribute: attribute,
|
41
|
+
methods: methods,
|
42
|
+
group: group,
|
43
|
+
render_nil: render_nil
|
44
|
+
)
|
45
|
+
|
37
46
|
@namespace = namespace
|
38
47
|
@cdata = cdata
|
39
48
|
end
|
@@ -46,6 +55,15 @@ module Shale
|
|
46
55
|
def prefixed_name
|
47
56
|
[namespace.prefix, name].compact.join(':')
|
48
57
|
end
|
58
|
+
|
59
|
+
# Return name with XML namespace
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
#
|
63
|
+
# @api private
|
64
|
+
def namespaced_name
|
65
|
+
[namespace.name, name].compact.join(':')
|
66
|
+
end
|
49
67
|
end
|
50
68
|
end
|
51
69
|
end
|