lutaml-model 0.3.6 → 0.3.8
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/.rubocop_todo.yml +14 -12
- data/README.adoc +30 -26
- data/lib/lutaml/model/attribute.rb +27 -0
- data/lib/lutaml/model/serialize.rb +100 -127
- data/lib/lutaml/model/type.rb +2 -0
- data/lib/lutaml/model/utils.rb +45 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +73 -0
- data/lib/lutaml/model/xml_adapter/builder/ox.rb +89 -0
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +19 -92
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +22 -94
- data/lib/lutaml/model/xml_adapter/xml_document.rb +111 -7
- data/lib/lutaml/model/yaml_adapter/standard_yaml_adapter.rb +0 -12
- data/lib/lutaml/model.rb +1 -0
- metadata +5 -2
data/lib/lutaml/model/version.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module XmlAdapter
|
4
|
+
module Builder
|
5
|
+
class Nokogiri
|
6
|
+
def self.build(options = {})
|
7
|
+
if block_given?
|
8
|
+
::Nokogiri::XML::Builder.new(options) do |xml|
|
9
|
+
yield(new(xml))
|
10
|
+
end
|
11
|
+
else
|
12
|
+
new(::Nokogiri::XML::Builder.new(options))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :xml
|
17
|
+
|
18
|
+
def initialize(xml)
|
19
|
+
@xml = xml
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_element(name, attributes = {})
|
23
|
+
xml.doc.create_element(name, attributes)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_element(element, child)
|
27
|
+
element.add_child(child)
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_and_add_element(element_name, prefix: nil, attributes: {})
|
31
|
+
add_namespace_prefix(prefix) if prefix
|
32
|
+
|
33
|
+
if block_given?
|
34
|
+
public_send(element_name, attributes) do
|
35
|
+
yield(self)
|
36
|
+
end
|
37
|
+
else
|
38
|
+
public_send(element_name, attributes)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_text(element, text)
|
43
|
+
if element.is_a?(self.class)
|
44
|
+
element = element.xml.parent
|
45
|
+
end
|
46
|
+
|
47
|
+
add_element(element, ::Nokogiri::XML::Text.new(text.to_s, xml.doc))
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_namespace_prefix(prefix)
|
51
|
+
xml[prefix] if prefix
|
52
|
+
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_missing(method_name, *args)
|
57
|
+
if block_given?
|
58
|
+
xml.public_send(method_name, *args) do
|
59
|
+
yield(xml)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
xml.public_send(method_name, *args)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def respond_to_missing?(method_name, include_private = false)
|
67
|
+
xml.respond_to?(method_name) || super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module XmlAdapter
|
4
|
+
module Builder
|
5
|
+
class Ox
|
6
|
+
def self.build(options = {})
|
7
|
+
if block_given?
|
8
|
+
::Ox::Builder.new(options) do |xml|
|
9
|
+
yield(new(xml))
|
10
|
+
end
|
11
|
+
else
|
12
|
+
new(::Ox::Builder.new(options))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :xml
|
17
|
+
|
18
|
+
def initialize(xml)
|
19
|
+
@xml = xml
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_element(name, attributes = {})
|
23
|
+
if block_given?
|
24
|
+
xml.element(name, attributes) do |element|
|
25
|
+
yield(self.class.new(element))
|
26
|
+
end
|
27
|
+
else
|
28
|
+
xml.element(name, attributes)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_element(element, child)
|
33
|
+
element << child
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_and_add_element(element_name, prefix: nil, attributes: {})
|
37
|
+
prefixed_name = if prefix
|
38
|
+
"#{prefix}:#{element_name}"
|
39
|
+
else
|
40
|
+
element_name
|
41
|
+
end
|
42
|
+
|
43
|
+
if block_given?
|
44
|
+
xml.element(prefixed_name, attributes) do |element|
|
45
|
+
yield(self.class.new(element))
|
46
|
+
end
|
47
|
+
else
|
48
|
+
xml.element(prefixed_name, attributes)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def <<(text)
|
53
|
+
xml.text(text)
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_text(element, text)
|
57
|
+
element << text
|
58
|
+
end
|
59
|
+
|
60
|
+
# Add XML namespace to document
|
61
|
+
#
|
62
|
+
# Ox doesn't support XML namespaces so this method does nothing.
|
63
|
+
def add_namespace_prefix(_prefix)
|
64
|
+
# :noop:
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def parent
|
69
|
+
xml
|
70
|
+
end
|
71
|
+
|
72
|
+
def method_missing(method_name, *args)
|
73
|
+
if block_given?
|
74
|
+
xml.public_send(method_name, *args) do
|
75
|
+
yield(xml)
|
76
|
+
end
|
77
|
+
else
|
78
|
+
xml.public_send(method_name, *args)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def respond_to_missing?(method_name, include_private = false)
|
83
|
+
xml.respond_to?(method_name) || super
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "nokogiri"
|
2
2
|
require_relative "xml_document"
|
3
|
+
require_relative "builder/nokogiri"
|
3
4
|
|
4
5
|
module Lutaml
|
5
6
|
module Model
|
@@ -12,12 +13,13 @@ module Lutaml
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def to_xml(options = {})
|
15
|
-
builder = Nokogiri
|
16
|
+
builder = Builder::Nokogiri.build(encoding: "UTF-8") do |xml|
|
16
17
|
if root.is_a?(Lutaml::Model::XmlAdapter::NokogiriElement)
|
17
18
|
root.to_xml(xml)
|
18
19
|
else
|
19
20
|
mapper_class = options[:mapper_class] || @root.class
|
20
|
-
options[:xml_attributes] =
|
21
|
+
options[:xml_attributes] =
|
22
|
+
build_namespace_attributes(mapper_class)
|
21
23
|
build_element(xml, @root, options)
|
22
24
|
end
|
23
25
|
end
|
@@ -31,59 +33,6 @@ module Lutaml
|
|
31
33
|
|
32
34
|
private
|
33
35
|
|
34
|
-
def build_unordered_element(xml, element, options = {})
|
35
|
-
mapper_class = options[:mapper_class] || element.class
|
36
|
-
xml_mapping = mapper_class.mappings_for(:xml)
|
37
|
-
return xml unless xml_mapping
|
38
|
-
|
39
|
-
attributes = options[:xml_attributes] ||= {}
|
40
|
-
attributes = build_attributes(element,
|
41
|
-
xml_mapping).merge(attributes)&.compact
|
42
|
-
|
43
|
-
prefixed_xml = if options.key?(:namespace_prefix)
|
44
|
-
options[:namespace_prefix] ? xml[options[:namespace_prefix]] : xml
|
45
|
-
elsif xml_mapping.namespace_prefix
|
46
|
-
xml[xml_mapping.namespace_prefix]
|
47
|
-
else
|
48
|
-
xml
|
49
|
-
end
|
50
|
-
|
51
|
-
tag_name = options[:tag_name] || xml_mapping.root_element
|
52
|
-
prefixed_xml.public_send(tag_name, attributes) do
|
53
|
-
if options.key?(:namespace_prefix) && !options[:namespace_prefix]
|
54
|
-
xml.parent.namespace = nil
|
55
|
-
end
|
56
|
-
|
57
|
-
xml_mapping.elements.each do |element_rule|
|
58
|
-
attribute_def = attribute_definition_for(element, element_rule, mapper_class: mapper_class)
|
59
|
-
value = attribute_value_for(element, element_rule)
|
60
|
-
|
61
|
-
next if value.nil? && !element_rule.render_nil?
|
62
|
-
|
63
|
-
nsp_xml = element_rule.prefix ? xml[element_rule.prefix] : xml
|
64
|
-
|
65
|
-
if attribute_def.collection?
|
66
|
-
value.each do |v|
|
67
|
-
add_to_xml(nsp_xml, v, attribute_def, element_rule)
|
68
|
-
end
|
69
|
-
elsif !value.nil? || element_rule.render_nil?
|
70
|
-
add_to_xml(nsp_xml, value, attribute_def, element_rule)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
if (content_rule = xml_mapping.content_mapping)
|
75
|
-
text = element.send(content_rule.to)
|
76
|
-
text = text.join if text.is_a?(Array)
|
77
|
-
|
78
|
-
if content_rule.custom_methods[:to]
|
79
|
-
text = @root.send(content_rule.custom_methods[:to], @root, text)
|
80
|
-
end
|
81
|
-
|
82
|
-
prefixed_xml.text text
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
36
|
def build_ordered_element(xml, element, options = {})
|
88
37
|
mapper_class = options[:mapper_class] || element.class
|
89
38
|
xml_mapping = mapper_class.mappings_for(:xml)
|
@@ -114,49 +63,27 @@ module Lutaml
|
|
114
63
|
element_rule = xml_mapping.find_by_name(name)
|
115
64
|
next if element_rule.nil?
|
116
65
|
|
117
|
-
attribute_def = attribute_definition_for(element, element_rule,
|
66
|
+
attribute_def = attribute_definition_for(element, element_rule,
|
67
|
+
mapper_class: mapper_class)
|
118
68
|
value = attribute_value_for(element, element_rule)
|
119
|
-
nsp_xml = element_rule.prefix ? xml[element_rule.prefix] : xml
|
120
69
|
|
121
70
|
if element_rule == xml_mapping.content_mapping
|
122
71
|
text = element.send(xml_mapping.content_mapping.to)
|
123
72
|
text = text[curr_index] if text.is_a?(Array)
|
124
73
|
|
125
74
|
prefixed_xml.text text
|
126
|
-
elsif attribute_def.collection?
|
127
|
-
add_to_xml(nsp_xml, value[curr_index], attribute_def,
|
128
|
-
element_rule)
|
129
75
|
elsif !value.nil? || element_rule.render_nil?
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
if value && (attribute&.type&.<= Lutaml::Model::Serialize)
|
142
|
-
handle_nested_elements(
|
143
|
-
xml,
|
144
|
-
value,
|
145
|
-
rule: rule,
|
146
|
-
attribute: attribute,
|
147
|
-
)
|
148
|
-
else
|
149
|
-
xml.public_send(rule.name) do
|
150
|
-
if !value.nil?
|
151
|
-
serialized_value = attribute.type.serialize(value)
|
152
|
-
|
153
|
-
if attribute.type == Lutaml::Model::Type::Hash
|
154
|
-
serialized_value.each do |key, val|
|
155
|
-
xml.public_send(key) { xml.text val }
|
156
|
-
end
|
157
|
-
else
|
158
|
-
xml.text(serialized_value)
|
159
|
-
end
|
76
|
+
value = value[curr_index] if attribute_def.collection?
|
77
|
+
|
78
|
+
add_to_xml(
|
79
|
+
xml,
|
80
|
+
element_rule.prefix,
|
81
|
+
value,
|
82
|
+
options.merge(
|
83
|
+
attribute: attribute_def,
|
84
|
+
rule: element_rule,
|
85
|
+
),
|
86
|
+
)
|
160
87
|
end
|
161
88
|
end
|
162
89
|
end
|
@@ -205,7 +132,7 @@ module Lutaml
|
|
205
132
|
end
|
206
133
|
|
207
134
|
def to_xml(builder = nil)
|
208
|
-
builder ||= Nokogiri
|
135
|
+
builder ||= Builder::Nokogiri.build
|
209
136
|
|
210
137
|
if name == "text"
|
211
138
|
builder.text(text)
|
@@ -232,7 +159,7 @@ module Lutaml
|
|
232
159
|
end
|
233
160
|
end
|
234
161
|
|
235
|
-
def build_attributes(node)
|
162
|
+
def build_attributes(node, _options = {})
|
236
163
|
attrs = node.attributes.transform_values(&:value)
|
237
164
|
|
238
165
|
attrs.merge(build_namespace_attributes(node))
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "ox"
|
2
2
|
require_relative "xml_document"
|
3
|
+
require_relative "builder/ox"
|
3
4
|
|
4
5
|
module Lutaml
|
5
6
|
module Model
|
@@ -12,7 +13,7 @@ module Lutaml
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def to_xml(options = {})
|
15
|
-
builder = Ox
|
16
|
+
builder = Builder::Ox.build
|
16
17
|
|
17
18
|
if @root.is_a?(Lutaml::Model::XmlAdapter::OxElement)
|
18
19
|
@root.to_xml(builder)
|
@@ -22,66 +23,12 @@ module Lutaml
|
|
22
23
|
build_element(builder, @root, options)
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
xml_data = builder.to_s
|
26
|
+
xml_data = builder.xml.to_s
|
27
27
|
options[:declaration] ? declaration(options) + xml_data : xml_data
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
-
def build_unordered_element(builder, element, options = {})
|
33
|
-
mapper_class = options[:mapper_class] || element.class
|
34
|
-
xml_mapping = mapper_class.mappings_for(:xml)
|
35
|
-
return xml unless xml_mapping
|
36
|
-
|
37
|
-
attributes = build_attributes(element, xml_mapping).compact
|
38
|
-
|
39
|
-
tag_name = options[:tag_name] || xml_mapping.root_element
|
40
|
-
prefixed_name = if options.key?(:namespace_prefix)
|
41
|
-
[options[:namespace_prefix], tag_name].compact.join(":")
|
42
|
-
elsif xml_mapping.namespace_prefix
|
43
|
-
"#{xml_mapping.namespace_prefix}:#{tag_name}"
|
44
|
-
else
|
45
|
-
tag_name
|
46
|
-
end
|
47
|
-
|
48
|
-
builder.element(prefixed_name, attributes) do |el|
|
49
|
-
xml_mapping.elements.each do |element_rule|
|
50
|
-
attribute_def = attribute_definition_for(element, element_rule, mapper_class: mapper_class)
|
51
|
-
value = attribute_value_for(element, element_rule)
|
52
|
-
|
53
|
-
val = if attribute_def.collection?
|
54
|
-
value
|
55
|
-
elsif value || element_rule.render_nil?
|
56
|
-
[value]
|
57
|
-
else
|
58
|
-
[]
|
59
|
-
end
|
60
|
-
|
61
|
-
val.each do |v|
|
62
|
-
if attribute_def&.type&.<= Lutaml::Model::Serialize
|
63
|
-
handle_nested_elements(el, v, rule: element_rule, attribute: attribute_def)
|
64
|
-
else
|
65
|
-
builder.element(element_rule.prefixed_name) do |el|
|
66
|
-
el.text(attribute_def.type.serialize(v)) if v
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
if (content_rule = xml_mapping.content_mapping)
|
73
|
-
text = element.send(xml_mapping.content_mapping.to)
|
74
|
-
text = text.join if text.is_a?(Array)
|
75
|
-
|
76
|
-
if content_rule.custom_methods[:to]
|
77
|
-
text = @root.send(content_rule.custom_methods[:to], @root, text)
|
78
|
-
end
|
79
|
-
|
80
|
-
el.text text
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
32
|
def build_ordered_element(builder, element, options = {})
|
86
33
|
mapper_class = options[:mapper_class] || element.class
|
87
34
|
xml_mapping = mapper_class.mappings_for(:xml)
|
@@ -90,7 +37,8 @@ module Lutaml
|
|
90
37
|
attributes = build_attributes(element, xml_mapping).compact
|
91
38
|
|
92
39
|
tag_name = options[:tag_name] || xml_mapping.root_element
|
93
|
-
builder.
|
40
|
+
builder.create_and_add_element(tag_name,
|
41
|
+
attributes: attributes) do |el|
|
94
42
|
index_hash = {}
|
95
43
|
|
96
44
|
element.element_order.each do |name|
|
@@ -99,47 +47,27 @@ module Lutaml
|
|
99
47
|
|
100
48
|
element_rule = xml_mapping.find_by_name(name)
|
101
49
|
|
102
|
-
attribute_def = attribute_definition_for(element, element_rule,
|
50
|
+
attribute_def = attribute_definition_for(element, element_rule,
|
51
|
+
mapper_class: mapper_class)
|
103
52
|
value = attribute_value_for(element, element_rule)
|
104
53
|
|
105
54
|
if element_rule == xml_mapping.content_mapping
|
106
55
|
text = element.send(xml_mapping.content_mapping.to)
|
107
56
|
text = text[curr_index] if text.is_a?(Array)
|
108
57
|
|
109
|
-
el.
|
110
|
-
elsif attribute_def.collection?
|
111
|
-
add_to_xml(el, value[curr_index], attribute_def, element_rule)
|
58
|
+
el.add_text(el, text)
|
112
59
|
elsif !value.nil? || element_rule.render_nil?
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
if value && (attribute&.type&.<= Lutaml::Model::Serialize)
|
125
|
-
handle_nested_elements(
|
126
|
-
xml,
|
127
|
-
value,
|
128
|
-
rule: rule,
|
129
|
-
attribute: attribute,
|
130
|
-
)
|
131
|
-
else
|
132
|
-
xml.element(rule.name) do |el|
|
133
|
-
if !value.nil?
|
134
|
-
serialized_value = attribute.type.serialize(value)
|
135
|
-
|
136
|
-
if attribute.type == Lutaml::Model::Type::Hash
|
137
|
-
serialized_value.each do |key, val|
|
138
|
-
el.element(key) { |child_el| child_el.text val }
|
139
|
-
end
|
140
|
-
else
|
141
|
-
el.text(serialized_value)
|
142
|
-
end
|
60
|
+
value = value[curr_index] if attribute_def.collection?
|
61
|
+
|
62
|
+
add_to_xml(
|
63
|
+
el,
|
64
|
+
nil,
|
65
|
+
value,
|
66
|
+
options.merge(
|
67
|
+
attribute: attribute_def,
|
68
|
+
rule: element_rule,
|
69
|
+
),
|
70
|
+
)
|
143
71
|
end
|
144
72
|
end
|
145
73
|
end
|
@@ -188,13 +116,13 @@ module Lutaml
|
|
188
116
|
end
|
189
117
|
|
190
118
|
def to_xml(builder = nil)
|
191
|
-
builder ||= Ox
|
119
|
+
builder ||= Builder::Ox.build
|
192
120
|
attrs = build_attributes(self)
|
193
121
|
|
194
122
|
if text?
|
195
|
-
builder.
|
123
|
+
builder.add_text(builder, text)
|
196
124
|
else
|
197
|
-
builder.
|
125
|
+
builder.create_and_add_element(name, attributes: attrs) do |el|
|
198
126
|
children.each { |child| child.to_xml(el) }
|
199
127
|
end
|
200
128
|
end
|
@@ -42,21 +42,24 @@ module Lutaml
|
|
42
42
|
@root.order
|
43
43
|
end
|
44
44
|
|
45
|
-
def handle_nested_elements(builder, value,
|
46
|
-
|
45
|
+
def handle_nested_elements(builder, value, options = {})
|
46
|
+
element_options = build_options_for_nested_elements(options)
|
47
47
|
|
48
48
|
case value
|
49
49
|
when Array
|
50
|
-
value.each { |val| build_element(builder, val,
|
50
|
+
value.each { |val| build_element(builder, val, element_options) }
|
51
51
|
else
|
52
|
-
build_element(builder, value,
|
52
|
+
build_element(builder, value, element_options)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
def build_options_for_nested_elements(
|
56
|
+
def build_options_for_nested_elements(options = {})
|
57
|
+
attribute = options.delete(:attribute)
|
58
|
+
rule = options.delete(:rule)
|
59
|
+
|
57
60
|
return {} unless rule
|
58
61
|
|
59
|
-
options = {}
|
62
|
+
# options = {}
|
60
63
|
|
61
64
|
options[:namespace_prefix] = rule.prefix if rule&.namespace_set?
|
62
65
|
options[:mixed_content] = rule.mixed_content
|
@@ -97,6 +100,103 @@ module Lutaml
|
|
97
100
|
end
|
98
101
|
end
|
99
102
|
|
103
|
+
def add_to_xml(xml, prefix, value, options = {})
|
104
|
+
if value.is_a?(Array)
|
105
|
+
value.each do |item|
|
106
|
+
add_to_xml(xml, prefix, item, options)
|
107
|
+
end
|
108
|
+
|
109
|
+
return
|
110
|
+
end
|
111
|
+
|
112
|
+
attribute = options[:attribute]
|
113
|
+
rule = options[:rule]
|
114
|
+
|
115
|
+
if rule.custom_methods[:to]
|
116
|
+
@root.send(rule.custom_methods[:to], @root, xml.parent, xml)
|
117
|
+
return
|
118
|
+
end
|
119
|
+
|
120
|
+
if value && (attribute&.type&.<= Lutaml::Model::Serialize)
|
121
|
+
handle_nested_elements(
|
122
|
+
xml,
|
123
|
+
value,
|
124
|
+
options.merge({ rule: rule, attribute: attribute }),
|
125
|
+
)
|
126
|
+
else
|
127
|
+
xml.create_and_add_element(rule.name, prefix: prefix) do
|
128
|
+
if !value.nil?
|
129
|
+
serialized_value = attribute.type.serialize(value)
|
130
|
+
|
131
|
+
if attribute.type == Lutaml::Model::Type::Hash
|
132
|
+
serialized_value.each do |key, val|
|
133
|
+
xml.create_and_add_element(key) do |element|
|
134
|
+
element.text(val)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
else
|
138
|
+
xml.add_text(xml, serialized_value)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def build_unordered_element(xml, element, options = {})
|
146
|
+
mapper_class = options[:mapper_class] || element.class
|
147
|
+
xml_mapping = mapper_class.mappings_for(:xml)
|
148
|
+
return xml unless xml_mapping
|
149
|
+
|
150
|
+
attributes = options[:xml_attributes] ||= {}
|
151
|
+
attributes = build_attributes(element,
|
152
|
+
xml_mapping, options).merge(attributes)&.compact
|
153
|
+
|
154
|
+
prefix = if options.key?(:namespace_prefix)
|
155
|
+
options[:namespace_prefix]
|
156
|
+
elsif xml_mapping.namespace_prefix
|
157
|
+
xml_mapping.namespace_prefix
|
158
|
+
end
|
159
|
+
|
160
|
+
prefixed_xml = xml.add_namespace_prefix(prefix)
|
161
|
+
tag_name = options[:tag_name] || xml_mapping.root_element
|
162
|
+
|
163
|
+
xml.create_and_add_element(tag_name, prefix: prefix,
|
164
|
+
attributes: attributes) do
|
165
|
+
if options.key?(:namespace_prefix) && !options[:namespace_prefix]
|
166
|
+
xml.add_namespace_prefix(nil)
|
167
|
+
end
|
168
|
+
|
169
|
+
xml_mapping.elements.each do |element_rule|
|
170
|
+
attribute_def = attribute_definition_for(element, element_rule,
|
171
|
+
mapper_class: mapper_class)
|
172
|
+
|
173
|
+
value = attribute_value_for(element, element_rule)
|
174
|
+
|
175
|
+
next if value.nil? && !element_rule.render_nil?
|
176
|
+
|
177
|
+
value = [value] if attribute_def.collection? && !value.is_a?(Array)
|
178
|
+
|
179
|
+
add_to_xml(
|
180
|
+
xml,
|
181
|
+
element_rule.prefix,
|
182
|
+
value,
|
183
|
+
options.merge({ attribute: attribute_def, rule: element_rule }),
|
184
|
+
)
|
185
|
+
end
|
186
|
+
|
187
|
+
if (content_rule = xml_mapping.content_mapping)
|
188
|
+
if content_rule.custom_methods[:to]
|
189
|
+
@root.send(content_rule.custom_methods[:to], element,
|
190
|
+
prefixed_xml.parent, prefixed_xml)
|
191
|
+
else
|
192
|
+
text = element.send(content_rule.to)
|
193
|
+
text = text.join if text.is_a?(Array)
|
194
|
+
prefixed_xml.add_text(xml, text)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
100
200
|
def ordered?(element, options = {})
|
101
201
|
return false unless element.respond_to?(:element_order)
|
102
202
|
return element.ordered? if element.respond_to?(:ordered?)
|
@@ -142,10 +242,12 @@ module Lutaml
|
|
142
242
|
attrs
|
143
243
|
end
|
144
244
|
|
145
|
-
def build_attributes(element, xml_mapping)
|
245
|
+
def build_attributes(element, xml_mapping, options = {})
|
146
246
|
attrs = namespace_attributes(xml_mapping)
|
147
247
|
|
148
248
|
xml_mapping.attributes.each_with_object(attrs) do |mapping_rule, hash|
|
249
|
+
next if options[:except]&.include?(mapping_rule.to)
|
250
|
+
|
149
251
|
if mapping_rule.namespace
|
150
252
|
hash["xmlns:#{mapping_rule.prefix}"] = mapping_rule.namespace
|
151
253
|
end
|
@@ -154,6 +256,8 @@ module Lutaml
|
|
154
256
|
end
|
155
257
|
|
156
258
|
xml_mapping.elements.each_with_object(attrs) do |mapping_rule, hash|
|
259
|
+
next if options[:except]&.include?(mapping_rule.to)
|
260
|
+
|
157
261
|
if mapping_rule.namespace
|
158
262
|
hash["xmlns:#{mapping_rule.prefix}"] = mapping_rule.namespace
|
159
263
|
end
|
@@ -16,18 +16,6 @@ module Lutaml
|
|
16
16
|
def to_yaml(options = {})
|
17
17
|
YAML.dump(@attributes, options)
|
18
18
|
end
|
19
|
-
|
20
|
-
# TODO: Is this really needed?
|
21
|
-
def self.to_yaml(attributes, *args)
|
22
|
-
new(attributes).to_yaml(*args)
|
23
|
-
end
|
24
|
-
|
25
|
-
# TODO: Is this really needed?
|
26
|
-
def self.from_yaml(yaml, klass)
|
27
|
-
data = parse(yaml)
|
28
|
-
mapped_attrs = klass.send(:apply_mappings, data, :yaml)
|
29
|
-
klass.new(mapped_attrs)
|
30
|
-
end
|
31
19
|
end
|
32
20
|
end
|
33
21
|
end
|
data/lib/lutaml/model.rb
CHANGED