lutaml-model 0.3.10 → 0.3.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +25 -23
- data/Gemfile +1 -0
- data/LICENSE.md +33 -0
- data/README.adoc +200 -15
- data/lib/lutaml/model/attribute.rb +28 -3
- data/lib/lutaml/model/error/incorrect_mapping_argument_error.rb +6 -0
- data/lib/lutaml/model/error/type_not_enabled_error.rb +9 -0
- data/lib/lutaml/model/error.rb +2 -0
- data/lib/lutaml/model/json_adapter/standard_json_adapter.rb +1 -2
- data/lib/lutaml/model/key_value_mapping.rb +25 -1
- data/lib/lutaml/model/key_value_mapping_rule.rb +31 -1
- data/lib/lutaml/model/mapping_hash.rb +22 -0
- data/lib/lutaml/model/mapping_rule.rb +28 -22
- data/lib/lutaml/model/serialize.rb +120 -64
- data/lib/lutaml/model/type.rb +10 -0
- data/lib/lutaml/model/utils.rb +34 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +14 -6
- data/lib/lutaml/model/xml_adapter/builder/ox.rb +4 -0
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +20 -9
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +9 -1
- data/lib/lutaml/model/xml_adapter/xml_attribute.rb +10 -0
- data/lib/lutaml/model/xml_adapter/xml_document.rb +86 -35
- data/lib/lutaml/model/xml_adapter/xml_element.rb +13 -3
- data/lib/lutaml/model/xml_adapter/xml_namespace.rb +1 -1
- data/lib/lutaml/model/xml_mapping.rb +60 -9
- data/lib/lutaml/model/xml_mapping_rule.rb +64 -4
- data/lib/lutaml/model/yaml_adapter/standard_yaml_adapter.rb +10 -5
- data/lutaml-model.gemspec +0 -1
- metadata +5 -16
@@ -55,6 +55,7 @@ module Lutaml
|
|
55
55
|
end
|
56
56
|
|
57
57
|
index_hash = {}
|
58
|
+
content = []
|
58
59
|
|
59
60
|
element.element_order.each do |name|
|
60
61
|
index_hash[name] ||= -1
|
@@ -68,15 +69,20 @@ module Lutaml
|
|
68
69
|
value = attribute_value_for(element, element_rule)
|
69
70
|
|
70
71
|
if element_rule == xml_mapping.content_mapping
|
71
|
-
text =
|
72
|
+
text = xml_mapping.content_mapping.serialize(element)
|
72
73
|
text = text[curr_index] if text.is_a?(Array)
|
73
74
|
|
74
|
-
|
75
|
+
if element.mixed?
|
76
|
+
prefixed_xml.text text
|
77
|
+
else
|
78
|
+
content << text
|
79
|
+
end
|
75
80
|
elsif !value.nil? || element_rule.render_nil?
|
76
81
|
value = value[curr_index] if attribute_def.collection?
|
77
82
|
|
78
83
|
add_to_xml(
|
79
84
|
xml,
|
85
|
+
element,
|
80
86
|
element_rule.prefix,
|
81
87
|
value,
|
82
88
|
options.merge(
|
@@ -86,12 +92,14 @@ module Lutaml
|
|
86
92
|
)
|
87
93
|
end
|
88
94
|
end
|
95
|
+
|
96
|
+
prefixed_xml.text content.join
|
89
97
|
end
|
90
98
|
end
|
91
99
|
end
|
92
100
|
|
93
101
|
class NokogiriElement < XmlElement
|
94
|
-
def initialize(node, root_node: nil)
|
102
|
+
def initialize(node, root_node: nil, default_namespace: nil)
|
95
103
|
if root_node
|
96
104
|
node.namespaces.each do |prefix, name|
|
97
105
|
namespace = XmlNamespace.new(name, prefix)
|
@@ -115,14 +123,15 @@ module Lutaml
|
|
115
123
|
namespace_prefix: attr.namespace&.prefix,
|
116
124
|
)
|
117
125
|
end
|
118
|
-
|
126
|
+
default_namespace = node.namespace&.href if root_node.nil?
|
119
127
|
super(
|
120
128
|
node.name,
|
121
129
|
attributes,
|
122
|
-
parse_all_children(node, root_node: root_node || self),
|
130
|
+
parse_all_children(node, root_node: root_node || self, default_namespace: default_namespace),
|
123
131
|
node.text,
|
124
132
|
parent_document: root_node,
|
125
133
|
namespace_prefix: node.namespace&.prefix,
|
134
|
+
default_namespace: default_namespace
|
126
135
|
)
|
127
136
|
end
|
128
137
|
|
@@ -137,8 +146,10 @@ module Lutaml
|
|
137
146
|
if name == "text"
|
138
147
|
builder.text(text)
|
139
148
|
else
|
140
|
-
builder.
|
141
|
-
children.each
|
149
|
+
builder.public_send(name, build_attributes(self)) do |xml|
|
150
|
+
children.each do |child|
|
151
|
+
child.to_xml(xml)
|
152
|
+
end
|
142
153
|
end
|
143
154
|
end
|
144
155
|
|
@@ -153,9 +164,9 @@ module Lutaml
|
|
153
164
|
end
|
154
165
|
end
|
155
166
|
|
156
|
-
def parse_all_children(node, root_node: nil)
|
167
|
+
def parse_all_children(node, root_node: nil, default_namespace: nil)
|
157
168
|
node.children.map do |child|
|
158
|
-
NokogiriElement.new(child, root_node: root_node)
|
169
|
+
NokogiriElement.new(child, root_node: root_node, default_namespace: default_namespace)
|
159
170
|
end
|
160
171
|
end
|
161
172
|
|
@@ -42,6 +42,7 @@ module Lutaml
|
|
42
42
|
builder.create_and_add_element(tag_name,
|
43
43
|
attributes: attributes) do |el|
|
44
44
|
index_hash = {}
|
45
|
+
content = []
|
45
46
|
|
46
47
|
element.element_order.each do |name|
|
47
48
|
index_hash[name] ||= -1
|
@@ -58,12 +59,17 @@ module Lutaml
|
|
58
59
|
text = element.send(xml_mapping.content_mapping.to)
|
59
60
|
text = text[curr_index] if text.is_a?(Array)
|
60
61
|
|
61
|
-
|
62
|
+
if element.mixed?
|
63
|
+
el.add_text(el, text)
|
64
|
+
else
|
65
|
+
content << text
|
66
|
+
end
|
62
67
|
elsif !value.nil? || element_rule.render_nil?
|
63
68
|
value = value[curr_index] if attribute_def.collection?
|
64
69
|
|
65
70
|
add_to_xml(
|
66
71
|
el,
|
72
|
+
element,
|
67
73
|
nil,
|
68
74
|
value,
|
69
75
|
options.merge(
|
@@ -73,6 +79,8 @@ module Lutaml
|
|
73
79
|
)
|
74
80
|
end
|
75
81
|
end
|
82
|
+
|
83
|
+
el.add_text(el, content.join)
|
76
84
|
end
|
77
85
|
end
|
78
86
|
end
|
@@ -66,24 +66,43 @@ module Lutaml
|
|
66
66
|
options[:tag_name] = rule.name
|
67
67
|
|
68
68
|
options[:mapper_class] = attribute&.type if attribute
|
69
|
+
options[:namespace_set] = set_namespace?(rule)
|
69
70
|
|
70
71
|
options
|
71
72
|
end
|
72
73
|
|
73
|
-
def parse_element(element)
|
74
|
+
def parse_element(element, klass = nil, format = nil)
|
74
75
|
result = Lutaml::Model::MappingHash.new
|
75
76
|
result.item_order = element.order
|
76
77
|
|
77
78
|
element.children.each_with_object(result) do |child, hash|
|
78
|
-
|
79
|
+
attr = klass.attribute_for_child(child.name, format) if klass&.<= Serialize
|
80
|
+
|
81
|
+
value = if child.text?
|
82
|
+
child.text
|
83
|
+
elsif attr&.raw?
|
84
|
+
child.children.map do |c|
|
85
|
+
next c.text if c.text?
|
86
|
+
|
87
|
+
c.to_xml.doc.root.to_xml({})
|
88
|
+
end.join
|
89
|
+
else
|
90
|
+
parse_element(child, attr&.type || klass, format)
|
91
|
+
end
|
79
92
|
|
80
|
-
hash[child.
|
81
|
-
[hash[child.
|
93
|
+
hash[child.namespaced_name] = if hash[child.namespaced_name]
|
94
|
+
[hash[child.namespaced_name], value].flatten
|
82
95
|
else
|
83
96
|
value
|
84
97
|
end
|
85
98
|
end
|
86
99
|
|
100
|
+
result.merge(attributes_hash(element))
|
101
|
+
end
|
102
|
+
|
103
|
+
def attributes_hash(element)
|
104
|
+
result = Lutaml::Model::MappingHash.new
|
105
|
+
|
87
106
|
element.attributes.each_value do |attr|
|
88
107
|
if attr.unprefixed_name == "schemaLocation"
|
89
108
|
result["__schema_location"] = {
|
@@ -92,7 +111,7 @@ module Lutaml
|
|
92
111
|
schema_location: attr.value,
|
93
112
|
}
|
94
113
|
else
|
95
|
-
result[attr.
|
114
|
+
result[attr.namespaced_name] = attr.value
|
96
115
|
end
|
97
116
|
end
|
98
117
|
|
@@ -107,10 +126,10 @@ module Lutaml
|
|
107
126
|
end
|
108
127
|
end
|
109
128
|
|
110
|
-
def add_to_xml(xml, prefix, value, options = {})
|
129
|
+
def add_to_xml(xml, element, prefix, value, options = {})
|
111
130
|
if value.is_a?(Array)
|
112
131
|
value.each do |item|
|
113
|
-
add_to_xml(xml, prefix, item, options)
|
132
|
+
add_to_xml(xml, element, prefix, item, options)
|
114
133
|
end
|
115
134
|
|
116
135
|
return
|
@@ -120,7 +139,7 @@ module Lutaml
|
|
120
139
|
rule = options[:rule]
|
121
140
|
|
122
141
|
if rule.custom_methods[:to]
|
123
|
-
|
142
|
+
options[:mapper_class].new.send(rule.custom_methods[:to], element, xml.parent, xml)
|
124
143
|
return
|
125
144
|
end
|
126
145
|
|
@@ -130,21 +149,29 @@ module Lutaml
|
|
130
149
|
value,
|
131
150
|
options.merge({ rule: rule, attribute: attribute }),
|
132
151
|
)
|
133
|
-
|
152
|
+
elsif rule.prefix_set?
|
134
153
|
xml.create_and_add_element(rule.name, prefix: prefix) do
|
135
|
-
|
136
|
-
|
154
|
+
add_value(xml, value, attribute)
|
155
|
+
end
|
156
|
+
else
|
157
|
+
xml.create_and_add_element(rule.name) do
|
158
|
+
add_value(xml, value, attribute)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
137
162
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
163
|
+
def add_value(xml, value, attribute)
|
164
|
+
if !value.nil?
|
165
|
+
serialized_value = attribute.type.serialize(value)
|
166
|
+
|
167
|
+
if attribute.type == Lutaml::Model::Type::Hash
|
168
|
+
serialized_value.each do |key, val|
|
169
|
+
xml.create_and_add_element(key) do |element|
|
170
|
+
element.text(val)
|
146
171
|
end
|
147
172
|
end
|
173
|
+
else
|
174
|
+
xml.add_text(xml, serialized_value)
|
148
175
|
end
|
149
176
|
end
|
150
177
|
end
|
@@ -176,21 +203,28 @@ module Lutaml
|
|
176
203
|
prefixed_xml.add_namespace_prefix(nil)
|
177
204
|
end
|
178
205
|
|
206
|
+
xml_mapping.attributes.each do |attribute_rule|
|
207
|
+
attribute_rule.serialize_attribute(element, prefixed_xml.parent, xml)
|
208
|
+
end
|
209
|
+
|
179
210
|
xml_mapping.elements.each do |element_rule|
|
180
211
|
attribute_def = attribute_definition_for(element, element_rule,
|
181
212
|
mapper_class: mapper_class)
|
182
213
|
|
183
|
-
|
214
|
+
if attribute_def
|
215
|
+
value = attribute_value_for(element, element_rule)
|
184
216
|
|
185
|
-
|
217
|
+
next if value.nil? && !element_rule.render_nil?
|
186
218
|
|
187
|
-
|
219
|
+
value = [value] if attribute_def.collection? && !value.is_a?(Array)
|
220
|
+
end
|
188
221
|
|
189
222
|
add_to_xml(
|
190
223
|
prefixed_xml,
|
224
|
+
element,
|
191
225
|
element_rule.prefix,
|
192
226
|
value,
|
193
|
-
options.merge({ attribute: attribute_def, rule: element_rule }),
|
227
|
+
options.merge({ attribute: attribute_def, rule: element_rule, mapper_class: mapper_class }),
|
194
228
|
)
|
195
229
|
end
|
196
230
|
|
@@ -199,7 +233,7 @@ module Lutaml
|
|
199
233
|
@root.send(content_rule.custom_methods[:to], element,
|
200
234
|
prefixed_xml.parent, prefixed_xml)
|
201
235
|
else
|
202
|
-
text =
|
236
|
+
text = content_rule.serialize(element)
|
203
237
|
text = text.join if text.is_a?(Array)
|
204
238
|
prefixed_xml.add_text(xml, text)
|
205
239
|
end
|
@@ -216,15 +250,21 @@ module Lutaml
|
|
216
250
|
mapper_class ? mapper_class.mappings_for(:xml).mixed_content? : false
|
217
251
|
end
|
218
252
|
|
219
|
-
def
|
253
|
+
def set_namespace?(rule)
|
254
|
+
rule.nil? || !rule.namespace_set? || !rule.namespace.nil?
|
255
|
+
end
|
256
|
+
|
257
|
+
def build_namespace_attributes(klass, processed = {}, options = {})
|
220
258
|
xml_mappings = klass.mappings_for(:xml)
|
221
259
|
attributes = klass.attributes
|
222
260
|
|
223
261
|
attrs = {}
|
224
262
|
|
225
|
-
if xml_mappings.namespace_uri
|
226
|
-
prefixed_name = [
|
227
|
-
|
263
|
+
if xml_mappings.namespace_uri && set_namespace?(options[:caller_rule])
|
264
|
+
prefixed_name = [
|
265
|
+
"xmlns",
|
266
|
+
xml_mappings.namespace_prefix,
|
267
|
+
].compact.join(":")
|
228
268
|
|
229
269
|
attrs[prefixed_name] = xml_mappings.namespace_uri
|
230
270
|
end
|
@@ -239,14 +279,16 @@ module Lutaml
|
|
239
279
|
type = if mapping_rule.delegate
|
240
280
|
attributes[mapping_rule.delegate].type.attributes[mapping_rule.to].type
|
241
281
|
else
|
242
|
-
attributes[mapping_rule.to]
|
282
|
+
attributes[mapping_rule.to]&.type
|
243
283
|
end
|
244
284
|
|
285
|
+
next unless type
|
286
|
+
|
245
287
|
if type <= Lutaml::Model::Serialize
|
246
|
-
attrs = attrs.merge(build_namespace_attributes(type, processed))
|
288
|
+
attrs = attrs.merge(build_namespace_attributes(type, processed, { caller_rule: mapping_rule }))
|
247
289
|
end
|
248
290
|
|
249
|
-
if mapping_rule.namespace
|
291
|
+
if mapping_rule.namespace && mapping_rule.prefix && mapping_rule.name != "lang"
|
250
292
|
attrs["xmlns:#{mapping_rule.prefix}"] = mapping_rule.namespace
|
251
293
|
end
|
252
294
|
end
|
@@ -255,22 +297,31 @@ module Lutaml
|
|
255
297
|
end
|
256
298
|
|
257
299
|
def build_attributes(element, xml_mapping, options = {})
|
258
|
-
attrs =
|
300
|
+
attrs = if options.fetch(:namespace_set, true)
|
301
|
+
namespace_attributes(xml_mapping)
|
302
|
+
else
|
303
|
+
{}
|
304
|
+
end
|
305
|
+
|
306
|
+
if element.respond_to?(:schema_location) && element.schema_location
|
307
|
+
attrs.merge!(element.schema_location.to_xml_attributes)
|
308
|
+
end
|
259
309
|
|
260
310
|
xml_mapping.attributes.each_with_object(attrs) do |mapping_rule, hash|
|
261
311
|
next if options[:except]&.include?(mapping_rule.to)
|
312
|
+
next if mapping_rule.custom_methods[:to]
|
262
313
|
|
263
|
-
if mapping_rule.namespace
|
314
|
+
if mapping_rule.namespace && mapping_rule.prefix && mapping_rule.name != "lang"
|
264
315
|
hash["xmlns:#{mapping_rule.prefix}"] = mapping_rule.namespace
|
265
316
|
end
|
266
317
|
|
267
|
-
hash[mapping_rule.prefixed_name] =
|
318
|
+
hash[mapping_rule.prefixed_name] = mapping_rule.to_value_for(element)
|
268
319
|
end
|
269
320
|
|
270
321
|
xml_mapping.elements.each_with_object(attrs) do |mapping_rule, hash|
|
271
322
|
next if options[:except]&.include?(mapping_rule.to)
|
272
323
|
|
273
|
-
if mapping_rule.namespace
|
324
|
+
if mapping_rule.namespace && mapping_rule.prefix
|
274
325
|
hash["xmlns:#{mapping_rule.prefix}"] = mapping_rule.namespace
|
275
326
|
end
|
276
327
|
end
|
@@ -16,7 +16,8 @@ module Lutaml
|
|
16
16
|
children = [],
|
17
17
|
text = nil,
|
18
18
|
parent_document: nil,
|
19
|
-
namespace_prefix: nil
|
19
|
+
namespace_prefix: nil,
|
20
|
+
default_namespace: nil
|
20
21
|
)
|
21
22
|
@name = extract_name(name)
|
22
23
|
@namespace_prefix = namespace_prefix || extract_namespace_prefix(name)
|
@@ -24,11 +25,20 @@ module Lutaml
|
|
24
25
|
@children = children
|
25
26
|
@text = text
|
26
27
|
@parent_document = parent_document
|
28
|
+
@default_namespace = default_namespace
|
27
29
|
end
|
28
30
|
|
29
31
|
def name
|
30
|
-
|
31
|
-
|
32
|
+
return @name unless namespace_prefix
|
33
|
+
|
34
|
+
"#{namespace_prefix}:#{@name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def namespaced_name
|
38
|
+
if namespaces[namespace_prefix] && !text?
|
39
|
+
"#{namespaces[namespace_prefix].uri}:#{@name}"
|
40
|
+
elsif @default_namespace && !text?
|
41
|
+
"#{@default_namespace}:#{name}"
|
32
42
|
else
|
33
43
|
@name
|
34
44
|
end
|
@@ -6,7 +6,8 @@ module Lutaml
|
|
6
6
|
attr_reader :root_element,
|
7
7
|
:namespace_uri,
|
8
8
|
:namespace_prefix,
|
9
|
-
:mixed_content
|
9
|
+
:mixed_content,
|
10
|
+
:ordered
|
10
11
|
|
11
12
|
def initialize
|
12
13
|
@elements = {}
|
@@ -16,10 +17,12 @@ module Lutaml
|
|
16
17
|
end
|
17
18
|
|
18
19
|
alias mixed_content? mixed_content
|
20
|
+
alias ordered? ordered
|
19
21
|
|
20
|
-
def root(name, mixed: false)
|
22
|
+
def root(name, mixed: false, ordered: false)
|
21
23
|
@root_element = name
|
22
24
|
@mixed_content = mixed
|
25
|
+
@ordered = ordered || mixed # mixed contenet will always be ordered
|
23
26
|
end
|
24
27
|
|
25
28
|
def prefixed_root
|
@@ -38,37 +41,46 @@ module Lutaml
|
|
38
41
|
# rubocop:disable Metrics/ParameterLists
|
39
42
|
def map_element(
|
40
43
|
name,
|
41
|
-
to
|
44
|
+
to: nil,
|
42
45
|
render_nil: false,
|
43
46
|
with: {},
|
44
47
|
delegate: nil,
|
45
48
|
namespace: (namespace_set = false
|
46
49
|
nil),
|
47
|
-
prefix:
|
50
|
+
prefix: (prefix_set = false
|
51
|
+
nil)
|
48
52
|
)
|
49
|
-
|
53
|
+
validate!(name, to, with)
|
54
|
+
|
55
|
+
rule = XmlMappingRule.new(
|
50
56
|
name,
|
51
57
|
to: to,
|
52
58
|
render_nil: render_nil,
|
53
59
|
with: with,
|
54
60
|
delegate: delegate,
|
55
61
|
namespace: namespace,
|
62
|
+
default_namespace: namespace_uri,
|
56
63
|
prefix: prefix,
|
57
64
|
namespace_set: namespace_set != false,
|
65
|
+
prefix_set: prefix_set != false,
|
58
66
|
)
|
67
|
+
@elements[rule.namespaced_name] = rule
|
59
68
|
end
|
60
69
|
|
61
70
|
def map_attribute(
|
62
71
|
name,
|
63
|
-
to
|
72
|
+
to: nil,
|
64
73
|
render_nil: false,
|
65
74
|
with: {},
|
66
75
|
delegate: nil,
|
67
76
|
namespace: (namespace_set = false
|
68
77
|
nil),
|
69
|
-
prefix:
|
78
|
+
prefix: (prefix_set = false
|
79
|
+
nil)
|
70
80
|
)
|
71
|
-
|
81
|
+
validate!(name, to, with)
|
82
|
+
|
83
|
+
rule = XmlMappingRule.new(
|
72
84
|
name,
|
73
85
|
to: to,
|
74
86
|
render_nil: render_nil,
|
@@ -76,19 +88,25 @@ module Lutaml
|
|
76
88
|
delegate: delegate,
|
77
89
|
namespace: namespace,
|
78
90
|
prefix: prefix,
|
91
|
+
attribute: true,
|
92
|
+
default_namespace: namespace_uri,
|
79
93
|
namespace_set: namespace_set != false,
|
94
|
+
prefix_set: prefix_set != false,
|
80
95
|
)
|
96
|
+
@attributes[rule.namespaced_name] = rule
|
81
97
|
end
|
82
98
|
|
83
99
|
# rubocop:enable Metrics/ParameterLists
|
84
100
|
|
85
101
|
def map_content(
|
86
|
-
to
|
102
|
+
to: nil,
|
87
103
|
render_nil: false,
|
88
104
|
with: {},
|
89
105
|
delegate: nil,
|
90
106
|
mixed: false
|
91
107
|
)
|
108
|
+
validate!("content", to, with)
|
109
|
+
|
92
110
|
@content_mapping = XmlMappingRule.new(
|
93
111
|
nil,
|
94
112
|
to: to,
|
@@ -99,6 +117,18 @@ module Lutaml
|
|
99
117
|
)
|
100
118
|
end
|
101
119
|
|
120
|
+
def validate!(key, to, with)
|
121
|
+
if to.nil? && with.empty?
|
122
|
+
msg = ":to or :with argument is required for mapping '#{key}'"
|
123
|
+
raise IncorrectMappingArgumentsError.new(msg)
|
124
|
+
end
|
125
|
+
|
126
|
+
if !with.empty? && (with[:from].nil? || with[:to].nil?)
|
127
|
+
msg = ":with argument for mapping '#{key}' requires :to and :from keys"
|
128
|
+
raise IncorrectMappingArgumentsError.new(msg)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
102
132
|
def elements
|
103
133
|
@elements.values
|
104
134
|
end
|
@@ -136,6 +166,27 @@ module Lutaml
|
|
136
166
|
end
|
137
167
|
end
|
138
168
|
end
|
169
|
+
|
170
|
+
def deep_dup
|
171
|
+
self.class.new.tap do |xml_mapping|
|
172
|
+
xml_mapping.root(@root_element.dup, mixed: @mixed_content, ordered: @ordered)
|
173
|
+
xml_mapping.namespace(@namespace_uri.dup, @namespace_prefix.dup)
|
174
|
+
|
175
|
+
xml_mapping.instance_variable_set(:@attributes, dup_mappings(@attributes))
|
176
|
+
xml_mapping.instance_variable_set(:@elements, dup_mappings(@elements))
|
177
|
+
xml_mapping.instance_variable_set(:@content_mapping, @content_mapping&.deep_dup)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def dup_mappings(mappings)
|
182
|
+
new_mappings = {}
|
183
|
+
|
184
|
+
mappings.each do |key, mapping_rule|
|
185
|
+
new_mappings[key] = mapping_rule.deep_dup
|
186
|
+
end
|
187
|
+
|
188
|
+
new_mappings
|
189
|
+
end
|
139
190
|
end
|
140
191
|
end
|
141
192
|
end
|
@@ -3,7 +3,7 @@ require_relative "mapping_rule"
|
|
3
3
|
module Lutaml
|
4
4
|
module Model
|
5
5
|
class XmlMappingRule < MappingRule
|
6
|
-
attr_reader :namespace, :prefix
|
6
|
+
attr_reader :namespace, :prefix, :mixed_content, :default_namespace
|
7
7
|
|
8
8
|
def initialize(
|
9
9
|
name,
|
@@ -14,7 +14,10 @@ module Lutaml
|
|
14
14
|
namespace: nil,
|
15
15
|
prefix: nil,
|
16
16
|
mixed_content: false,
|
17
|
-
namespace_set: false
|
17
|
+
namespace_set: false,
|
18
|
+
prefix_set: false,
|
19
|
+
attribute: false,
|
20
|
+
default_namespace: nil
|
18
21
|
)
|
19
22
|
super(
|
20
23
|
name,
|
@@ -22,8 +25,7 @@ module Lutaml
|
|
22
25
|
render_nil: render_nil,
|
23
26
|
with: with,
|
24
27
|
delegate: delegate,
|
25
|
-
|
26
|
-
namespace_set: namespace_set,
|
28
|
+
attribute: attribute,
|
27
29
|
)
|
28
30
|
|
29
31
|
@namespace = if namespace.to_s == "inherit"
|
@@ -33,6 +35,64 @@ module Lutaml
|
|
33
35
|
namespace
|
34
36
|
end
|
35
37
|
@prefix = prefix
|
38
|
+
@mixed_content = mixed_content
|
39
|
+
|
40
|
+
@default_namespace = default_namespace
|
41
|
+
|
42
|
+
@namespace_set = namespace_set
|
43
|
+
@prefix_set = prefix_set
|
44
|
+
end
|
45
|
+
|
46
|
+
def namespace_set?
|
47
|
+
!!@namespace_set
|
48
|
+
end
|
49
|
+
|
50
|
+
def prefix_set?
|
51
|
+
!!@prefix_set
|
52
|
+
end
|
53
|
+
|
54
|
+
def content_mapping?
|
55
|
+
name.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
def mixed_content?
|
59
|
+
!!@mixed_content
|
60
|
+
end
|
61
|
+
|
62
|
+
def prefixed_name
|
63
|
+
if prefix
|
64
|
+
"#{prefix}:#{name}"
|
65
|
+
else
|
66
|
+
name
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def namespaced_name
|
71
|
+
if name == "lang"
|
72
|
+
"#{prefix}:#{name}"
|
73
|
+
elsif namespace_set? || @attribute
|
74
|
+
[namespace, name].compact.join(":")
|
75
|
+
elsif default_namespace
|
76
|
+
"#{default_namespace}:#{name}"
|
77
|
+
else
|
78
|
+
name
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def deep_dup
|
83
|
+
self.class.new(
|
84
|
+
name.dup,
|
85
|
+
to: to,
|
86
|
+
render_nil: render_nil,
|
87
|
+
with: Utils.deep_dup(custom_methods),
|
88
|
+
delegate: delegate,
|
89
|
+
namespace: namespace.dup,
|
90
|
+
prefix: prefix.dup,
|
91
|
+
mixed_content: mixed_content,
|
92
|
+
namespace_set: namespace_set?,
|
93
|
+
prefix_set: prefix_set?,
|
94
|
+
default_namespace: default_namespace.dup,
|
95
|
+
)
|
36
96
|
end
|
37
97
|
end
|
38
98
|
end
|
@@ -5,12 +5,17 @@ module Lutaml
|
|
5
5
|
module Model
|
6
6
|
module YamlAdapter
|
7
7
|
class StandardYamlAdapter < YamlDocument
|
8
|
+
PERMITTED_CLASSES_BASE = [Date, Time, DateTime, Symbol, Hash,
|
9
|
+
Array].freeze
|
10
|
+
|
11
|
+
PERMITTED_CLASSES = if defined?(BigDecimal)
|
12
|
+
PERMITTED_CLASSES_BASE + [BigDecimal]
|
13
|
+
else
|
14
|
+
PERMITTED_CLASSES_BASE
|
15
|
+
end.freeze
|
16
|
+
|
8
17
|
def self.parse(yaml)
|
9
|
-
YAML.safe_load(
|
10
|
-
yaml,
|
11
|
-
permitted_classes: [Date, Time, DateTime, Symbol,
|
12
|
-
BigDecimal, Hash, Array],
|
13
|
-
)
|
18
|
+
YAML.safe_load(yaml, permitted_classes: PERMITTED_CLASSES)
|
14
19
|
end
|
15
20
|
|
16
21
|
def to_yaml(options = {})
|