From 7124acea4569f2c31ea904fe8400b2a690d3eb0e Mon Sep 17 00:00:00 2001 From: suleman-uzair Date: Tue, 5 Nov 2024 17:00:48 +0500 Subject: [PATCH 1/2] added parent namespace for xml mappings --- lib/lutaml/model/attribute.rb | 3 +- lib/lutaml/model/serialize.rb | 13 ++++--- lib/lutaml/model/xml_mapping_rule.rb | 4 +- spec/lutaml/model/namespace_spec.rb | 57 ++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 spec/lutaml/model/namespace_spec.rb diff --git a/lib/lutaml/model/attribute.rb b/lib/lutaml/model/attribute.rb index f268394..eb544dd 100644 --- a/lib/lutaml/model/attribute.rb +++ b/lib/lutaml/model/attribute.rb @@ -200,11 +200,10 @@ def serialize(value, format, options = {}) def cast(value, format, options = {}) value ||= [] if collection? - instance = options[:instance] if value.is_a?(Array) value.map do |v| - cast(v, format, instance: instance) + cast(v, format, options) end elsif type <= Serialize && value.is_a?(Hash) type.apply_mappings(value, format, options) diff --git a/lib/lutaml/model/serialize.rb b/lib/lutaml/model/serialize.rb index 4a357f9..66a4995 100644 --- a/lib/lutaml/model/serialize.rb +++ b/lib/lutaml/model/serialize.rb @@ -310,6 +310,7 @@ def apply_mappings(doc, format, options = {}) def apply_xml_mapping(doc, instance, options = {}) return instance unless doc + options[:default_namespace] = mappings_for(:xml)&.namespace_uri if options[:default_namespace].nil? mappings = mappings_for(:xml).mappings if doc.is_a?(Array) @@ -340,14 +341,14 @@ def apply_xml_mapping(doc, instance, options = {}) doc.node.inner_xml elsif rule.content_mapping? doc["text"] - elsif doc.key_exist?(rule.namespaced_name) - doc.fetch(rule.namespaced_name) + elsif doc.key_exist?(rule.namespaced_name(options[:default_namespace])) + doc.fetch(rule.namespaced_name(options[:default_namespace])) else defaults_used << rule.to rule.to_value_for(instance) end - value = normalize_xml_value(value, rule) + value = normalize_xml_value(value, rule, options) rule.deserialize(instance, value, attributes, self) end @@ -388,7 +389,7 @@ def apply_hash_mapping(doc, instance, format, _options = {}) instance end - def normalize_xml_value(value, rule) + def normalize_xml_value(value, rule, options = {}) attr = attribute_for_rule(rule) value = [value].compact if attr&.collection? && !value.is_a?(Array) @@ -405,11 +406,11 @@ def normalize_xml_value(value, rule) return value unless cast_value?(attr, rule) + options.merge(caller_class: self, mixed_content: rule.mixed_content) attr.cast( value, :xml, - caller_class: self, - mixed_content: rule.mixed_content, + options, ) end diff --git a/lib/lutaml/model/xml_mapping_rule.rb b/lib/lutaml/model/xml_mapping_rule.rb index f8668c5..5b6601e 100644 --- a/lib/lutaml/model/xml_mapping_rule.rb +++ b/lib/lutaml/model/xml_mapping_rule.rb @@ -73,7 +73,7 @@ def prefixed_name end end - def namespaced_name + def namespaced_name(parent_namespace = nil) if name == "lang" "#{prefix}:#{name}" elsif namespace_set? || @attribute @@ -81,7 +81,7 @@ def namespaced_name elsif default_namespace "#{default_namespace}:#{name}" else - name + [parent_namespace, name].compact.join(":") end end diff --git a/spec/lutaml/model/namespace_spec.rb b/spec/lutaml/model/namespace_spec.rb new file mode 100644 index 0000000..2579c39 --- /dev/null +++ b/spec/lutaml/model/namespace_spec.rb @@ -0,0 +1,57 @@ +require "spec_helper" + +module NamespaceSpec + class NestedChild < Lutaml::Model::Serializable + attribute :name, :string + + xml do + root "NestedChild" + + map_element :name, to: :name + end + end + + class Child < Lutaml::Model::Serializable + attribute :nested_child, NestedChild + + xml do + root "NestedChild" + + map_element :NestedChild, to: :nested_child + end + end + + class Parent < Lutaml::Model::Serializable + attribute :child, Child + + xml do + root "Parent" + namespace "https://abc.com" + + map_element :Child, to: :child + end + end +end + +RSpec.describe "NamespaceSpec" do + let(:parsed) { NamespaceSpec::Parent.from_xml(xml) } + let(:xml) do + <<~XML + + + + Rogger moore + + + + XML + end + + it "parses nested child using root namespace" do + expect(parsed.child.nested_child.name).to eq("Rogger moore") + end + + it "round-trips xml" do + expect(parsed.to_xml).to be_equivalent_to(xml) + end +end From 1c9806b6b7dcb625257e58b65130e13e4c8b6013 Mon Sep 17 00:00:00 2001 From: suleman-uzair Date: Tue, 5 Nov 2024 17:42:18 +0500 Subject: [PATCH 2/2] fix: model inheritence --- lib/lutaml/model/serialize.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lutaml/model/serialize.rb b/lib/lutaml/model/serialize.rb index 66a4995..d109e6a 100644 --- a/lib/lutaml/model/serialize.rb +++ b/lib/lutaml/model/serialize.rb @@ -35,7 +35,7 @@ def inherited(subclass) subclass.instance_variable_set(:@attributes, Utils.deep_dup(@attributes)) subclass.instance_variable_set(:@mappings, Utils.deep_dup(@mappings)) - subclass.instance_variable_set(:@model, subclass) + subclass.instance_variable_set(:@model, @model || subclass) end def model(klass = nil)