如何确保 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")
在我看来,没有办法确保 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")