diff --git a/lib/rexml/formatters/default.rb b/lib/rexml/formatters/default.rb index 811b2ff3..8c8b73b5 100644 --- a/lib/rexml/formatters/default.rb +++ b/lib/rexml/formatters/default.rb @@ -62,27 +62,32 @@ def write_document( node, output ) node.children.each { |child| write( child, output ) } end + # Descendants are walked with an explicit stack instead of recursion so + # that a deeply nested document doesn't exhaust the machine stack. A + # String on the stack is an end tag waiting to be written. def write_element( node, output ) - output << "<#{node.expanded_name}" - - node.attributes.to_a.map { |a| - Hash === a ? a.values : a - }.flatten.sort_by {|attr| attr.name}.each do |attr| - output << " " - attr.write( output ) - end unless node.attributes.empty? - - if node.children.empty? - output << " " if @ie_hack - output << "/" - else - output << ">" - node.children.each { |child| - write( child, output ) - } - output << "" + else + output << ">" + stack << "" + stack.concat(children.reverse) + end + else + write( current, output ) + end end - output << ">" end def write_text( node, output ) @@ -111,6 +116,17 @@ def write_instruction( node, output ) end output << Instruction::STOP end + + private + def write_element_attributes( node, output ) + return if node.attributes.empty? + node.attributes.to_a.map { |a| + Hash === a ? a.values : a + }.flatten.sort_by {|attr| attr.name}.each do |attr| + output << " " + attr.write( output ) + end + end end end end