xmlable 0.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|