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) ⇒ 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) ⇒ 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.
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 205 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
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 226 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) ⇒ Object
Override choice to set format: :xml so Choice knows which format it belongs to.
92 93 94 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 92 def choice(min: 1, max: 1, format: :xml, &) 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
115 116 117 118 119 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 115 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
125 126 127 128 129 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 125 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
195 196 197 198 199 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 195 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
155 156 157 158 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 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 155 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) ⇒ 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.
104 105 106 107 108 109 110 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 104 def process_mapping(format, *args, &) if format == :xml && args.any? && args.first.is_a?(Class) && args.first < Lutaml::Xml::Mapping process_xml_mapping_class_inheritance(args.first, &) else super end end |
#validate_document(format, doc, options, register) ⇒ Object
XML-specific document validation: root mapping, encoding, doctype
137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 137 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.
80 81 82 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 80 def validate_xml(xml) XsdValidator.validate(xml, xml_schema_paths) end |
#validate_xml!(xml) ⇒ Object
86 87 88 89 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 86 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 |
# File 'lib/lutaml/xml/serialization/format_conversion.rb', line 65 def xml_schema_paths inherited = if superclass.respond_to?(:xml_schema_paths) superclass.xml_schema_paths else [] end inherited + own_xml_schema_paths end |