2

我正在使用 REXML 创建 XML 文档

File.open(xmlFilename,'w') do |xmlFile|
    xmlDoc = Document.new
    # add stuff to the document...
    xmlDoc.write(xmlFile,4)
end

一些元素包含相当多的参数,因此,相应的行可能会变得很长。如果它们的长度超过 166 个字符,REXML 将插入一个换行符。这当然仍然是完全有效的 XML,但我的工作流程包括一些差异和合并,如果每个元素都包含在一行中,则效果最好。

那么,有没有办法让 REXML插入这些换行符?

编辑:我最终通过tidy推送完成的 XML 文件作为脚本的最后一步。如果有人知道更好的方法来做到这一点,我仍然会很感激。

4

2 回答 2

3

正如 Ryan Calhoun 在他之前的回答中所说,REXML 使用 80 作为其换行线长度。我很确定这是一个错误(尽管我现在找不到错误报告)。我能够通过覆盖 Formatters::Pretty 类的 write_text 方法来修复它,以便它使用可配置的 @width 属性而不是硬编码的 80。

require "rubygems"
require "rexml/document"
include REXML

long_xml = "<root><tag>As Ryan Calhoun said in his previous answer, REXML uses 80 as its wrap line length.  I'm pretty sure this is a bug (although I couldn't find a bug report just now).  I was able to *fix* it by overwriting the Formatters::Pretty class's write_text method.</tag></root>"

xml = Document.new(long_xml)

#fix bug in REXML::Formatters::Pretty
class MyPrecious < REXML::Formatters::Pretty
    def write_text( node, output )
        s = node.to_s()
        s.gsub!(/\s/,' ')
        s.squeeze!(" ")

        #The Pretty formatter code mistakenly used 80 instead of the @width variable
        #s = wrap(s, 80-@level)
        s = wrap(s, @width-@level)

        s = indent_text(s, @level, " ", true)
        output << (' '*@level + s)
    end
end

printer = MyPrecious.new(5)
printer.width = 1000
printer.compact = true
printer.write(xml, STDOUT)
于 2010-11-19T18:53:26.783 回答
1

简短的回答:是和不是。

REXML 根据您为 指定的值使用不同的格式化程序indent。如果您保留默认值 -1,它将使用REXML::Formatters::Default. 如果你给它一个像 4 这样的值,它使用REXML::Formatters::Pretty. 在处理文本(不是标签或属性)时,漂亮的格式化程序确实具有换行的逻辑(尽管它看起来像是在 80 而非 166 处换行)。例如,内容

<p> a paragraph tag </p>

将被包装为 80 个字符,但是

<a-tag with='a' long='list' of='attributes'/>

不会被包裹。

无论如何,80 是硬编码的rexml/formatters/pretty.rb,不可配置。如果您使用没有缩进的默认格式化程序,那么它主要只是一个没有添加换行符的原始转储。您可以尝试传递格式化程序(请参阅 文​​档Document.write),但它在某些版本的 ruby​​ 中已损坏,并且可能需要代码破解。无论如何,这可能不是你想要的。


您可以尝试Builder::XmlMarkup从 builder gem 中查看。

于 2010-11-18T03:59:28.383 回答