From 9ba15e378a601cc15e2625748fb1e8c3750c82b6 Mon Sep 17 00:00:00 2001 From: Lukas Bischof Date: Fri, 14 Oct 2022 21:45:09 +0200 Subject: [PATCH] Provide option to strip attributes for empty tags Introduce strip_attributes_of_empty_tags option which can be set to have consistent return values for empty tags by neglecting their attributes. --- lib/nori.rb | 19 ++++++++------- lib/nori/xml_utility_node.rb | 4 ++- spec/nori/nori_spec.rb | 47 ++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/lib/nori.rb b/lib/nori.rb index ba55215..d404dd2 100644 --- a/lib/nori.rb +++ b/lib/nori.rb @@ -15,15 +15,16 @@ def self.hash_key(name, options = {}) def initialize(options = {}) defaults = { - :strip_namespaces => false, - :delete_namespace_attributes => false, - :convert_tags_to => nil, - :convert_attributes_to => nil, - :empty_tag_value => nil, - :advanced_typecasting => true, - :convert_dashes_to_underscores => true, - :scrub_xml => true, - :parser => :nokogiri + :strip_namespaces => false, + :delete_namespace_attributes => false, + :convert_tags_to => nil, + :convert_attributes_to => nil, + :empty_tag_value => nil, + :advanced_typecasting => true, + :convert_dashes_to_underscores => true, + :scrub_xml => true, + :strip_attributes_of_empty_tags => false, + :parser => :nokogiri } validate_options! defaults.keys, options.keys diff --git a/lib/nori/xml_utility_node.rb b/lib/nori/xml_utility_node.rb index 63d74a4..cf55ff4 100644 --- a/lib/nori/xml_utility_node.rb +++ b/lib/nori/xml_utility_node.rb @@ -170,7 +170,9 @@ def to_hash out.merge!( k => v.map{|e| e.to_hash[k]}) end end - out.merge! prefixed_attributes unless attributes.empty? + if !(@options[:strip_attributes_of_empty_tags] && @children.empty?) && attributes.any? + out.merge! prefixed_attributes + end out = out.empty? ? @options[:empty_tag_value] : out end diff --git a/spec/nori/nori_spec.rb b/spec/nori/nori_spec.rb index e673722..d87524f 100644 --- a/spec/nori/nori_spec.rb +++ b/spec/nori/nori_spec.rb @@ -640,6 +640,53 @@ expect(parse(' ')).to eq({}) end + context "with strip_attributes_of_empty_tags set to true" do + it "should strip attributes of empty tags" do + expect(parse('', strip_attributes_of_empty_tags: true)).to eq({ 'foo' => nil }) + end + + it "should strip attributes only of empty tags also in a nested structure" do + xml = <<-XML + + + + + actual content + + XML + + expect(parse(xml, strip_attributes_of_empty_tags: true)).to match({ + "content" => { + "foo" => [nil, nil, nil, be_a(Nori::StringWithAttributes).and(eq("actual content"))], + } + }) + end + end + + context "with strip_attributes_of_empty_tags set to false" do + it "should not strip any attributes" do + xml = <<-XML + + + + + actual content + + XML + + expect(parse(xml, strip_attributes_of_empty_tags: false)).to match({ + "content" => { + "foo" => [ + nil, + {"@bar"=>"baz"}, + {"@bar"=>"baz", "@bar2"=>"baz2"}, + be_a(Nori::StringWithAttributes).and(eq("actual content")) + ], + } + }) + end + end + end end