lutaml-model 0.8.9 → 0.8.11
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/.github/workflows/dependent-repos.json +1 -0
- data/.rubocop_todo.yml +52 -22
- data/README.adoc +43 -0
- data/docs/_guides/jsonld-serialization.adoc +3 -1
- data/docs/_guides/rdf-serialization.adoc +94 -8
- data/docs/_guides/turtle-serialization.adoc +17 -4
- data/lib/lutaml/jsonld/transform.rb +70 -24
- data/lib/lutaml/key_value/transform.rb +5 -5
- data/lib/lutaml/key_value/transformation/collection_serializer.rb +25 -11
- data/lib/lutaml/key_value/transformation/value_serializer.rb +7 -7
- data/lib/lutaml/key_value/transformation.rb +27 -17
- data/lib/lutaml/model/adapter_resolver.rb +4 -6
- data/lib/lutaml/model/attribute.rb +26 -23
- data/lib/lutaml/model/cached_type_resolver.rb +10 -9
- data/lib/lutaml/model/cli.rb +1 -1
- data/lib/lutaml/model/collection.rb +4 -4
- data/lib/lutaml/model/comparable_model.rb +11 -11
- data/lib/lutaml/model/config.rb +1 -1
- data/lib/lutaml/model/consolidation/dispatcher.rb +1 -1
- data/lib/lutaml/model/consolidation/pattern_chunker.rb +3 -3
- data/lib/lutaml/model/format_registry.rb +6 -4
- data/lib/lutaml/model/global_context.rb +2 -2
- data/lib/lutaml/model/global_register.rb +1 -1
- data/lib/lutaml/model/instrumentation.rb +1 -1
- data/lib/lutaml/model/mapping/mapping_rule.rb +3 -3
- data/lib/lutaml/model/mapping/model_mapping.rb +1 -1
- data/lib/lutaml/model/mapping/model_mapping_rule.rb +1 -1
- data/lib/lutaml/model/register.rb +3 -3
- data/lib/lutaml/model/render_policy.rb +11 -17
- data/lib/lutaml/model/runtime_compatibility.rb +0 -1
- data/lib/lutaml/model/schema/xml_compiler/group.rb +1 -1
- data/lib/lutaml/model/schema/xml_compiler/registry_generator.rb +1 -1
- data/lib/lutaml/model/schema/xml_compiler/sequence.rb +0 -2
- data/lib/lutaml/model/schema/xml_compiler.rb +14 -14
- data/lib/lutaml/model/serialize/attribute_definition.rb +1 -1
- data/lib/lutaml/model/serialize/deserialization_context.rb +50 -0
- data/lib/lutaml/model/serialize/format_conversion.rb +2 -2
- data/lib/lutaml/model/serialize/initialization.rb +44 -7
- data/lib/lutaml/model/serialize/model_import.rb +1 -1
- data/lib/lutaml/model/serialize.rb +8 -1
- data/lib/lutaml/model/services/rule_value_extractor.rb +2 -1
- data/lib/lutaml/model/store.rb +77 -24
- data/lib/lutaml/model/transformation_registry.rb +1 -1
- data/lib/lutaml/model/type_context.rb +7 -1
- data/lib/lutaml/model/type_resolver.rb +1 -6
- data/lib/lutaml/model/utils.rb +19 -6
- data/lib/lutaml/model/validation_framework.rb +1 -1
- data/lib/lutaml/model/value_transformer.rb +2 -2
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/rdf/mapping.rb +19 -13
- data/lib/lutaml/rdf/mapping_rule.rb +19 -2
- data/lib/lutaml/rdf/member_rule.rb +19 -2
- data/lib/lutaml/rdf/transform.rb +20 -11
- data/lib/lutaml/turtle/transform.rb +125 -53
- data/lib/lutaml/xml/adapter/adapter_helpers.rb +1 -1
- data/lib/lutaml/xml/adapter/base_adapter.rb +10 -14
- data/lib/lutaml/xml/adapter/namespace_uri_collector.rb +3 -3
- data/lib/lutaml/xml/adapter/plan_based_builder.rb +14 -14
- data/lib/lutaml/xml/adapter/xml_serializer.rb +3 -3
- data/lib/lutaml/xml/configurable.rb +2 -1
- data/lib/lutaml/xml/data_model.rb +2 -2
- data/lib/lutaml/xml/decisions/decision_context.rb +3 -3
- data/lib/lutaml/xml/decisions/rules/element_form_default_unqualified_rule.rb +1 -1
- data/lib/lutaml/xml/decisions/rules/element_form_option_rule.rb +1 -1
- data/lib/lutaml/xml/decisions/rules/used_prefix_rule.rb +1 -1
- data/lib/lutaml/xml/declaration_plan.rb +2 -2
- data/lib/lutaml/xml/declaration_planner.rb +12 -13
- data/lib/lutaml/xml/document.rb +13 -13
- data/lib/lutaml/xml/format_chooser.rb +3 -3
- data/lib/lutaml/xml/hoisting_algorithm.rb +1 -1
- data/lib/lutaml/xml/mapping.rb +2 -2
- data/lib/lutaml/xml/mapping_rule.rb +16 -3
- data/lib/lutaml/xml/model_transform.rb +17 -19
- data/lib/lutaml/xml/namespace_collector.rb +10 -10
- data/lib/lutaml/xml/namespace_declaration.rb +2 -2
- data/lib/lutaml/xml/namespace_declaration_data.rb +5 -8
- data/lib/lutaml/xml/namespace_scope_config.rb +3 -2
- data/lib/lutaml/xml/namespace_type_resolver.rb +4 -4
- data/lib/lutaml/xml/nokogiri/element.rb +2 -2
- data/lib/lutaml/xml/polymorphic_value_handler.rb +1 -1
- data/lib/lutaml/xml/schema/xsd/base.rb +7 -7
- data/lib/lutaml/xml/schema/xsd/choice.rb +2 -2
- data/lib/lutaml/xml/schema/xsd/complex_type.rb +5 -5
- data/lib/lutaml/xml/schema/xsd/errors/message_builder.rb +3 -3
- data/lib/lutaml/xml/schema/xsd/group.rb +2 -2
- data/lib/lutaml/xml/schema/xsd/sequence.rb +2 -2
- data/lib/lutaml/xml/schema/xsd_schema.rb +5 -5
- data/lib/lutaml/xml/serialization/format_conversion.rb +4 -3
- data/lib/lutaml/xml/transformation/element_builder.rb +4 -2
- data/lib/lutaml/xml/transformation/rule_applier.rb +2 -2
- data/lib/lutaml/xml/transformation/value_serializer.rb +4 -6
- data/lib/lutaml/xml/transformation.rb +4 -4
- data/lib/lutaml/xml/type/configurable.rb +0 -4
- data/lib/lutaml/xml/xml_element.rb +21 -13
- data/lutaml-model.gemspec +1 -1
- data/spec/lutaml/jsonld/transform_spec.rb +239 -0
- data/spec/lutaml/model/cached_type_resolver_spec.rb +3 -3
- data/spec/lutaml/model/optimization_spec.rb +228 -0
- data/spec/lutaml/model/store_spec.rb +195 -0
- data/spec/lutaml/rdf/mapping_rule_spec.rb +97 -0
- data/spec/lutaml/rdf/mapping_spec.rb +74 -4
- data/spec/lutaml/rdf/member_rule_spec.rb +41 -0
- data/spec/lutaml/rdf/rdf_transform_spec.rb +95 -29
- data/spec/lutaml/turtle/mapping_spec.rb +2 -2
- data/spec/lutaml/turtle/transform_spec.rb +315 -0
- data/spec/lutaml/xml/data_model_spec.rb +10 -28
- metadata +7 -4
|
@@ -46,56 +46,101 @@ module Lutaml
|
|
|
46
46
|
def build_graph(mapping, instance)
|
|
47
47
|
graph = RDF::Graph.new
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
49
|
+
has_resource_data =
|
|
50
|
+
mapping.rdf_type.any? ||
|
|
51
|
+
mapping.rdf_predicates.any? ||
|
|
52
|
+
mapping.rdf_members.any?(&:linked?)
|
|
53
|
+
|
|
54
|
+
if has_resource_data
|
|
55
|
+
subject_uri = resolve_subject(mapping, instance)
|
|
56
|
+
build_resource_triples(graph, mapping, instance, subject_uri)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
build_member_subgraphs(graph, mapping, instance)
|
|
60
|
+
|
|
61
|
+
graph
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def resolve_subject(mapping, instance)
|
|
65
|
+
if mapping.rdf_subject
|
|
66
|
+
RDF::URI(resolve_subject_uri(mapping, instance))
|
|
67
|
+
else
|
|
68
|
+
RDF::Node.new
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def build_resource_triples(graph, mapping, instance, subject_uri)
|
|
73
|
+
mapping.rdf_type.each do |type_value|
|
|
74
|
+
type_uri = RDF::URI(resolve_single_type_uri(mapping, type_value))
|
|
75
|
+
graph << RDF::Statement.new(subject_uri, RDF.type, type_uri)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
mapping.rdf_predicates.each do |rule|
|
|
79
|
+
value = instance.public_send(rule.to)
|
|
80
|
+
next if value.nil?
|
|
81
|
+
|
|
82
|
+
Array(value).each do |v|
|
|
83
|
+
object = build_rdf_object(v, rule, mapping.namespace_set)
|
|
84
|
+
graph << RDF::Statement.new(subject_uri, RDF::URI(rule.uri), object)
|
|
61
85
|
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
mapping.rdf_members.each do |member_rule|
|
|
89
|
+
next unless member_rule.linked?
|
|
62
90
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
next
|
|
91
|
+
each_member(instance, member_rule) do |member|
|
|
92
|
+
member_mapping = member_mapping_for(member, :turtle)
|
|
93
|
+
next unless member_mapping
|
|
66
94
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
95
|
+
member_subject = RDF::URI(resolve_subject_uri(member_mapping,
|
|
96
|
+
member))
|
|
97
|
+
graph << RDF::Statement.new(
|
|
98
|
+
subject_uri,
|
|
99
|
+
RDF::URI(member_rule.linked_predicate_uri),
|
|
100
|
+
member_subject,
|
|
101
|
+
)
|
|
72
102
|
end
|
|
73
103
|
end
|
|
104
|
+
end
|
|
74
105
|
|
|
106
|
+
def build_member_subgraphs(graph, mapping, instance)
|
|
75
107
|
mapping.rdf_members.each do |member_rule|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
member_mapping = member.class.mappings[:turtle]
|
|
108
|
+
each_member(instance, member_rule) do |member|
|
|
109
|
+
member_mapping = member_mapping_for(member, :turtle)
|
|
79
110
|
next unless member_mapping
|
|
80
111
|
|
|
81
112
|
graph << build_graph(member_mapping, member)
|
|
82
113
|
end
|
|
83
114
|
end
|
|
84
|
-
|
|
85
|
-
graph
|
|
86
115
|
end
|
|
87
116
|
|
|
88
|
-
def build_rdf_object(value, rule)
|
|
89
|
-
|
|
117
|
+
def build_rdf_object(value, rule, namespace_set)
|
|
118
|
+
case rule.kind
|
|
119
|
+
when :uri_reference
|
|
120
|
+
build_uri_reference_object(value, namespace_set)
|
|
121
|
+
when :lang_tagged
|
|
90
122
|
lang = extract_language(value)
|
|
91
123
|
RDF::Literal.new(value.to_s, language: lang)
|
|
92
124
|
else
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
125
|
+
build_plain_literal(value)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def build_uri_reference_object(value, namespace_set)
|
|
130
|
+
resolved = if value.to_s.include?(":")
|
|
131
|
+
namespace_set.resolve_compact_iri(value.to_s)
|
|
132
|
+
else
|
|
133
|
+
value.to_s
|
|
134
|
+
end
|
|
135
|
+
RDF::URI.new(resolved)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def build_plain_literal(value)
|
|
139
|
+
case value
|
|
140
|
+
when Integer then RDF::Literal.new(value, datatype: RDF::XSD.integer)
|
|
141
|
+
when Float then RDF::Literal.new(value, datatype: RDF::XSD.double)
|
|
142
|
+
when TrueClass, FalseClass then RDF::Literal.new(value, datatype: RDF::XSD.boolean)
|
|
143
|
+
else RDF::Literal.new(value.to_s)
|
|
99
144
|
end
|
|
100
145
|
end
|
|
101
146
|
|
|
@@ -103,13 +148,12 @@ module Lutaml
|
|
|
103
148
|
ns_set = mapping.namespace_set
|
|
104
149
|
|
|
105
150
|
mapping.rdf_members.each do |member_rule|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
member_mapping = collection.first.class.mappings[:turtle]
|
|
110
|
-
next unless member_mapping
|
|
151
|
+
each_member(instance, member_rule) do |member|
|
|
152
|
+
member_mapping = member_mapping_for(member, :turtle)
|
|
153
|
+
next unless member_mapping
|
|
111
154
|
|
|
112
|
-
|
|
155
|
+
ns_set = ns_set.merge(member_mapping.namespace_set)
|
|
156
|
+
end
|
|
113
157
|
end
|
|
114
158
|
|
|
115
159
|
ns_set.each.with_object({}) do |ns, h|
|
|
@@ -119,38 +163,66 @@ module Lutaml
|
|
|
119
163
|
|
|
120
164
|
def extract_attributes(graph, mapping)
|
|
121
165
|
attrs = {}
|
|
122
|
-
|
|
166
|
+
type_uris = resolve_type_uris(mapping)
|
|
123
167
|
|
|
124
|
-
matching_subjects =
|
|
168
|
+
matching_subjects = find_subjects_by_types(graph, type_uris)
|
|
125
169
|
|
|
126
170
|
matching_subjects.each do |subject|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
next if stmts.empty?
|
|
130
|
-
|
|
131
|
-
values = stmts.map { |s| literal_to_ruby(s.object) }
|
|
132
|
-
attrs[rule.to] = values.length == 1 ? values.first : values
|
|
133
|
-
end
|
|
171
|
+
attrs["id"] = subject.to_s unless subject.node?
|
|
172
|
+
extract_predicate_attributes(graph, subject, mapping, attrs)
|
|
134
173
|
end
|
|
135
174
|
|
|
136
175
|
attrs
|
|
137
176
|
end
|
|
138
177
|
|
|
139
|
-
def
|
|
140
|
-
|
|
178
|
+
def extract_predicate_attributes(graph, subject, mapping, attrs)
|
|
179
|
+
mapping.rdf_predicates.each do |rule|
|
|
180
|
+
stmts = graph.query([subject, RDF::URI(rule.uri), nil])
|
|
181
|
+
next if stmts.empty?
|
|
182
|
+
|
|
183
|
+
values = stmts.map do |s|
|
|
184
|
+
literal_to_ruby(s.object, rule, mapping.namespace_set)
|
|
185
|
+
end
|
|
186
|
+
attrs[rule.to] = values.length == 1 ? values.first : values
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def find_subjects_by_types(graph, type_uris)
|
|
191
|
+
type_uris.flat_map do |type_uri|
|
|
192
|
+
graph.query([nil, RDF.type, RDF::URI(type_uri)]).map(&:subject).uniq
|
|
193
|
+
end.uniq
|
|
141
194
|
end
|
|
142
195
|
|
|
143
|
-
def literal_to_ruby(rdf_object)
|
|
196
|
+
def literal_to_ruby(rdf_object, rule, namespace_set)
|
|
144
197
|
case rdf_object
|
|
198
|
+
when RDF::URI
|
|
199
|
+
uri_to_ruby(rdf_object, rule, namespace_set)
|
|
145
200
|
when RDF::Literal
|
|
201
|
+
literal_value_to_ruby(rdf_object, rule)
|
|
202
|
+
else
|
|
203
|
+
rdf_object.to_s
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def uri_to_ruby(rdf_object, rule, namespace_set)
|
|
208
|
+
uri_str = rdf_object.to_s
|
|
209
|
+
if rule.kind == :uri_reference
|
|
210
|
+
namespace_set.compact(uri_str) || uri_str
|
|
211
|
+
else
|
|
212
|
+
uri_str
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def literal_value_to_ruby(rdf_object, rule)
|
|
217
|
+
if rule.kind == :lang_tagged && rdf_object.language
|
|
218
|
+
rdf_object.value
|
|
219
|
+
else
|
|
146
220
|
case rdf_object.datatype
|
|
147
221
|
when RDF::XSD.integer then rdf_object.value.to_i
|
|
148
222
|
when RDF::XSD.double, RDF::XSD.decimal, RDF::XSD.float then rdf_object.value.to_f
|
|
149
223
|
when RDF::XSD.boolean then rdf_object.value == "true"
|
|
150
224
|
else rdf_object.value
|
|
151
225
|
end
|
|
152
|
-
else
|
|
153
|
-
rdf_object.to_s
|
|
154
226
|
end
|
|
155
227
|
end
|
|
156
228
|
end
|
|
@@ -90,7 +90,7 @@ module Lutaml
|
|
|
90
90
|
# @param node [Moxml::Node] The XML node
|
|
91
91
|
# @return [String] The namespaced name (e.g., "uri:name" or "name")
|
|
92
92
|
def namespaced_name_of(node)
|
|
93
|
-
return name_of(node) unless node.
|
|
93
|
+
return name_of(node) unless node.is_a?(Lutaml::Xml::XmlElement)
|
|
94
94
|
|
|
95
95
|
[node&.namespace&.uri, node.name].compact.join(":")
|
|
96
96
|
end
|
|
@@ -126,7 +126,7 @@ module Lutaml
|
|
|
126
126
|
# @param options [Hash] serialization options
|
|
127
127
|
# @return [Boolean] true if element has ordered content
|
|
128
128
|
def ordered?(element, options = {})
|
|
129
|
-
return false unless element.
|
|
129
|
+
return false unless element.is_a?(Lutaml::Model::Serialize)
|
|
130
130
|
|
|
131
131
|
mapper_class = options[:mapper_class]
|
|
132
132
|
xml_mapping = mapper_class&.mappings_for(:xml)
|
|
@@ -156,7 +156,7 @@ module Lutaml
|
|
|
156
156
|
klass = mapper_class || element.class
|
|
157
157
|
return klass.attributes[rule.to] unless rule.delegate
|
|
158
158
|
|
|
159
|
-
delegated_obj = element.
|
|
159
|
+
delegated_obj = element.public_send(rule.delegate)
|
|
160
160
|
return nil if delegated_obj.nil?
|
|
161
161
|
|
|
162
162
|
delegated_obj.class.attributes[rule.to]
|
|
@@ -168,12 +168,12 @@ module Lutaml
|
|
|
168
168
|
# @param rule [MappingRule] the mapping rule
|
|
169
169
|
# @return [Object, nil] the attribute value or nil if delegate is nil
|
|
170
170
|
def attribute_value_for(element, rule)
|
|
171
|
-
return element.
|
|
171
|
+
return element.public_send(rule.to) unless rule.delegate
|
|
172
172
|
|
|
173
|
-
delegate_obj = element.
|
|
173
|
+
delegate_obj = element.public_send(rule.delegate)
|
|
174
174
|
return nil if delegate_obj.nil?
|
|
175
175
|
|
|
176
|
-
delegate_obj.
|
|
176
|
+
delegate_obj.public_send(rule.to)
|
|
177
177
|
end
|
|
178
178
|
|
|
179
179
|
# Process content mapping for an element
|
|
@@ -186,7 +186,7 @@ module Lutaml
|
|
|
186
186
|
return unless content_rule
|
|
187
187
|
|
|
188
188
|
if content_rule.custom_methods[:to]
|
|
189
|
-
mapper_class.new.
|
|
189
|
+
mapper_class.new.public_send(
|
|
190
190
|
content_rule.custom_methods[:to],
|
|
191
191
|
element,
|
|
192
192
|
xml.parent,
|
|
@@ -225,15 +225,11 @@ module Lutaml
|
|
|
225
225
|
private
|
|
226
226
|
|
|
227
227
|
def attribute_values(element, &)
|
|
228
|
-
|
|
229
|
-
element.attributes_each_value(&)
|
|
230
|
-
else
|
|
231
|
-
element.attributes.each_value(&)
|
|
232
|
-
end
|
|
228
|
+
element.attributes.each_value(&)
|
|
233
229
|
end
|
|
234
230
|
|
|
235
231
|
def schema_location_attribute?(attr)
|
|
236
|
-
attr_name = if attr.
|
|
232
|
+
attr_name = if attr.is_a?(Lutaml::Xml::XmlAttribute)
|
|
237
233
|
attr.unprefixed_name
|
|
238
234
|
else
|
|
239
235
|
attr.name
|
|
@@ -242,7 +238,7 @@ module Lutaml
|
|
|
242
238
|
end
|
|
243
239
|
|
|
244
240
|
def attribute_namespace_prefix(attr)
|
|
245
|
-
if attr.
|
|
241
|
+
if attr.is_a?(Lutaml::Xml::XmlAttribute)
|
|
246
242
|
attr.namespace_prefix
|
|
247
243
|
else
|
|
248
244
|
attr.namespace&.prefix
|
|
@@ -250,7 +246,7 @@ module Lutaml
|
|
|
250
246
|
end
|
|
251
247
|
|
|
252
248
|
def attribute_hash_name(attr)
|
|
253
|
-
if attr.
|
|
249
|
+
if attr.is_a?(Lutaml::Xml::XmlAttribute)
|
|
254
250
|
attr.namespaced_name
|
|
255
251
|
else
|
|
256
252
|
self.class.namespaced_attr_name(attr)
|
|
@@ -29,7 +29,7 @@ module Lutaml
|
|
|
29
29
|
|
|
30
30
|
visited.add(model.object_id)
|
|
31
31
|
|
|
32
|
-
if model.
|
|
32
|
+
if model.is_a?(::Lutaml::Model::Serialize) && model.class.attributes.key?(:original_namespace_uri) && model.original_namespace_uri
|
|
33
33
|
original_uri = model.original_namespace_uri
|
|
34
34
|
if original_uri && !original_uri.empty?
|
|
35
35
|
ns_class = model.class.mappings_for(:xml)&.namespace_class
|
|
@@ -47,12 +47,12 @@ module Lutaml
|
|
|
47
47
|
next unless attr_def
|
|
48
48
|
|
|
49
49
|
child_type = attr_def.type(Lutaml::Model::Config.default_register)
|
|
50
|
-
next unless child_type.
|
|
50
|
+
next unless child_type.is_a?(Class) && child_type < ::Lutaml::Model::Serializable
|
|
51
51
|
|
|
52
52
|
child_mapping = child_type.mappings_for(:xml)
|
|
53
53
|
next unless child_mapping
|
|
54
54
|
|
|
55
|
-
child_instance = model.public_send(elem_rule.to) if model.
|
|
55
|
+
child_instance = model.public_send(elem_rule.to) if model.class.attributes.key?(elem_rule.to)
|
|
56
56
|
|
|
57
57
|
if child_instance.is_a?(Array) || child_instance.is_a?(::Lutaml::Model::Collection)
|
|
58
58
|
instances = child_instance.is_a?(::Lutaml::Model::Collection) ? child_instance.collection : child_instance
|
|
@@ -158,8 +158,8 @@ module Lutaml
|
|
|
158
158
|
prefix: prefix) do |inner_xml|
|
|
159
159
|
# Call attribute custom methods now that element is created
|
|
160
160
|
attribute_custom_methods.each do |attribute_rule|
|
|
161
|
-
mapper_class.new.
|
|
162
|
-
|
|
161
|
+
mapper_class.new.public_send(attribute_rule.custom_methods[:to],
|
|
162
|
+
element, inner_xml.parent, inner_xml)
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
if ordered?(element, options.merge(mapper_class: mapper_class))
|
|
@@ -292,7 +292,7 @@ module Lutaml
|
|
|
292
292
|
end
|
|
293
293
|
|
|
294
294
|
# Check if element was created from nil value with render_nil option
|
|
295
|
-
if element.
|
|
295
|
+
if element.is_a?(Lutaml::Xml::DataModel::XmlElement) && element.xsi_nil
|
|
296
296
|
attributes["xsi:nil"] = true
|
|
297
297
|
end
|
|
298
298
|
|
|
@@ -301,7 +301,7 @@ module Lutaml
|
|
|
301
301
|
prefix: prefix) do |inner_xml|
|
|
302
302
|
# Handle raw content (map_all directive)
|
|
303
303
|
has_raw_content = false
|
|
304
|
-
if element.
|
|
304
|
+
if element.is_a?(Lutaml::Xml::DataModel::XmlElement)
|
|
305
305
|
raw_content = element.raw_content
|
|
306
306
|
if raw_content && !raw_content.to_s.empty?
|
|
307
307
|
inner_xml.add_xml_fragment(inner_xml, raw_content.to_s)
|
|
@@ -361,8 +361,8 @@ module Lutaml
|
|
|
361
361
|
|
|
362
362
|
# Handle custom methods
|
|
363
363
|
if element_rule.custom_methods[:to]
|
|
364
|
-
mapper_class.new.
|
|
365
|
-
|
|
364
|
+
mapper_class.new.public_send(element_rule.custom_methods[:to], element,
|
|
365
|
+
xml.parent, xml)
|
|
366
366
|
next
|
|
367
367
|
end
|
|
368
368
|
|
|
@@ -432,8 +432,8 @@ module Lutaml
|
|
|
432
432
|
|
|
433
433
|
# Handle custom methods
|
|
434
434
|
if element_rule.custom_methods[:to]
|
|
435
|
-
mapper_class.new.
|
|
436
|
-
|
|
435
|
+
mapper_class.new.public_send(element_rule.custom_methods[:to], element,
|
|
436
|
+
xml.parent, xml)
|
|
437
437
|
next
|
|
438
438
|
end
|
|
439
439
|
|
|
@@ -468,7 +468,7 @@ module Lutaml
|
|
|
468
468
|
attribute_def = mapper_class.attributes[element_rule.to]
|
|
469
469
|
next unless attribute_def
|
|
470
470
|
|
|
471
|
-
value = element.
|
|
471
|
+
value = element.public_send(element_rule.to)
|
|
472
472
|
next unless element_rule.render?(value, element)
|
|
473
473
|
|
|
474
474
|
# For type-only models, children plans may not be available
|
|
@@ -500,7 +500,7 @@ module Lutaml
|
|
|
500
500
|
attribute_def = mapper_class.attributes[element_rule.to]
|
|
501
501
|
next unless attribute_def
|
|
502
502
|
|
|
503
|
-
value = element.
|
|
503
|
+
value = element.public_send(element_rule.to)
|
|
504
504
|
next unless element_rule.render?(value, element)
|
|
505
505
|
|
|
506
506
|
child_plan = plan.child_plan(element_rule.to)
|
|
@@ -805,10 +805,10 @@ module Lutaml
|
|
|
805
805
|
value = nil
|
|
806
806
|
|
|
807
807
|
if element_rule.delegate
|
|
808
|
-
delegate_obj = element.
|
|
809
|
-
if delegate_obj.
|
|
808
|
+
delegate_obj = element.public_send(element_rule.delegate)
|
|
809
|
+
if delegate_obj.is_a?(Lutaml::Model::Serialize) && delegate_obj.class.attributes.key?(element_rule.to)
|
|
810
810
|
attribute_def = delegate_obj.class.attributes[element_rule.to]
|
|
811
|
-
value = delegate_obj.
|
|
811
|
+
value = delegate_obj.public_send(element_rule.to)
|
|
812
812
|
end
|
|
813
813
|
else
|
|
814
814
|
attribute_def = attribute_definition_for(element, element_rule,
|
|
@@ -828,7 +828,7 @@ module Lutaml
|
|
|
828
828
|
# @param content [Array] accumulated content strings
|
|
829
829
|
def process_ordered_content(element, xml_mapping, xml, curr_index,
|
|
830
830
|
content)
|
|
831
|
-
text = element.
|
|
831
|
+
text = element.public_send(xml_mapping.content_mapping.to)
|
|
832
832
|
text = text[curr_index] if text.is_a?(Array)
|
|
833
833
|
|
|
834
834
|
if element.mixed?
|
|
@@ -83,7 +83,7 @@ module Lutaml
|
|
|
83
83
|
def build_xml_element_with_plan(builder, xml_element, plan,
|
|
84
84
|
options = {})
|
|
85
85
|
# Add processing instructions before the root element
|
|
86
|
-
if xml_element.
|
|
86
|
+
if xml_element.is_a?(Lutaml::Xml::DataModel::XmlElement)
|
|
87
87
|
xml_element.processing_instructions.each do |pi|
|
|
88
88
|
builder.add_processing_instruction(pi.target, pi.content)
|
|
89
89
|
end
|
|
@@ -230,7 +230,7 @@ module Lutaml
|
|
|
230
230
|
attributes[attr_node.qualified_name] = xml_attr.value.to_s
|
|
231
231
|
end
|
|
232
232
|
|
|
233
|
-
if xml_element.
|
|
233
|
+
if xml_element.is_a?(Lutaml::Xml::DataModel::XmlElement) && xml_element.xsi_nil
|
|
234
234
|
attributes["xsi:nil"] = "true"
|
|
235
235
|
end
|
|
236
236
|
|
|
@@ -240,7 +240,7 @@ module Lutaml
|
|
|
240
240
|
attributes["xmlns"] = "" if needs_xmlns_blank
|
|
241
241
|
|
|
242
242
|
xml.create_and_add_element(qualified_name, attributes: attributes) do
|
|
243
|
-
if xml_element.
|
|
243
|
+
if xml_element.is_a?(Lutaml::Xml::DataModel::XmlElement)
|
|
244
244
|
raw_content = xml_element.raw_content
|
|
245
245
|
if raw_content && !raw_content.to_s.empty?
|
|
246
246
|
xml.add_xml_fragment(xml, raw_content.to_s)
|
|
@@ -119,7 +119,8 @@ module Lutaml
|
|
|
119
119
|
# @return [void]
|
|
120
120
|
def inherit_mapping_from(mapping_class)
|
|
121
121
|
# Get the parent mapping instance that has DSL already evaluated
|
|
122
|
-
parent_mapping = if mapping_class.
|
|
122
|
+
parent_mapping = if mapping_class.is_a?(Class) &&
|
|
123
|
+
(mapping_class < Lutaml::Xml::Mapping || mapping_class.include?(Lutaml::Model::Serialize)) &&
|
|
123
124
|
mapping_class.xml_mapping_instance
|
|
124
125
|
mapping_class.xml_mapping_instance
|
|
125
126
|
else
|
|
@@ -133,7 +133,7 @@ module Lutaml
|
|
|
133
133
|
def qualified_name(prefix = nil)
|
|
134
134
|
if prefix
|
|
135
135
|
"#{prefix}:#{name}"
|
|
136
|
-
elsif namespace_class.
|
|
136
|
+
elsif namespace_class.is_a?(Class) && namespace_class < Lutaml::Xml::Namespace
|
|
137
137
|
ns_prefix = namespace_class.prefix_default
|
|
138
138
|
ns_prefix ? "#{ns_prefix}:#{name}" : name
|
|
139
139
|
else
|
|
@@ -202,7 +202,7 @@ module Lutaml
|
|
|
202
202
|
def qualified_name(prefix = nil)
|
|
203
203
|
if prefix
|
|
204
204
|
"#{prefix}:#{name}"
|
|
205
|
-
elsif namespace_class.
|
|
205
|
+
elsif namespace_class.is_a?(Class) && namespace_class < Lutaml::Xml::Namespace
|
|
206
206
|
ns_prefix = namespace_class.prefix_default
|
|
207
207
|
ns_prefix ? "#{ns_prefix}:#{name}" : name
|
|
208
208
|
else
|
|
@@ -129,7 +129,7 @@ module Lutaml
|
|
|
129
129
|
return nil unless @element
|
|
130
130
|
|
|
131
131
|
if @element.is_a?(Lutaml::Xml::XmlElement)
|
|
132
|
-
@element.namespace_prefix
|
|
132
|
+
@element.namespace_prefix
|
|
133
133
|
else
|
|
134
134
|
# For DataModel::XmlElement, check xml_namespace_prefix first
|
|
135
135
|
prefix = @element.xml_namespace_prefix
|
|
@@ -137,7 +137,7 @@ module Lutaml
|
|
|
137
137
|
|
|
138
138
|
# Fall back to original XmlElement wrapper if available
|
|
139
139
|
original = @element.original_xml_element
|
|
140
|
-
if original.
|
|
140
|
+
if original.is_a?(Lutaml::Xml::XmlElement)
|
|
141
141
|
return original.namespace_prefix
|
|
142
142
|
end
|
|
143
143
|
|
|
@@ -213,7 +213,7 @@ module Lutaml
|
|
|
213
213
|
|
|
214
214
|
# Returns all URIs for the current namespace (canonical + aliases).
|
|
215
215
|
def namespace_all_uris
|
|
216
|
-
if @namespace_class.
|
|
216
|
+
if @namespace_class.is_a?(Class) && @namespace_class < Lutaml::Xml::Namespace
|
|
217
217
|
@namespace_class.all_uris
|
|
218
218
|
else
|
|
219
219
|
[@namespace_uri]
|
|
@@ -51,7 +51,7 @@ module Lutaml
|
|
|
51
51
|
|
|
52
52
|
# Only apply if no explicit form option on the element
|
|
53
53
|
# ElementFormOptionRule (Priority -0.5) handles explicit form options
|
|
54
|
-
return false if context.element.
|
|
54
|
+
return false if context.element.is_a?(Lutaml::Xml::DataModel::XmlElement) && !context.element.form.nil?
|
|
55
55
|
|
|
56
56
|
true
|
|
57
57
|
end
|
|
@@ -30,7 +30,7 @@ module Lutaml
|
|
|
30
30
|
def applies?(context)
|
|
31
31
|
return false unless context.element
|
|
32
32
|
# Check if element responds to :form before accessing it
|
|
33
|
-
return false unless context.element.
|
|
33
|
+
return false unless context.element.is_a?(Lutaml::Xml::DataModel::XmlElement)
|
|
34
34
|
|
|
35
35
|
# Check if element has form attribute
|
|
36
36
|
form = context.element.form
|
|
@@ -44,7 +44,7 @@ module Lutaml
|
|
|
44
44
|
# Skip if namespace does NOT have element_form_default :qualified
|
|
45
45
|
# Namespaces without explicit :qualified should use default format
|
|
46
46
|
# (e.g., dcterms namespace uses default format, not prefix)
|
|
47
|
-
return false unless ns_class.
|
|
47
|
+
return false unless ns_class.is_a?(Class) && ns_class < Lutaml::Xml::Namespace &&
|
|
48
48
|
ns_class.element_form_default_set? &&
|
|
49
49
|
ns_class.element_form_default == :qualified
|
|
50
50
|
|
|
@@ -441,7 +441,7 @@ module Lutaml
|
|
|
441
441
|
ns_classes = []
|
|
442
442
|
collect_ns_classes_recursive(@root_node, ns_classes)
|
|
443
443
|
ns_classes.uniq.select do |ns_class|
|
|
444
|
-
ns_class.
|
|
444
|
+
ns_class.is_a?(Class) && ns_class < Lutaml::Xml::Namespace && ns_class.schema_location
|
|
445
445
|
end
|
|
446
446
|
end
|
|
447
447
|
|
|
@@ -452,7 +452,7 @@ module Lutaml
|
|
|
452
452
|
# @return [void]
|
|
453
453
|
def collect_ns_classes_recursive(element_node, ns_classes)
|
|
454
454
|
# Add namespace from element's own namespace_class
|
|
455
|
-
if element_node.
|
|
455
|
+
if element_node.is_a?(Lutaml::Xml::DeclarationPlan::ElementNode) && @namespace_classes
|
|
456
456
|
# Try to find namespace class from namespace_classes by matching URI
|
|
457
457
|
# The ElementNode itself doesn't store ns_class, but we can check if
|
|
458
458
|
# any of our namespace_classes match the element's context
|