lutaml-model 0.8.11 → 0.8.13
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/opal.yml +31 -0
- data/.rspec-opal +5 -0
- data/.rubocop_todo.yml +45 -34
- data/README.adoc +126 -104
- data/RELEASE_NOTES.adoc +3 -3
- data/benchmark/quick_benchmark.rb +2 -2
- data/benchmark/serialization_benchmark.rb +4 -4
- data/docs/_guides/advanced-mapping.adoc +1 -1
- data/docs/_guides/character-encoding.adoc +3 -3
- data/docs/_guides/index.adoc +4 -0
- data/docs/_guides/missing-values-handling.adoc +6 -6
- data/docs/_guides/ooxml-examples.adoc +7 -7
- data/docs/_guides/opal.adoc +221 -0
- data/docs/_guides/value-transformations.adoc +7 -7
- data/docs/_guides/xml/namespace-presentation.adoc +1 -1
- data/docs/_guides/xml/namespace-semantics.adoc +15 -15
- data/docs/_guides/xml/type-namespaces.adoc +9 -9
- data/docs/_guides/xml-mapping.adoc +32 -26
- data/docs/_guides/xml-namespace-qualification.adoc +4 -4
- data/docs/_guides/xml-namespaces.adoc +2 -2
- data/docs/_guides/xml_mappings/04_xml_namespace_class.adoc +18 -18
- data/docs/_guides/xml_mappings/05_common_patterns.adoc +16 -16
- data/docs/_guides/xml_mappings/06_migration_guide.adoc +5 -5
- data/docs/_guides/xml_mappings/07_best_practices.adoc +13 -12
- data/docs/_migrations/0-8-0-namespace-restructuring.adoc +2 -2
- data/docs/_pages/attributes.adoc +2 -2
- data/docs/_pages/collections.adoc +26 -20
- data/docs/_pages/configuration.adoc +9 -4
- data/docs/_pages/consolidation-mapping.adoc +4 -4
- data/docs/_pages/importable_models.adoc +14 -13
- data/docs/_pages/index.adoc +1 -0
- data/docs/_pages/quick-start.adoc +1 -1
- data/docs/_pages/serialization_adapters.adoc +3 -2
- data/docs/_pages/value_types.adoc +10 -10
- data/docs/_references/custom_registers.adoc +7 -7
- data/docs/_references/format-independent-features.adoc +4 -4
- data/docs/_references/instance-serialization.adoc +1 -1
- data/docs/_references/parent-root-context.adoc +3 -3
- data/docs/_tutorials/basic-model-definition.adoc +1 -1
- data/docs/_tutorials/first-xml-serialization.adoc +4 -4
- data/docs/_tutorials/lutaml-xml-architecture.adoc +4 -4
- data/docs/_tutorials/validation-basics.adoc +1 -1
- data/docs/_tutorials/working-with-collections.adoc +2 -2
- data/docs/_tutorials/xml-namespaces-basics.adoc +1 -1
- data/docs/_tutorials/xml-schema-primer-style-guide.adoc +29 -29
- data/docs/cli_compare.adoc +1 -1
- data/docs/index.adoc +2 -1
- data/docs/namespace-management.adoc +14 -14
- data/lib/lutaml/hash_format/adapter/mapping.rb +2 -4
- data/lib/lutaml/json/adapter/mapping.rb +2 -4
- data/lib/lutaml/jsonl/adapter/mapping.rb +2 -4
- data/lib/lutaml/key_value/adapter/hash/mapping.rb +2 -4
- data/lib/lutaml/key_value/adapter/json/mapping.rb +2 -4
- data/lib/lutaml/key_value/adapter/jsonl/mapping.rb +2 -4
- data/lib/lutaml/key_value/adapter/toml/mapping.rb +2 -4
- data/lib/lutaml/key_value/adapter/yaml/mapping.rb +2 -4
- data/lib/lutaml/key_value/adapter/yamls/mapping.rb +2 -4
- data/lib/lutaml/key_value/mapping.rb +35 -10
- data/lib/lutaml/model/adapter_resolver.rb +5 -8
- data/lib/lutaml/model/collection.rb +11 -11
- data/lib/lutaml/model/error/no_root_mapping_error.rb +6 -5
- data/lib/lutaml/model/error/no_root_namespace_error.rb +6 -5
- data/lib/lutaml/model/error/type_only_mapping_error.rb +13 -0
- data/lib/lutaml/model/error/type_only_namespace_error.rb +12 -0
- data/lib/lutaml/model/mapping/mapping.rb +12 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model.rb +3 -0
- data/lib/lutaml/toml/adapter/mapping.rb +2 -4
- data/lib/lutaml/xml/adapter/base_adapter.rb +0 -9
- data/lib/lutaml/xml/adapter/nokogiri_adapter.rb +0 -1
- data/lib/lutaml/xml/adapter/oga_adapter.rb +0 -1
- data/lib/lutaml/xml/adapter/ox_adapter.rb +0 -1
- data/lib/lutaml/xml/adapter/rexml_adapter.rb +0 -1
- data/lib/lutaml/xml/adapter/xml_serializer.rb +42 -22
- data/lib/lutaml/xml/adapter.rb +4 -0
- data/lib/lutaml/xml/builder/base.rb +64 -25
- data/lib/lutaml/xml/builder/nokogiri.rb +0 -2
- data/lib/lutaml/xml/builder/oga.rb +0 -2
- data/lib/lutaml/xml/builder/ox.rb +0 -2
- data/lib/lutaml/xml/builder/rexml.rb +0 -2
- data/lib/lutaml/xml/builder.rb +1 -0
- data/lib/lutaml/xml/configurable.rb +2 -2
- data/lib/lutaml/xml/declaration_handler.rb +3 -105
- data/lib/lutaml/xml/mapping.rb +3 -3
- data/lib/lutaml/xml/schema/xsd/documentation.rb +1 -1
- data/lib/lutaml/xml/schema/xsd.rb +5 -4
- data/lib/lutaml/xml/schema.rb +8 -5
- data/lib/lutaml/xml/serialization/collection_ext.rb +7 -7
- data/lib/lutaml/xml/serialization/format_conversion.rb +1 -1
- data/lib/lutaml/xml/serialization/instance_methods.rb +1 -1
- data/lib/lutaml/xml/xml_orderable.rb +17 -0
- data/lib/lutaml/xml.rb +9 -13
- data/lib/lutaml/yaml/adapter/mapping.rb +2 -4
- data/lib/lutaml/yamls/adapter/mapping.rb +7 -3
- data/lib/tasks/memory_profile.rb +2 -2
- data/lib/tasks/performance_benchmark.rb +5 -5
- data/lutaml-model.gemspec +1 -1
- data/spec/lutaml/key_value/transformation/rule_compiler_spec.rb +1 -1
- data/spec/lutaml/key_value/transformation/value_serializer_spec.rb +1 -1
- data/spec/lutaml/model/attribute_collection_spec.rb +1 -1
- data/spec/lutaml/model/cli_spec.rb +1 -1
- data/spec/lutaml/model/collection_spec.rb +1 -1
- data/spec/lutaml/model/collection_validation_spec.rb +6 -6
- data/spec/lutaml/model/consolidation_spec.rb +8 -8
- data/spec/lutaml/model/custom_collection_spec.rb +3 -3
- data/spec/lutaml/model/default_register_spec.rb +23 -23
- data/spec/lutaml/model/delegation_spec.rb +3 -10
- data/spec/lutaml/model/derived_attribute_serialization_spec.rb +1 -1
- data/spec/lutaml/model/dynamic_attribute_spec.rb +2 -2
- data/spec/lutaml/model/enum_spec.rb +1 -1
- data/spec/lutaml/model/group_spec.rb +12 -12
- data/spec/lutaml/model/lazy_collection_spec.rb +4 -4
- data/spec/lutaml/model/mixed_content_spec.rb +2 -2
- data/spec/lutaml/model/namespace_versioning_spec.rb +4 -4
- data/spec/lutaml/model/opal_smoke_spec.rb +117 -0
- data/spec/lutaml/model/processing_instruction_spec.rb +11 -11
- data/spec/lutaml/model/register_methods_spec.rb +2 -2
- data/spec/lutaml/model/render_empty_spec.rb +1 -1
- data/spec/lutaml/model/serialize_perf_guard_spec.rb +1 -1
- data/spec/lutaml/model/transform_dynamic_attributes_spec.rb +1 -1
- data/spec/lutaml/model/transformation_builder_spec.rb +2 -2
- data/spec/lutaml/model/xml_decoupling_spec.rb +3 -3
- data/spec/lutaml/model/xsd_patterns_spec.rb +2 -3
- data/spec/lutaml/xml/adapter/order_spec.rb +1 -1
- data/spec/lutaml/xml/clear_parse_state_spec.rb +1 -1
- data/spec/lutaml/xml/content_model_validation_spec.rb +4 -2
- data/spec/lutaml/xml/doubly_defined_namespace_spec.rb +5 -5
- data/spec/lutaml/xml/enhanced_mapping_spec.rb +2 -1
- data/spec/lutaml/xml/entity_fragmentation_spec.rb +5 -5
- data/spec/lutaml/xml/indent_spec.rb +109 -0
- data/spec/lutaml/xml/line_ending_spec.rb +66 -0
- data/spec/lutaml/xml/mapping_finalization_guard_spec.rb +2 -2
- data/spec/lutaml/xml/model_transform_guard_spec.rb +4 -4
- data/spec/lutaml/xml/namespace_alias_spec.rb +4 -4
- data/spec/lutaml/xml/namespace_aware_parsing_spec.rb +3 -3
- data/spec/lutaml/xml/namespace_bound_element_roundtrip_spec.rb +2 -2
- data/spec/lutaml/xml/namespace_format_preservation_spec.rb +1 -1
- data/spec/lutaml/xml/namespace_inheritance_spec.rb +3 -3
- data/spec/lutaml/xml/namespace_preservation_spec.rb +5 -5
- data/spec/lutaml/xml/opal_xml_spec.rb +145 -0
- data/spec/lutaml/xml/pipeline_integration_spec.rb +145 -0
- data/spec/lutaml/xml/schema_primer_spec.rb +5 -5
- data/spec/lutaml/xml/transformation_spec.rb +20 -20
- data/spec/lutaml/xml/type_namespace/collector_spec.rb +1 -1
- data/spec/lutaml/xml/type_namespace/planner_spec.rb +3 -3
- data/spec/lutaml/xml/xml_spec.rb +64 -13
- data/spec/support/opal.rb +6 -0
- metadata +16 -4
data/lib/lutaml/xml/builder.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Lutaml
|
|
|
13
13
|
# include Lutaml::Xml::Configurable
|
|
14
14
|
#
|
|
15
15
|
# xml do
|
|
16
|
-
#
|
|
16
|
+
# element "MyModel"
|
|
17
17
|
# namespace MyNamespace
|
|
18
18
|
# end
|
|
19
19
|
# end
|
|
@@ -51,7 +51,7 @@ module Lutaml
|
|
|
51
51
|
#
|
|
52
52
|
# @example Configuration with block
|
|
53
53
|
# xml do
|
|
54
|
-
#
|
|
54
|
+
# element "MyModel"
|
|
55
55
|
# namespace MyNamespace
|
|
56
56
|
# map_element 'name', to: :name
|
|
57
57
|
# end
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
module Lutaml
|
|
2
2
|
module Xml
|
|
3
|
-
# DeclarationHandler provides XML declaration
|
|
4
|
-
# for all XML adapter implementations.
|
|
3
|
+
# DeclarationHandler provides XML declaration extraction from input XML.
|
|
5
4
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# Extraction methods detect and parse XML declarations from input strings.
|
|
6
|
+
# Generation is handled by moxml's document model — no manual string assembly.
|
|
8
7
|
module DeclarationHandler
|
|
9
8
|
# Extract XML declaration information from input string
|
|
10
9
|
#
|
|
@@ -92,126 +91,25 @@ module Lutaml
|
|
|
92
91
|
# @param xml_declaration [Hash] extracted declaration info from input
|
|
93
92
|
# @return [Boolean] true if declaration should be included
|
|
94
93
|
def should_include_declaration?(options, xml_declaration = nil)
|
|
95
|
-
# Use instance variable if not provided (for adapter instance methods)
|
|
96
94
|
xml_declaration ||= @xml_declaration
|
|
97
95
|
|
|
98
96
|
if options.key?(:declaration)
|
|
99
97
|
case options[:declaration]
|
|
100
98
|
when false
|
|
101
|
-
# Explicit false: omit declaration
|
|
102
99
|
false
|
|
103
100
|
when true
|
|
104
|
-
# Explicit true: force include
|
|
105
101
|
true
|
|
106
102
|
when :preserve
|
|
107
|
-
# Preserve mode: include if input had one
|
|
108
103
|
xml_declaration&.dig(:had_declaration) || false
|
|
109
104
|
when String
|
|
110
|
-
# Custom version string: include
|
|
111
105
|
true
|
|
112
106
|
else
|
|
113
|
-
# Default: preserve from input
|
|
114
107
|
xml_declaration&.dig(:had_declaration) || false
|
|
115
108
|
end
|
|
116
109
|
else
|
|
117
|
-
# No declaration option provided: default behavior is preserve from input
|
|
118
110
|
xml_declaration&.dig(:had_declaration) || false
|
|
119
111
|
end
|
|
120
112
|
end
|
|
121
|
-
|
|
122
|
-
# Generate XML declaration string
|
|
123
|
-
#
|
|
124
|
-
# Uses stored declaration info if available, otherwise uses defaults.
|
|
125
|
-
# Supports custom version strings, encoding, and standalone options.
|
|
126
|
-
#
|
|
127
|
-
# @param options [Hash] serialization options
|
|
128
|
-
# - :declaration => String for custom version, true for default
|
|
129
|
-
# - :encoding => String or true for UTF-8
|
|
130
|
-
# - :standalone => String ("yes"/"no"), true ("yes"), false ("no"), :preserve
|
|
131
|
-
# @param xml_declaration [Hash] extracted declaration info from input
|
|
132
|
-
# @return [String] the XML declaration (includes trailing newline)
|
|
133
|
-
def generate_declaration(options, xml_declaration = nil)
|
|
134
|
-
# Use instance variable if not provided (for adapter instance methods)
|
|
135
|
-
xml_declaration ||= @xml_declaration
|
|
136
|
-
|
|
137
|
-
# Determine version
|
|
138
|
-
# When declaration: true (force), use default 1.0 not input version
|
|
139
|
-
# When declaration: "1.x" (custom), use that string
|
|
140
|
-
# When preserving (no option or :preserve), use input version or default
|
|
141
|
-
version = if options[:declaration].is_a?(String)
|
|
142
|
-
# Custom version string
|
|
143
|
-
options[:declaration]
|
|
144
|
-
elsif options[:declaration] == true
|
|
145
|
-
# Force with default version
|
|
146
|
-
"1.0"
|
|
147
|
-
elsif xml_declaration&.dig(:version)
|
|
148
|
-
# Preserve from input
|
|
149
|
-
xml_declaration[:version]
|
|
150
|
-
else
|
|
151
|
-
# Default fallback
|
|
152
|
-
"1.0"
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# Determine encoding
|
|
156
|
-
# Priority: explicit encoding option > input encoding > none
|
|
157
|
-
encoding = if options[:encoding].is_a?(String)
|
|
158
|
-
options[:encoding]
|
|
159
|
-
elsif options[:encoding] == true
|
|
160
|
-
"UTF-8"
|
|
161
|
-
elsif xml_declaration&.dig(:encoding)
|
|
162
|
-
xml_declaration[:encoding]
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# Determine standalone
|
|
166
|
-
# Priority: explicit standalone option > input standalone > none
|
|
167
|
-
# Supported values: "yes", "no", true ("yes"), false ("no"), :preserve
|
|
168
|
-
standalone = if options.key?(:standalone)
|
|
169
|
-
case options[:standalone]
|
|
170
|
-
when String
|
|
171
|
-
options[:standalone]
|
|
172
|
-
when true
|
|
173
|
-
"yes"
|
|
174
|
-
when false
|
|
175
|
-
"no"
|
|
176
|
-
when :preserve
|
|
177
|
-
xml_declaration&.dig(:standalone)
|
|
178
|
-
end
|
|
179
|
-
elsif xml_declaration&.dig(:standalone)
|
|
180
|
-
xml_declaration[:standalone]
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
declaration = "<?xml version=\"#{version}\""
|
|
184
|
-
declaration += " encoding=\"#{encoding}\"" if encoding
|
|
185
|
-
declaration += " standalone=\"#{standalone}\"" if standalone
|
|
186
|
-
declaration += "?>\n"
|
|
187
|
-
declaration
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
# Generate DOCTYPE declaration from doctype hash
|
|
191
|
-
#
|
|
192
|
-
# Supports both PUBLIC and SYSTEM DTDs.
|
|
193
|
-
# Format: <!DOCTYPE name PUBLIC "public_id" "system_id">
|
|
194
|
-
# <!DOCTYPE name SYSTEM "system_id">
|
|
195
|
-
#
|
|
196
|
-
# @param doctype [Hash] the doctype information
|
|
197
|
-
# - :name => root element name
|
|
198
|
-
# - :public_id => public identifier (optional)
|
|
199
|
-
# - :system_id => system identifier (optional)
|
|
200
|
-
# @return [String, nil] the DOCTYPE declaration or nil if no doctype
|
|
201
|
-
def generate_doctype_declaration(doctype)
|
|
202
|
-
return nil unless doctype
|
|
203
|
-
|
|
204
|
-
parts = ["<!DOCTYPE #{doctype[:name]}"]
|
|
205
|
-
|
|
206
|
-
if doctype[:public_id]
|
|
207
|
-
parts << %(PUBLIC "#{doctype[:public_id]}")
|
|
208
|
-
parts << %("#{doctype[:system_id]}") if doctype[:system_id]
|
|
209
|
-
elsif doctype[:system_id]
|
|
210
|
-
parts << %(SYSTEM "#{doctype[:system_id]}")
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
"#{parts.join(' ')}>\n"
|
|
214
|
-
end
|
|
215
113
|
end
|
|
216
114
|
end
|
|
217
115
|
end
|
data/lib/lutaml/xml/mapping.rb
CHANGED
|
@@ -350,11 +350,11 @@ module Lutaml
|
|
|
350
350
|
# namespace :blank
|
|
351
351
|
#
|
|
352
352
|
# @raise [ArgumentError] if invalid arguments provided
|
|
353
|
-
# @raise [Lutaml::Model::
|
|
353
|
+
# @raise [Lutaml::Model::TypeOnlyNamespaceError] if explicitly marked as no_root
|
|
354
354
|
def namespace(ns_class_or_symbol, _deprecated_prefix = nil)
|
|
355
355
|
# Only raise error for explicitly marked no_root (using deprecated method)
|
|
356
356
|
# Type-only models (no element declared) CAN have namespaces
|
|
357
|
-
raise Lutaml::Model::
|
|
357
|
+
raise Lutaml::Model::TypeOnlyNamespaceError if @no_root
|
|
358
358
|
|
|
359
359
|
# Warn if prefix parameter is provided
|
|
360
360
|
if _deprecated_prefix
|
|
@@ -784,7 +784,7 @@ module Lutaml
|
|
|
784
784
|
#
|
|
785
785
|
# @example
|
|
786
786
|
# xml do
|
|
787
|
-
#
|
|
787
|
+
# element "rfc"
|
|
788
788
|
# map_processing_instruction "rfc", to: :pi_settings
|
|
789
789
|
# end
|
|
790
790
|
#
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
# NOTE: Do NOT require lutaml/model here. This file is autoloaded via
|
|
4
4
|
# Lutaml::Xml::Schema::Xsd, and requiring lutaml/model creates a circular
|
|
5
|
-
# dependency since lutaml/xml.rb requires lutaml/model.
|
|
6
|
-
#
|
|
5
|
+
# dependency since lutaml/xml.rb requires lutaml/model. This file only sets
|
|
6
|
+
# a fallback XML adapter when no adapter has been selected yet.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
Lutaml::Model::Config.xml_adapter_type =
|
|
8
|
+
unless defined?(Lutaml::Model::Config.xml_adapter_type)
|
|
9
|
+
Lutaml::Model::Config.xml_adapter_type = Lutaml::Model::AdapterResolver.detect_xml_adapter
|
|
10
|
+
end
|
|
10
11
|
|
|
11
12
|
# Require the XsdNamespace class for XSD schema support
|
|
12
13
|
require_relative "xsd_namespace"
|
data/lib/lutaml/xml/schema.rb
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
module Lutaml
|
|
4
4
|
module Xml
|
|
5
5
|
module Schema
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
Lutaml::Model::RuntimeCompatibility.autoload_native(
|
|
7
|
+
self,
|
|
8
|
+
Xsd: "#{__dir__}/schema/xsd",
|
|
9
|
+
XsdSchema: "#{__dir__}/schema/xsd_schema",
|
|
10
|
+
RelaxngSchema: "#{__dir__}/schema/relaxng_schema",
|
|
11
|
+
Builder: "#{__dir__}/schema/builder",
|
|
12
|
+
BuiltinTypes: "#{__dir__}/schema/builtin_types",
|
|
13
|
+
)
|
|
11
14
|
end
|
|
12
15
|
end
|
|
13
16
|
end
|
|
@@ -6,7 +6,7 @@ module Lutaml
|
|
|
6
6
|
# XML-specific overrides for Collection class methods.
|
|
7
7
|
#
|
|
8
8
|
# Prepended into Collection's singleton class when XML is loaded.
|
|
9
|
-
# Provides XML-specific
|
|
9
|
+
# Provides XML-specific unwrapped collection handling.
|
|
10
10
|
module CollectionExt
|
|
11
11
|
# XML is a structured (tree-based) format
|
|
12
12
|
def collection_structured_format?(format)
|
|
@@ -15,15 +15,15 @@ module Lutaml
|
|
|
15
15
|
true
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
# XML handles
|
|
19
|
-
def
|
|
18
|
+
# XML handles unwrapped serialization specially
|
|
19
|
+
def collection_unwrapped_to?(format)
|
|
20
20
|
return super unless format == :xml
|
|
21
21
|
|
|
22
22
|
true
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
# XML
|
|
26
|
-
def
|
|
25
|
+
# XML unwrapped serialization: serialize each mapping separately
|
|
26
|
+
def collection_unwrapped_to(format, mappings, instance, options)
|
|
27
27
|
return super unless format == :xml
|
|
28
28
|
|
|
29
29
|
mappings.mappings.map do |mapping|
|
|
@@ -31,8 +31,8 @@ module Lutaml
|
|
|
31
31
|
end.join("\n")
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
# XML
|
|
35
|
-
def
|
|
34
|
+
# XML unwrapped: wrap raw XML in a fake root tag before parsing
|
|
35
|
+
def wrap_unwrapped_input(format, mappings, data)
|
|
36
36
|
return super unless format == :xml
|
|
37
37
|
|
|
38
38
|
tag_name = mappings.find_by_to!(instance_name).name
|
|
@@ -94,7 +94,7 @@ module Lutaml
|
|
|
94
94
|
return super unless format == :xml
|
|
95
95
|
|
|
96
96
|
valid = root?(register) || options[:from_collection]
|
|
97
|
-
raise Lutaml::Model::
|
|
97
|
+
raise Lutaml::Model::TypeOnlyMappingError.new(self) unless valid
|
|
98
98
|
|
|
99
99
|
options[:encoding] = doc.encoding
|
|
100
100
|
if doc.is_a?(Lutaml::Xml::Document) && doc.doctype
|
|
@@ -204,7 +204,7 @@ module Lutaml
|
|
|
204
204
|
return super unless format == :xml
|
|
205
205
|
return if options[:collection] || self.class.root?(lutaml_register)
|
|
206
206
|
|
|
207
|
-
raise Lutaml::Model::
|
|
207
|
+
raise Lutaml::Model::TypeOnlyMappingError.new(self.class)
|
|
208
208
|
end
|
|
209
209
|
|
|
210
210
|
# XML-specific instance options preparation
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lutaml
|
|
4
|
+
module Xml
|
|
5
|
+
# Mixin for XML element/attribute ordering state.
|
|
6
|
+
#
|
|
7
|
+
# Included by:
|
|
8
|
+
# - Lutaml::Xml::Serialization::InstanceMethods (Serialize instances)
|
|
9
|
+
# - Plain model classes via add_format_specific_model_methods
|
|
10
|
+
#
|
|
11
|
+
# Enables Lutaml::Model to check ordering capability with is_a? instead
|
|
12
|
+
# of respond_to?, following proper OOP type-checking.
|
|
13
|
+
module XmlOrderable
|
|
14
|
+
attr_accessor :element_order, :attribute_order, :ordered, :mixed
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/lutaml/xml.rb
CHANGED
|
@@ -42,16 +42,13 @@ module Lutaml
|
|
|
42
42
|
# XML Schema modules
|
|
43
43
|
autoload :Schema, "#{__dir__}/xml/schema"
|
|
44
44
|
|
|
45
|
-
# Detect available XML adapter
|
|
46
|
-
#
|
|
45
|
+
# Detect available XML adapter.
|
|
46
|
+
# Delegates to moxml, which is the authority on XML adapter
|
|
47
|
+
# availability and platform constraints.
|
|
48
|
+
#
|
|
49
|
+
# @return [Symbol] adapter type name
|
|
47
50
|
def self.detect_xml_adapter
|
|
48
|
-
|
|
49
|
-
return :nokogiri if Lutaml::Model::Utils.safe_load("nokogiri", :Nokogiri)
|
|
50
|
-
return :ox if Lutaml::Model::Utils.safe_load("ox", :Ox)
|
|
51
|
-
return :oga if Lutaml::Model::Utils.safe_load("oga", :Oga)
|
|
52
|
-
return :rexml if Lutaml::Model::Utils.safe_load("rexml", :REXML)
|
|
53
|
-
|
|
54
|
-
nil
|
|
51
|
+
Moxml::Config.runtime_default_adapter
|
|
55
52
|
end
|
|
56
53
|
|
|
57
54
|
# Get the current XML adapter
|
|
@@ -137,7 +134,6 @@ module Lutaml
|
|
|
137
134
|
autoload :ElementPrefixResolver, "#{__dir__}/xml/element_prefix_resolver"
|
|
138
135
|
autoload :FormatChooser, "#{__dir__}/xml/format_chooser"
|
|
139
136
|
autoload :HoistingAlgorithm, "#{__dir__}/xml/hoisting_algorithm"
|
|
140
|
-
autoload :HoistingAlgorithm, "#{__dir__}/xml/hoisting_algorithm"
|
|
141
137
|
autoload :NamespaceInheritanceResolver,
|
|
142
138
|
"#{__dir__}/xml/namespace_inheritance_resolver"
|
|
143
139
|
autoload :NamespaceScopeConfig, "#{__dir__}/xml/namespace_scope_config"
|
|
@@ -174,8 +170,8 @@ Lutaml::Model::FormatRegistry.register(
|
|
|
174
170
|
],
|
|
175
171
|
adapter_options: if Lutaml::Model::RuntimeCompatibility.opal?
|
|
176
172
|
{
|
|
177
|
-
available: %i[
|
|
178
|
-
default: :
|
|
173
|
+
available: %i[rexml],
|
|
174
|
+
default: :rexml,
|
|
179
175
|
}
|
|
180
176
|
else
|
|
181
177
|
{
|
|
@@ -232,7 +228,7 @@ end
|
|
|
232
228
|
Lutaml::Model::Attribute.format_specific_warn_names.push(:element_order,
|
|
233
229
|
:schema_location, :encoding, :doctype, :ordered?, :mixed?)
|
|
234
230
|
|
|
235
|
-
# Prepend XML-specific Collection overrides (
|
|
231
|
+
# Prepend XML-specific Collection overrides (unwrapped collection handling for XML)
|
|
236
232
|
require_relative "xml/serialization/collection_ext"
|
|
237
233
|
Lutaml::Model::Collection.singleton_class.prepend(
|
|
238
234
|
Lutaml::Xml::Serialization::CollectionExt,
|
|
@@ -4,7 +4,7 @@ module Lutaml
|
|
|
4
4
|
module Yamls
|
|
5
5
|
module Adapter
|
|
6
6
|
class Mapping < Lutaml::KeyValue::Mapping
|
|
7
|
-
|
|
7
|
+
attr_accessor :yamls_sequence
|
|
8
8
|
|
|
9
9
|
def initialize
|
|
10
10
|
super(:yaml)
|
|
@@ -15,9 +15,13 @@ module Lutaml
|
|
|
15
15
|
@yamls_sequence.instance_eval(&)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def dup_instance
|
|
19
|
+
self.class.new
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
def deep_dup
|
|
19
|
-
|
|
20
|
-
new_mapping.
|
|
23
|
+
super.tap do |new_mapping|
|
|
24
|
+
new_mapping.yamls_sequence = @yamls_sequence&.dup
|
|
21
25
|
end
|
|
22
26
|
end
|
|
23
27
|
end
|
data/lib/tasks/memory_profile.rb
CHANGED
|
@@ -18,7 +18,7 @@ class Address < Lutaml::Model::Serializable
|
|
|
18
18
|
attribute :country, :string
|
|
19
19
|
|
|
20
20
|
xml do
|
|
21
|
-
|
|
21
|
+
element "address"
|
|
22
22
|
map_element "street", to: :street
|
|
23
23
|
map_element "city", to: :city
|
|
24
24
|
map_element "zip", to: :zip
|
|
@@ -37,7 +37,7 @@ class Person < Lutaml::Model::Serializable
|
|
|
37
37
|
attribute :tags, :string, collection: true
|
|
38
38
|
|
|
39
39
|
xml do
|
|
40
|
-
|
|
40
|
+
element "person"
|
|
41
41
|
map_attribute "id", to: :id
|
|
42
42
|
map_element "first_name", to: :first_name
|
|
43
43
|
map_element "last_name", to: :last_name
|
|
@@ -21,7 +21,7 @@ module Lutaml
|
|
|
21
21
|
attribute :created_at, :date_time
|
|
22
22
|
|
|
23
23
|
xml do
|
|
24
|
-
|
|
24
|
+
element "simple"
|
|
25
25
|
map_attribute "id", to: :id
|
|
26
26
|
map_element "name", to: :name
|
|
27
27
|
map_element "active", to: :active
|
|
@@ -46,7 +46,7 @@ module Lutaml
|
|
|
46
46
|
attribute :country, :string
|
|
47
47
|
|
|
48
48
|
xml do
|
|
49
|
-
|
|
49
|
+
element "address"
|
|
50
50
|
map_element "street", to: :street
|
|
51
51
|
map_element "city", to: :city
|
|
52
52
|
map_element "zip", to: :zip
|
|
@@ -73,7 +73,7 @@ module Lutaml
|
|
|
73
73
|
attribute :tags, :string, collection: true
|
|
74
74
|
|
|
75
75
|
xml do
|
|
76
|
-
|
|
76
|
+
element "person"
|
|
77
77
|
map_attribute "id", to: :id
|
|
78
78
|
map_element "first_name", to: :first_name
|
|
79
79
|
map_element "last_name", to: :last_name
|
|
@@ -103,7 +103,7 @@ module Lutaml
|
|
|
103
103
|
attribute :price, :float
|
|
104
104
|
|
|
105
105
|
xml do
|
|
106
|
-
|
|
106
|
+
element "item"
|
|
107
107
|
map_attribute "product_id", to: :product_id
|
|
108
108
|
map_element "quantity", to: :quantity
|
|
109
109
|
map_element "price", to: :price
|
|
@@ -118,7 +118,7 @@ module Lutaml
|
|
|
118
118
|
attribute :status, :string
|
|
119
119
|
|
|
120
120
|
xml do
|
|
121
|
-
|
|
121
|
+
element "order"
|
|
122
122
|
map_attribute "id", to: :id
|
|
123
123
|
map_element "customer", to: :customer
|
|
124
124
|
map_element "item", to: :items
|
data/lutaml-model.gemspec
CHANGED
|
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
|
|
|
36
36
|
spec.add_dependency "canon"
|
|
37
37
|
spec.add_dependency "concurrent-ruby"
|
|
38
38
|
spec.add_dependency "liquid", ">= 4.0", "< 6.0"
|
|
39
|
-
spec.add_dependency "moxml", ">= 0.1.
|
|
39
|
+
spec.add_dependency "moxml", ">= 0.1.22"
|
|
40
40
|
spec.add_dependency "ostruct"
|
|
41
41
|
spec.add_dependency "rubyzip", "~> 2.3"
|
|
42
42
|
spec.add_dependency "thor"
|
|
@@ -33,7 +33,7 @@ RSpec.describe Lutaml::Model::Cli do
|
|
|
33
33
|
attribute :extract_language, ExtractLanguage, collection: true
|
|
34
34
|
|
|
35
35
|
xml do
|
|
36
|
-
|
|
36
|
+
element "termium_extract"
|
|
37
37
|
namespace TermiumNamespace
|
|
38
38
|
|
|
39
39
|
map_attribute "language", to: :language, namespace: nil
|
|
@@ -10,7 +10,7 @@ module CollectionValidationTests
|
|
|
10
10
|
attribute :category, :string
|
|
11
11
|
|
|
12
12
|
xml do
|
|
13
|
-
|
|
13
|
+
element "publication"
|
|
14
14
|
map_attribute "id", to: :id
|
|
15
15
|
map_element "title", to: :title
|
|
16
16
|
map_element "year", to: :year
|
|
@@ -33,7 +33,7 @@ module CollectionValidationTests
|
|
|
33
33
|
validates_uniqueness_of :id, message: "Publication IDs must be unique"
|
|
34
34
|
|
|
35
35
|
xml do
|
|
36
|
-
|
|
36
|
+
element "publications"
|
|
37
37
|
map_element "publication", to: :publications
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -49,7 +49,7 @@ module CollectionValidationTests
|
|
|
49
49
|
validates_max_count 5, message: "Cannot have more than 5 publications"
|
|
50
50
|
|
|
51
51
|
xml do
|
|
52
|
-
|
|
52
|
+
element "publications"
|
|
53
53
|
map_element "publication", to: :publications
|
|
54
54
|
end
|
|
55
55
|
|
|
@@ -66,7 +66,7 @@ module CollectionValidationTests
|
|
|
66
66
|
validates_all_present :year, message: "All publications must have a year"
|
|
67
67
|
|
|
68
68
|
xml do
|
|
69
|
-
|
|
69
|
+
element "publications"
|
|
70
70
|
map_element "publication", to: :publications
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -102,7 +102,7 @@ module CollectionValidationTests
|
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
xml do
|
|
105
|
-
|
|
105
|
+
element "publications"
|
|
106
106
|
map_element "publication", to: :publications
|
|
107
107
|
end
|
|
108
108
|
|
|
@@ -122,7 +122,7 @@ module CollectionValidationTests
|
|
|
122
122
|
validates_min_count 1 # Collection-level validation
|
|
123
123
|
|
|
124
124
|
xml do
|
|
125
|
-
|
|
125
|
+
element "publications"
|
|
126
126
|
map_element "publication", to: :publications
|
|
127
127
|
end
|
|
128
128
|
|
|
@@ -18,7 +18,7 @@ RSpec.describe "Consolidation Mapping" do
|
|
|
18
18
|
attribute :content, :string
|
|
19
19
|
|
|
20
20
|
xml do
|
|
21
|
-
|
|
21
|
+
element "title"
|
|
22
22
|
map_attribute "lang", to: :lang
|
|
23
23
|
map_attribute "type", to: :type_of_title
|
|
24
24
|
map_content to: :content
|
|
@@ -40,7 +40,7 @@ RSpec.describe "Consolidation Mapping" do
|
|
|
40
40
|
organizes :per_lang, ConPerLangGroup
|
|
41
41
|
|
|
42
42
|
xml do
|
|
43
|
-
|
|
43
|
+
element "titles"
|
|
44
44
|
map_instances to: :items
|
|
45
45
|
consolidate_map by: :lang, to: :per_lang do
|
|
46
46
|
gather :lang, to: :lang
|
|
@@ -59,7 +59,7 @@ RSpec.describe "Consolidation Mapping" do
|
|
|
59
59
|
attribute :titles, ConTitle, collection: ConTitleCollection
|
|
60
60
|
|
|
61
61
|
xml do
|
|
62
|
-
|
|
62
|
+
element "bibdata"
|
|
63
63
|
map_element "title", to: :titles
|
|
64
64
|
end
|
|
65
65
|
end)
|
|
@@ -141,7 +141,7 @@ RSpec.describe "Consolidation Mapping" do
|
|
|
141
141
|
attribute :content, :string
|
|
142
142
|
|
|
143
143
|
xml do
|
|
144
|
-
|
|
144
|
+
element "title"
|
|
145
145
|
map_attribute "lang", to: :lang
|
|
146
146
|
map_attribute "type", to: :type_of_title
|
|
147
147
|
map_content to: :content
|
|
@@ -159,7 +159,7 @@ RSpec.describe "Consolidation Mapping" do
|
|
|
159
159
|
organizes :per_type, ConPerTypeGroup
|
|
160
160
|
|
|
161
161
|
xml do
|
|
162
|
-
|
|
162
|
+
element "titles"
|
|
163
163
|
map_instances to: :items
|
|
164
164
|
consolidate_map by: :type_of_title, to: :per_type do
|
|
165
165
|
gather :type_of_title, to: :type_of_title
|
|
@@ -175,7 +175,7 @@ RSpec.describe "Consolidation Mapping" do
|
|
|
175
175
|
attribute :titles, ConTitle2, collection: ConTitleCollection2
|
|
176
176
|
|
|
177
177
|
xml do
|
|
178
|
-
|
|
178
|
+
element "bibdata"
|
|
179
179
|
map_element "title", to: :titles
|
|
180
180
|
end
|
|
181
181
|
end)
|
|
@@ -247,7 +247,7 @@ RSpec.describe "Consolidation Mapping" do
|
|
|
247
247
|
organizes :entries, group_class
|
|
248
248
|
|
|
249
249
|
xml do
|
|
250
|
-
|
|
250
|
+
element "test"
|
|
251
251
|
consolidate_map by: :lang, to: :entries do
|
|
252
252
|
gather :lang, to: :lang
|
|
253
253
|
dispatch_by :type do
|
|
@@ -276,7 +276,7 @@ RSpec.describe "Consolidation Mapping" do
|
|
|
276
276
|
organizes :entries, entry_class
|
|
277
277
|
|
|
278
278
|
xml do
|
|
279
|
-
|
|
279
|
+
element "test"
|
|
280
280
|
consolidate_map by: :pattern, to: :entries do
|
|
281
281
|
map_element "member", to: :name
|
|
282
282
|
map_element "member_key", to: :key
|