如何确保 REXML::Formatters::Pretty 使用 \t 而不是 white-space 进行缩进

How to make sure REXML::Formatters::Pretty uses \t instead of white-space for indentation

在我看来,没有办法确保 REXML::Formatters::Pretty 可以使用 \t 而不是 white-space 作为 XML 树中的缩进策略。我唯一能做的就是定义每个缩进级别使用多少白色 space。

我错了吗?

不确定为什么 REXML 库不为您提供此选项,因为它肯定可以在内部支持它,但您可以推出自己的格式化程序:

module REXML
   module Formatters
     class Prettier < Pretty
        attr_accessor :style
        def initialize(indentation = 2, indent_style =" ", ie_hack=false)
           @style = indent_style
           super(indentation,ie_hack)
        end
        protected  

        def write_element(node, output)
          output << style*@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 << style*@level
            end
            output << "</#{node.expanded_name}"
          end
          output << ">"
        end

        def write_text( node, output )
          s = node.to_s()
          s.gsub!(/\s/,' ')
          s.squeeze!(" ")
          s = wrap(s, @width - @level)
          s = indent_text(s, @level, style, true)
          output << (style*@level + s)
        end

        def write_comment( node, output)
          output << style * @level
          Default.instance_method(:write_comment).bind(self).call(node,output)
        end

        def write_cdata( node, output)
          output << style * @level
          Default.instance_method(:write_cdata).bind(self).call(node,output)
        end
     end
   end
 end

现在您可以指定自己的缩进级别和缩进样式,例如

require "rexml/document"
include REXML
string = <<EOF
  <mydoc>
    <someelement attribute="nanoo">Text, text, text</someelement>
  </mydoc>
EOF
doc = Document.new string

f = Formatters::Prettier(2,"h")
f.write(doc,$stdout)
#<mydoc>
#hh<someelement attribute='nanoo'>
#hhhhText, text, text
#hh</someelement>
#</mydoc>

我使用 "h" 来展示缩进是如何工作的,因为 \t 不会出现在 $stdout 中,但在你的情况下,这将是

f = Formatters::Prettier(1,"\t")