class REXML::Formatters::Pretty

以美观的方式打印 XML 文档。这会破坏文本节点中的空格,并插入回车符和缩进。

待办事项:添加一个选项,将属性打印在新行上

属性

compact[RW]

如果 compact 设置为 true,则格式化程序将尝试使用尽可能少的空间

width[RW]

页面的宽度。用于格式化文本

公共类方法

new( indentation=2, ie_hack=false ) 点击以切换源代码

创建一个新的漂亮打印机。

output

一个实现 ‘<<(String)’ 的对象,输出将写入到该对象。

indentation

一个大于 0 的整数。每一级的缩进将是此数字的空格数。如果此值 < 1,则此对象的行为未定义。默认为 2。

ie_hack

如果为 true,打印机将在关闭空标记之前插入空格,从而允许 Internet Explorer 的 XML 解析器正常工作。默认为 false。

# File rexml-3.4.0/lib/rexml/formatters/pretty.rb, line 30
def initialize( indentation=2, ie_hack=false )
  @indentation = indentation
  @level = 0
  @ie_hack = ie_hack
  @width = 80
  @compact = false
end

受保护的实例方法

write_cdata( node, output) 点击以切换源代码
# File rexml-3.4.0/lib/rexml/formatters/pretty.rb, line 102
def write_cdata( node, output)
  output << ' ' * @level
  super
end
write_comment( node, output) 点击以切换源代码
# File rexml-3.4.0/lib/rexml/formatters/pretty.rb, line 97
def write_comment( node, output)
  output << ' ' * @level
  super
end
write_document( node, output ) 点击以切换源代码
# File rexml-3.4.0/lib/rexml/formatters/pretty.rb, line 107
def write_document( node, output )
  # Ok, this is a bit odd.  All XML documents have an XML declaration,
  # but it may not write itself if the user didn't specifically add it,
  # either through the API or in the input document.  If it doesn't write
  # itself, then we don't need a carriage return... which makes this
  # logic more complex.
  node.children.each { |child|
    next if child.instance_of?(Text)
    unless child == node.children[0] or child.instance_of?(Text) or
      (child == node.children[1] and !node.children[0].writethis)
      output << "\n"
    end
    write( child, output )
  }
end
write_element(node, output) 点击以切换源代码
# File rexml-3.4.0/lib/rexml/formatters/pretty.rb, line 39
def write_element(node, output)
  output << ' '*@level
  output << "<#{node.expanded_name}"

  node.attributes.each_attribute do |attr|
    output << " "
    attr.write( output )
  end unless node.attributes.empty?

  if node.children.empty?
    if @ie_hack
      output << " "
    end
    output << "/"
  else
    output << ">"
    # If compact and all children are text, and if the formatted output
    # is less than the specified width, then try to print everything on
    # one line
    skip = false
    if compact
      if node.children.inject(true) {|s,c| s & c.kind_of?(Text)}
        string = +""
        old_level = @level
        @level = 0
        node.children.each { |child| write( child, string ) }
        @level = old_level
        if string.length < @width
          output << string
          skip = true
        end
      end
    end
    unless skip
      output << "\n"
      @level += @indentation
      node.children.each { |child|
        next if child.kind_of?(Text) and child.to_s.strip.length == 0
        write( child, output )
        output << "\n"
      }
      @level -= @indentation
      output << ' '*@level
    end
    output << "</#{node.expanded_name}"
  end
  output << ">"
end
write_text( node, output ) 点击以切换源代码
# File rexml-3.4.0/lib/rexml/formatters/pretty.rb, line 88
def write_text( node, output )
  s = node.to_s()
  s.gsub!(/\s/,' ')
  s.squeeze!(" ")
  s = wrap(s, @width - @level)
  s = indent_text(s, @level, " ", true)
  output << (' '*@level + s)
end

私有实例方法

indent_text(string, level=1, style="\t", indentfirstline=true) 点击以切换源代码
# File rexml-3.4.0/lib/rexml/formatters/pretty.rb, line 124
def indent_text(string, level=1, style="\t", indentfirstline=true)
  return string if level < 0
  string.gsub(/\n/, "\n#{style*level}")
end
wrap(string, width) 点击以切换源代码
# File rexml-3.4.0/lib/rexml/formatters/pretty.rb, line 129
def wrap(string, width)
  parts = []
  while string.length > width and place = string.rindex(' ', width)
    parts << string[0...place]
    string = string[place+1..-1]
  end
  parts << string
  parts.join("\n")
end