ATTRIBUTE_VALUE_TESTS = %w( & < > " ' & < > " ' & < > " ' & < > " ' &amp; &lt; &gt; &quot; &apos; &amp; &lt; &gt; &quot; &apos; &amp; &lt; &gt; &quot; &apos; ) require 'rexml/document' if REXML::Document.new("").to_s.index('&amp;') # http://www.germane-software.com/projects/rexml/ticket/122 unless ARGV.include?("mp") module REXML class Text ENT_OR_NUM_REF = /&(?!#?#{Entity::NAME};)/ def Text::normalize( input, doctype=nil, entity_filter=nil ) copy = input # Doing it like this rather than in a loop improves the speed copy = copy.gsub( ENT_OR_NUM_REF, '&' ) # copy = copy.gsub( "&", "&" ) if doctype # Replace all ampersands that aren't part of an entity doctype.entities.each_value do |entity| copy = copy.gsub( entity.value, "&#{entity.name};" ) if entity.value and not( entity_filter and entity_filter.include?(entity) ) end else # Replace all ampersands that aren't part of an entity DocType::DEFAULT_ENTITIES.each_value do |entity| copy = copy.gsub(entity.value, "&#{entity.name};" ) end end copy end end end end end require 'test/unit' class RoundTripAttributeValueTests < Test::Unit::TestCase ATTRIBUTE_VALUE_TESTS.each_with_index do |attr, index| define_method "test_serializer_#{index}" do doc = REXML::Document.new("") doc.root.attributes['a'] = attr assert_equal attr, REXML::Document.new(doc.to_s).root.attributes['a'] end unless ARGV.include?("nots") next if %w{< &}.include? attr # illegal inside attributes define_method "test_parser_#{index}" do element = "" element = "" if attr == "'" doc = REXML::Document.new(element) if attr.length == 1 # special characters are replaced with an entity reference assert_match //, doc.to_s else # everything else should be left as is assert_equal element, doc.to_s end end unless ARGV.include?("notp") end end