Module: Lutaml::Xml::Serialization::FormatConversion
- Defined in:
- lib/lutaml/xml/serialization/format_conversion.rb
Overview
XML-specific format conversion hooks for Serialize module
This module provides XML-specific serialization logic that extends the format-agnostic Lutaml::Model::Serialize::FormatConversion.
It is prepended into Serialize::ClassMethods when XML format is loaded, overriding the hook methods defined in FormatConversion.
Instance Method Summary collapse
-
#add_format_specific_model_methods(klass) ⇒ Object
Add XML-specific model methods (ordered, mixed, element_order, etc.) when
model CustomClassis used with a plain Ruby class. -
#apply_namespace_overrides(options) ⇒ Hash
Apply namespace prefix overrides for XML serialization.
-
#choice(min: 1, max: 1, format: :xml, &block) ⇒ Object
Override choice to set format: :xml so Choice knows which format it belongs to.
-
#namespace(ns_class = nil) ⇒ Class?
deprecated
Deprecated.
Use namespace inside
xml do ... endblocks instead. -
#namespace_prefix ⇒ String?
Get the default namespace prefix for this Model.
-
#namespace_uri ⇒ String?
Get the namespace URI for this Model.
-
#post_process_mapping(format) ⇒ Object
XML-specific post-processing after mapping DSL evaluation.
-
#pre_deserialize_hook(format, register) ⇒ Object
XML-specific pre-deserialization: resolve XML mapping imports.
-
#pre_serialize_hook(format, register) ⇒ Object
XML-specific pre-serialization: resolve XML mapping imports.
-
#prepare_to_options(format, instance, options) ⇒ Hash
XML-specific options preparation for serialization.
-
#process_mapping(format, *args, &block) ⇒ Object
Override process_mapping for XML format to handle mapping class inheritance.
-
#validate_document(format, doc, options, register) ⇒ Object
XML-specific document validation: root mapping, encoding, doctype.
-
#validate_xml(xml) ⇒ Array<Lutaml::Xml::Error::SchemaValidationError>
Validate a raw XML string against the configured schemas without instantiating a model — the explicit input-side counterpart to the validate/validate! output-side check.
- #validate_xml!(xml) ⇒ Object
-
#validate_xml_with(*paths) ⇒ Object
Configure one or more XSD schemas that the model's generated XML must conform to.
-
#xml_schema_paths ⇒ Array<String>
All configured XSD schema paths, parent-first: inherited paths come before paths declared on this class.
Instance Method Details
#add_format_specific_model_methods(klass) ⇒ Object
Add XML-specific model methods (ordered, mixed, element_order, etc.)
when model CustomClass is used with a plain Ruby class.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 209 def add_format_specific_model_methods(klass) super Lutaml::Model::Utils.add_boolean_accessor_if_not_defined(klass, :ordered) Lutaml::Model::Utils.add_boolean_accessor_if_not_defined(klass, :mixed) Lutaml::Model::Utils.add_accessor_if_not_defined(klass, :element_order) Lutaml::Model::Utils.add_accessor_if_not_defined(klass, :encoding) Lutaml::Model::Utils.add_accessor_if_not_defined(klass, :doctype) # XML namespace metadata accessors for custom model classes %i[xml_namespace_prefix xml_ns_prefixes original_namespace_uri xml_declaration raw_schema_location].each do |attr| Lutaml::Model::Utils.add_accessor_if_not_defined(klass, attr) end end |
#apply_namespace_overrides(options) ⇒ Hash
Apply namespace prefix overrides for XML serialization
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 230 def apply_namespace_overrides() namespaces = [:namespaces] return unless namespaces.is_a?(Array) # Build a namespace URI to prefix mapping ns_prefix_map = {} namespaces.each do |ns_config| if ns_config.is_a?(Hash) ns_class = ns_config[:namespace] prefix = ns_config[:prefix] if ns_class.is_a?(Class) && ns_class < Lutaml::Xml::Namespace && prefix ns_prefix_map[ns_class.uri] = prefix.to_s end end end unless ns_prefix_map.empty? [:namespace_prefix_map] = ns_prefix_map end end |
#choice(min: 1, max: 1, format: :xml, &block) ⇒ Object
Override choice to set format: :xml so Choice knows which format it belongs to.
96 97 98 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 96 def choice(min: 1, max: 1, format: :xml, &block) super end |
#namespace(ns_class = nil) ⇒ Class?
Use namespace inside xml do ... end blocks instead.
Class-level namespace directive for XML.
20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 20 def namespace(ns_class = nil) if ns_class unless ns_class.is_a?(Class) && ns_class < Lutaml::Xml::Namespace raise ArgumentError, "namespace must be an XmlNamespace class, got #{ns_class.class}" end warn_class_level_namespace_usage(ns_class) @namespace_class = ns_class end @namespace_class end |
#namespace_prefix ⇒ String?
Get the default namespace prefix for this Model
43 44 45 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 43 def namespace_prefix @namespace_class&.prefix_default end |
#namespace_uri ⇒ String?
Get the namespace URI for this Model
36 37 38 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 36 def namespace_uri @namespace_class&.uri end |
#post_process_mapping(format) ⇒ Object
XML-specific post-processing after mapping DSL evaluation
119 120 121 122 123 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 119 def post_process_mapping(format) return super unless format == :xml check_sort_configs! end |
#pre_deserialize_hook(format, register) ⇒ Object
XML-specific pre-deserialization: resolve XML mapping imports
129 130 131 132 133 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 129 def pre_deserialize_hook(format, register) return super unless format == :xml mappings[:xml]&.ensure_mappings_imported!(register) end |
#pre_serialize_hook(format, register) ⇒ Object
XML-specific pre-serialization: resolve XML mapping imports
199 200 201 202 203 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 199 def pre_serialize_hook(format, register) return super unless format == :xml mappings[:xml]&.ensure_mappings_imported!(register) end |
#prepare_to_options(format, instance, options) ⇒ Hash
XML-specific options preparation for serialization
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 159 def (format, instance, ) return super unless format == :xml [:mapper_class] = self # Handle prefix option for XML if .key?(:prefix) prefix_option = [:prefix] mappings_for(:xml) case prefix_option when true [:use_prefix] = true when String [:use_prefix] = prefix_option when false, :default, nil [:use_prefix] = false end .delete(:prefix) end # Apply namespace prefix overrides for XML format if [:namespaces] = apply_namespace_overrides() end # Retrieve stored declaration plan from model instance for namespace preservation if instance.is_a?(Lutaml::Model::Serialize) && !.key?(:stored_xml_declaration_plan) stored_plan = instance.import_declaration_plan [:stored_xml_declaration_plan] = stored_plan if stored_plan end end |
#process_mapping(format, *args, &block) ⇒ Object
Override process_mapping for XML format to handle mapping class inheritance.
When xml SomeMapping is called with a mapping class argument,
inherits mappings from the class instead of using a DSL block.
108 109 110 111 112 113 114 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 108 def process_mapping(format, *args, &block) if format == :xml && args.any? && args.first.is_a?(Class) && args.first < Lutaml::Xml::Mapping process_xml_mapping_class_inheritance(args.first, &block) else super end end |
#validate_document(format, doc, options, register) ⇒ Object
XML-specific document validation: root mapping, encoding, doctype
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 141 def validate_document(format, doc, , register) return super unless format == :xml valid = root?(register) || [:from_collection] raise Lutaml::Model::TypeOnlyMappingError.new(self) unless valid [:encoding] = doc.encoding if doc.is_a?(Lutaml::Xml::Document) && doc.doctype [:doctype] = doc.doctype end end |
#validate_xml(xml) ⇒ Array<Lutaml::Xml::Error::SchemaValidationError>
Validate a raw XML string against the configured schemas without instantiating a model — the explicit input-side counterpart to the validate/validate! output-side check.
84 85 86 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 84 def validate_xml(xml) XsdValidator.validate(xml, xml_schema_paths) end |
#validate_xml!(xml) ⇒ Object
90 91 92 93 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 90 def validate_xml!(xml) errors = validate_xml(xml) raise Lutaml::Model::ValidationError.new(errors) if errors.any? end |
#validate_xml_with(*paths) ⇒ Object
Configure one or more XSD schemas that the model's generated XML must conform to. Checked during validate/validate! (issue #264). Repeated calls (including in subclasses) append.
Relative paths resolve against the file that declares the macro, so a model works regardless of the process working directory.
55 56 57 58 59 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 55 def validate_xml_with(*paths) base = File.dirname(caller_locations(1, 1).first.path) @own_xml_schema_paths = own_xml_schema_paths + paths.flatten.map { |path| File.(path.to_s, base) } end |
#xml_schema_paths ⇒ Array<String>
All configured XSD schema paths, parent-first: inherited paths come before paths declared on this class.
65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 65 def xml_schema_paths # Type check, not a probe: every Serializable carries the # class method; a plain (non-Serializable) superclass ends # the chain. inherited = if superclass.is_a?(Class) && superclass.include?(Lutaml::Model::Serialize) superclass.xml_schema_paths else [] end inherited + own_xml_schema_paths end |