xmlable 0.0.0.alpha1
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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +245 -0
- data/lib/xmlable/attribute.rb +16 -0
- data/lib/xmlable/builder.rb +189 -0
- data/lib/xmlable/document.rb +16 -0
- data/lib/xmlable/element.rb +19 -0
- data/lib/xmlable/exports/base.rb +78 -0
- data/lib/xmlable/exports/json_exporter.rb +208 -0
- data/lib/xmlable/exports/xml_exporter.rb +179 -0
- data/lib/xmlable/exports.rb +11 -0
- data/lib/xmlable/handlers/attribute.rb +41 -0
- data/lib/xmlable/handlers/attribute_none.rb +10 -0
- data/lib/xmlable/handlers/base.rb +103 -0
- data/lib/xmlable/handlers/document.rb +33 -0
- data/lib/xmlable/handlers/element.rb +89 -0
- data/lib/xmlable/handlers/element_none.rb +10 -0
- data/lib/xmlable/handlers/elements.rb +15 -0
- data/lib/xmlable/handlers/mixins/described.rb +19 -0
- data/lib/xmlable/handlers/mixins/namespace.rb +40 -0
- data/lib/xmlable/handlers/mixins/tag.rb +24 -0
- data/lib/xmlable/handlers/namespace.rb +26 -0
- data/lib/xmlable/handlers/root.rb +9 -0
- data/lib/xmlable/handlers/root_none.rb +10 -0
- data/lib/xmlable/handlers/storage.rb +104 -0
- data/lib/xmlable/handlers.rb +23 -0
- data/lib/xmlable/mixins/attributes_storage.rb +195 -0
- data/lib/xmlable/mixins/bare_value.rb +41 -0
- data/lib/xmlable/mixins/castable.rb +93 -0
- data/lib/xmlable/mixins/container.rb +71 -0
- data/lib/xmlable/mixins/content_storage.rb +138 -0
- data/lib/xmlable/mixins/document_storage.rb +136 -0
- data/lib/xmlable/mixins/elements_storage.rb +219 -0
- data/lib/xmlable/mixins/export.rb +45 -0
- data/lib/xmlable/mixins/instantiable.rb +47 -0
- data/lib/xmlable/mixins/namespace_definitions_storage.rb +105 -0
- data/lib/xmlable/mixins/object.rb +95 -0
- data/lib/xmlable/mixins/options_storage.rb +39 -0
- data/lib/xmlable/mixins/root_storage.rb +162 -0
- data/lib/xmlable/mixins/standalone_attribute.rb +34 -0
- data/lib/xmlable/mixins/standalone_element.rb +47 -0
- data/lib/xmlable/mixins/value_storage.rb +84 -0
- data/lib/xmlable/mixins/wrapper.rb +37 -0
- data/lib/xmlable/mixins.rb +25 -0
- data/lib/xmlable/options/nokogiri_export.rb +19 -0
- data/lib/xmlable/options/storage.rb +97 -0
- data/lib/xmlable/options.rb +9 -0
- data/lib/xmlable/types.rb +31 -0
- data/lib/xmlable/version.rb +4 -0
- data/lib/xmlable.rb +49 -0
- metadata +149 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Mixins
|
3
|
+
#
|
4
|
+
# Base class contains base item's methods
|
5
|
+
#
|
6
|
+
module Object
|
7
|
+
# @return [Nokogiri::XML::Node]
|
8
|
+
attr_reader :__node
|
9
|
+
# @return [XMLable::Handlers::Base]
|
10
|
+
attr_reader :__handler
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Initialize
|
18
|
+
#
|
19
|
+
# @param [Nokogiri::XML::Node] node item's XML node
|
20
|
+
# @param [XMLable::Handlers::Base] handler item's handler
|
21
|
+
#
|
22
|
+
def initialize(node, handler)
|
23
|
+
@__node = node
|
24
|
+
@__handler = handler
|
25
|
+
__inject_node(@__node, @__handler)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Is this object empty?
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
#
|
33
|
+
# @return [Boolean]
|
34
|
+
#
|
35
|
+
def __empty?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Does this object have a nested object with given key
|
41
|
+
#
|
42
|
+
# @return [Object, false]
|
43
|
+
#
|
44
|
+
def key?(*)
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Get nested object
|
50
|
+
#
|
51
|
+
def [](*)
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# get nested object value
|
56
|
+
#
|
57
|
+
def []=(*)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
#
|
63
|
+
# Inject XML node and handler with the curren object
|
64
|
+
#
|
65
|
+
# @param [Nokogiri::XML::Node] node item's XML node
|
66
|
+
# @param [XMLable::Handlers::Base] handler item's handler
|
67
|
+
#
|
68
|
+
# @api private
|
69
|
+
#
|
70
|
+
def __inject_node(node, handler)
|
71
|
+
node.instance_variable_set(:@__handler, handler)
|
72
|
+
node.instance_variable_set(:@__element, self)
|
73
|
+
end
|
74
|
+
|
75
|
+
module ClassMethods
|
76
|
+
#
|
77
|
+
# Get inherited object value if it's set
|
78
|
+
#
|
79
|
+
# @param [String, Symbol] var varibale name
|
80
|
+
#
|
81
|
+
# @return [Object, nil]
|
82
|
+
#
|
83
|
+
def __nested(var)
|
84
|
+
klass = superclass
|
85
|
+
obj = nil
|
86
|
+
loop do
|
87
|
+
obj = klass.instance_variable_get(var)
|
88
|
+
break if obj || !(klass = klass.superclass)
|
89
|
+
end
|
90
|
+
obj ? obj.clone : nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Mixins
|
3
|
+
#
|
4
|
+
# OptionsStorage modules contains method to manage with addtional options
|
5
|
+
#
|
6
|
+
module OptionsStorage
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
#
|
13
|
+
# Set the export options
|
14
|
+
#
|
15
|
+
def on_export(*args)
|
16
|
+
args.each { |opt| __options.opt_set(opt, true) }
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Set the before export options
|
21
|
+
#
|
22
|
+
def before_export(&block)
|
23
|
+
__options.opt_set(:before_export, block) if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Get the options storage
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
#
|
31
|
+
# @return [XMLable::Options::Strage]
|
32
|
+
#
|
33
|
+
def __options
|
34
|
+
@__options ||= __nested(:@__options) || Options::Storage.new
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Mixins
|
3
|
+
#
|
4
|
+
# RootStorage module contains the logic to manage with XML root element
|
5
|
+
#
|
6
|
+
module RootStorage
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# Set XML root element
|
13
|
+
#
|
14
|
+
# @param [Nokogiri::XML::Element, nil] node
|
15
|
+
#
|
16
|
+
def __set_root(node)
|
17
|
+
unless node.is_a?(Nokogiri::XML::Element)
|
18
|
+
node = Nokogiri::XML::Element.new(__root_handler.tag.to_s, @__node)
|
19
|
+
@__node.root = node
|
20
|
+
end
|
21
|
+
node.instance_variable_set(:@__handler, __root_handler)
|
22
|
+
@root = __root_handler.from_xml_element(node)
|
23
|
+
if __root_handler.namespace_prefix
|
24
|
+
node.namespace = node.namespace_scopes.find do |n|
|
25
|
+
n.prefix == __root_handler.namespace_prefix
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_missing(name, *args, &block)
|
31
|
+
return super unless key?(name)
|
32
|
+
return root unless name.to_s.end_with?('=')
|
33
|
+
self.root = args.first
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Is the current object empty?
|
38
|
+
#
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
def __empty?
|
42
|
+
return false unless super
|
43
|
+
__empty(root)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Get root object
|
48
|
+
#
|
49
|
+
# @return [XMLable::Mixins::Object]
|
50
|
+
#
|
51
|
+
def root
|
52
|
+
__set_root(nil) unless instance_variable_defined?(:@root)
|
53
|
+
@root
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Get unwraped root object's value
|
58
|
+
#
|
59
|
+
# @return [Object]
|
60
|
+
#
|
61
|
+
def root!
|
62
|
+
root.__object
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Initialize root object with params
|
67
|
+
#
|
68
|
+
# @param [XMLable::Handlers::Root, XMLable::Handlers::RootNone] h root's handler
|
69
|
+
# @param [Object] value
|
70
|
+
#
|
71
|
+
def __root_object_initialize(h, value)
|
72
|
+
return self.root = value unless value.is_a?(Hash)
|
73
|
+
value.each do |key, val|
|
74
|
+
root[key].__initialize_with(val)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Set root object content
|
80
|
+
#
|
81
|
+
# @param [Object] val
|
82
|
+
#
|
83
|
+
def root=(val)
|
84
|
+
@root.__overwrite_content(val)
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Does this object has root object with given key?
|
89
|
+
#
|
90
|
+
# @return [Boolean]
|
91
|
+
#
|
92
|
+
def key?(key)
|
93
|
+
names = ['root', __root_handler.method_name]
|
94
|
+
return __root_handler if names.include?(key.to_s)
|
95
|
+
super
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# Get root object by key
|
100
|
+
#
|
101
|
+
# @param [String] key
|
102
|
+
#
|
103
|
+
def [](key)
|
104
|
+
root if key?(key)
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Set root object value
|
109
|
+
#
|
110
|
+
# @param [String] key
|
111
|
+
# @param [Object] val
|
112
|
+
#
|
113
|
+
def []=(key, val)
|
114
|
+
self.root = val if key?(key)
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Cureent root object's handler
|
119
|
+
#
|
120
|
+
# @return [XMLable::Handlers::Root, XMLable::Handlers::RootNone]
|
121
|
+
#
|
122
|
+
def __root_handler
|
123
|
+
self.class.__root_handler
|
124
|
+
end
|
125
|
+
|
126
|
+
module ClassMethods
|
127
|
+
#
|
128
|
+
# Define root handler
|
129
|
+
#
|
130
|
+
# @see XMLable::Handler::Base#build
|
131
|
+
#
|
132
|
+
def root(*args, &block)
|
133
|
+
@__root_handler = Handlers::Root.build(*args, &block)
|
134
|
+
__define_root(@__root_handler)
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# Define root object methods
|
139
|
+
#
|
140
|
+
# @param [XMLable::Handlers::Root] h root's handler
|
141
|
+
#
|
142
|
+
def __define_root(h)
|
143
|
+
return if h.method_name == 'root'
|
144
|
+
define_method(h.method_name) { root }
|
145
|
+
define_method("#{h.method_name}=") { |val| self.root = val }
|
146
|
+
define_method("#{h.method_name}!") { root! }
|
147
|
+
define_method("__initialize_#{h.method_name}") { |val| __initialize_root(val) }
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# Root object's handler
|
152
|
+
#
|
153
|
+
# @return [XMLable::Handlers::Root, XMLable::Handlers::RootNone]
|
154
|
+
#
|
155
|
+
def __root_handler
|
156
|
+
@__root_handler ||=
|
157
|
+
__nested(:@__root_handler) || Handlers::RootNone.build(:root)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Mixins
|
3
|
+
#
|
4
|
+
# StandaloneAttribute module contains standalone attribute's logic
|
5
|
+
#
|
6
|
+
module StandaloneAttribute
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
#
|
13
|
+
# Describe attribute name/tag
|
14
|
+
#
|
15
|
+
# @param [String, Symbol] tag
|
16
|
+
#
|
17
|
+
def attr_name(tag)
|
18
|
+
@__tag = tag.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Get attribute name/tag
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
#
|
26
|
+
# @return [String]
|
27
|
+
#
|
28
|
+
def __tag
|
29
|
+
@__tag
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Mixins
|
3
|
+
#
|
4
|
+
# StandaloneElement module contains standalone element's logic
|
5
|
+
#
|
6
|
+
module StandaloneElement
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# @param [Nokogiri::XML::Element] node XML element
|
13
|
+
# @param [XMLable::Handlers::Document] handler element's handler
|
14
|
+
#
|
15
|
+
def initialize(node = nil, handler = nil)
|
16
|
+
unless node
|
17
|
+
doc = Nokogiri::XML::Document.new
|
18
|
+
node = Nokogiri::XML::Element.new(self.class.__tag, doc)
|
19
|
+
end
|
20
|
+
handler = self.class.__standalone_element_handler unless handler
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
#
|
26
|
+
# Describe element's tag name
|
27
|
+
#
|
28
|
+
# @param [String, Symbol] name
|
29
|
+
#
|
30
|
+
def tag(name)
|
31
|
+
@__tag = name.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Get tag name
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
#
|
39
|
+
# @return [String]
|
40
|
+
#
|
41
|
+
def __tag
|
42
|
+
@__tag
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Mixins
|
3
|
+
#
|
4
|
+
# ValueStorage modules contains the logic to manage XML attributes values
|
5
|
+
#
|
6
|
+
module ValueStorage
|
7
|
+
#
|
8
|
+
# Set XML attribute value
|
9
|
+
#
|
10
|
+
# @param [Nokogiri::XML::Attr] node XML attribute node
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
#
|
14
|
+
def __set_value(node)
|
15
|
+
self.__value = __cast(node.content)
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Set value
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
#
|
23
|
+
# @param [Object] val
|
24
|
+
#
|
25
|
+
def __value=(val)
|
26
|
+
@__value = val
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Overwrite XML attribute's value
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
#
|
34
|
+
# @param [Object] val
|
35
|
+
#
|
36
|
+
def __overwrite_value(val)
|
37
|
+
@__node.content = __export_to_xml(val)
|
38
|
+
self.__value = val
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Get unwraped attribute object's value
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
#
|
46
|
+
# @return [Object]
|
47
|
+
#
|
48
|
+
def __object
|
49
|
+
__value
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
#
|
54
|
+
# Get attribute value
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
#
|
58
|
+
# @return [Object]
|
59
|
+
#
|
60
|
+
def __value
|
61
|
+
@__value
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Is this element empty?
|
66
|
+
#
|
67
|
+
# @api private
|
68
|
+
#
|
69
|
+
# @return [Boolean]
|
70
|
+
#
|
71
|
+
def __empty?
|
72
|
+
return false unless super
|
73
|
+
__empty(__value)
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# @return [String]
|
78
|
+
#
|
79
|
+
def to_s
|
80
|
+
__value.to_s
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Mixins
|
3
|
+
#
|
4
|
+
# Wrapper module contains methods to wrap the primitive classes
|
5
|
+
#
|
6
|
+
module Wrapper
|
7
|
+
def method_missing(*args, &block)
|
8
|
+
__object.send(*args, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
def to_s(*args)
|
15
|
+
__object.to_s(*args)
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Is wrapped class inherits from given class?
|
20
|
+
#
|
21
|
+
# @param [Class] klass
|
22
|
+
#
|
23
|
+
# @param [Boolean]
|
24
|
+
#
|
25
|
+
def is_a?(klass)
|
26
|
+
__object.is_a?(klass)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
#
|
32
|
+
def inspect
|
33
|
+
"[Wrapper(#{__object.class})] #{__object.inspect}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module XMLable
|
2
|
+
#
|
3
|
+
# Mixins module contains object mixins modules
|
4
|
+
#
|
5
|
+
module Mixins
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require_relative 'mixins/object'
|
10
|
+
require_relative 'mixins/standalone_element'
|
11
|
+
require_relative 'mixins/standalone_attribute'
|
12
|
+
require_relative 'mixins/value_storage'
|
13
|
+
require_relative 'mixins/elements_storage'
|
14
|
+
require_relative 'mixins/attributes_storage'
|
15
|
+
require_relative 'mixins/container'
|
16
|
+
require_relative 'mixins/content_storage'
|
17
|
+
require_relative 'mixins/document_storage'
|
18
|
+
require_relative 'mixins/root_storage'
|
19
|
+
require_relative 'mixins/options_storage'
|
20
|
+
require_relative 'mixins/namespace_definitions_storage'
|
21
|
+
require_relative 'mixins/export'
|
22
|
+
require_relative 'mixins/bare_value'
|
23
|
+
require_relative 'mixins/instantiable'
|
24
|
+
require_relative 'mixins/castable'
|
25
|
+
require_relative 'mixins/wrapper'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Options
|
3
|
+
#
|
4
|
+
# NokogiriExport class contains Nokogiri's export settings
|
5
|
+
#
|
6
|
+
# @see http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Node/SaveOptions
|
7
|
+
#
|
8
|
+
class NokogiriExport < Hash
|
9
|
+
#
|
10
|
+
# Nokogiri's save_with options
|
11
|
+
#
|
12
|
+
# @return [Nokogiri::XML::Node::SaveOptions.new]
|
13
|
+
#
|
14
|
+
def save_with
|
15
|
+
self[:save_with] ||= Nokogiri::XML::Node::SaveOptions.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module XMLable
|
2
|
+
module Options
|
3
|
+
#
|
4
|
+
# Storage class stores handlers options
|
5
|
+
#
|
6
|
+
class Storage < Hash
|
7
|
+
#
|
8
|
+
# Initialize
|
9
|
+
#
|
10
|
+
# @param [Hash] hash initial params
|
11
|
+
#
|
12
|
+
def new(hash = {})
|
13
|
+
opts_set(hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Set multiple options
|
18
|
+
#
|
19
|
+
# @param [Hash] hash
|
20
|
+
#
|
21
|
+
def opts_set(hash)
|
22
|
+
hash.each { |key, value| opt_set(key, value) }
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Set option
|
27
|
+
#
|
28
|
+
# @param [String, Symbol] key
|
29
|
+
# @param [Object] value
|
30
|
+
#
|
31
|
+
# @return [XMLable::Options::Storage]
|
32
|
+
#
|
33
|
+
def opt_set(key, value)
|
34
|
+
key = key.to_s
|
35
|
+
value = false if key =~ /^no_/
|
36
|
+
key = key.sub(/^no_/, '').to_sym
|
37
|
+
method = "opt_set_#{key}"
|
38
|
+
respond_to?(method) ? send(method, value) : opt_default_set(key, value)
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Set the drop empty objects
|
44
|
+
#
|
45
|
+
# @param [Boolean]
|
46
|
+
#
|
47
|
+
def opt_set_drop_empty(value)
|
48
|
+
self[:drop_empty_attributes] = self[:drop_empty_elements] = value
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Set the drop undescribed objects
|
53
|
+
#
|
54
|
+
# @param [Boolean]
|
55
|
+
#
|
56
|
+
def opt_set_drop_undescribed(value)
|
57
|
+
self[:drop_undescribed_attributes] = self[:drop_undescribed_elements] = value
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Default option setter
|
62
|
+
#
|
63
|
+
# @param [String, Symbol] key
|
64
|
+
# @param [Object] value
|
65
|
+
#
|
66
|
+
def opt_default_set(key, value)
|
67
|
+
self[key.to_sym] = value
|
68
|
+
end
|
69
|
+
|
70
|
+
%i[undescribed empty].each do |m|
|
71
|
+
%i[attributes elements].each do |e|
|
72
|
+
define_method("drop_#{m}_#{e}?") { fetch(:"drop_#{m}_#{e}", false) }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Merge options
|
78
|
+
#
|
79
|
+
# @param [Hash, XMLable::Options::Storage] opts
|
80
|
+
#
|
81
|
+
# @return [XMLable::Options::Storage]
|
82
|
+
#
|
83
|
+
def merge_opts(other)
|
84
|
+
merger = proc do |_, v1, v2|
|
85
|
+
if [v1, v2].all? { |h| h.is_a?(Hash) }
|
86
|
+
v1.merge(v2, &merger)
|
87
|
+
elsif [v1, v2].all? { |h| h.is_a?(Array) }
|
88
|
+
v1 + v2
|
89
|
+
else
|
90
|
+
v2
|
91
|
+
end
|
92
|
+
end
|
93
|
+
merge(other, &merger)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
XMLable::Builder.tap do |b|
|
2
|
+
b.define_type :string, :str, String do
|
3
|
+
cast { |val| val.to_s }
|
4
|
+
end
|
5
|
+
|
6
|
+
b.define_type :integer, :int, Integer do
|
7
|
+
cast { |val| val.to_i }
|
8
|
+
export_to_json { |val| val }
|
9
|
+
end
|
10
|
+
|
11
|
+
b.define_type :float, Float do
|
12
|
+
cast { |val| val.to_f }
|
13
|
+
export_to_json { |val| val }
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
b.define_type :date, Date do
|
18
|
+
cast do |val|
|
19
|
+
Date.parse(val) if val.is_a?(String) && !val.empty?
|
20
|
+
end
|
21
|
+
export { |val| val.is_a?(Date) ? val.to_s : val }
|
22
|
+
end
|
23
|
+
|
24
|
+
b.define_type :bool, :boolean do
|
25
|
+
cast do |val|
|
26
|
+
!['false', '0', ''].include?(val.to_s.downcase)
|
27
|
+
end
|
28
|
+
|
29
|
+
export_to_json { |val| val }
|
30
|
+
end
|
31
|
+
end
|