我尝试使用REXML生成这样的XML
<root>
<add key='foo' value='bar'/>
</root>但是我得到的是(注意键/值的顺序)
<root>
<add value='bar' key='foo'/>
</root>代码:
require 'rexml/document'
include REXML
doc = Document.new
doc.add_element('root')
el = doc.root.add_element('add')
el.add_attribute('key', 'foo')
el.add_attribute('value', 'bar')
puts doc如果我写:
el.add_attribute('key', 'foo')
el.add_attribute('value', 'bar')或
el.add_attribute('value', 'bar')
el.add_attribute('key', 'foo')结果是一样的。看起来REXML使用了一些字典来保存属性...
我可以强制执行所需的顺序:键/值吗?
发布于 2009-02-22 11:19:50
在XML中,属性的顺序并不重要。如果您有一些重要的XML处理代码,那么我认为代码是有buggy的。
从XML spec here中,请注意短语:“请注意,开始标记或空元素标记中属性规范的顺序并不重要”。
在回答你关于你是否可以强制执行某个命令的具体问题时,我不这么认为。我实际上从来没有尝试过这样做(因为这是不必要的),但REXML人员似乎不太可能浪费时间实现这样一个非特性:-)。由于键/值对是以散列形式存储的,因此它们的顺序很可能是随机的(从键的字母顺序可以看出)。
当然,由于Ruby附带了REXML的源代码,您可以(如果迫不及待地)用您自己的版本(REXML2 ?)替换或扩充所包含的副本。
因为您正在做一个简单的puts,所以它可能使用了漂亮的格式化程序,所以请检查src/rexml/formatters/pretty.rb中执行"node.attributes.each_attribute do |attr|“的write_element代码的开头-您可能会发现它就像在处理元素之前对列表进行排序一样简单。
您可能还想建议开发人员(请参阅here获取邮件列表或here获取错误报告和增强请求),建议他们在将来的版本中选择此选项,但如果我是他们,我会简单地说这是不必要的。
发布于 2011-10-22 01:56:20
您可以尝试使用ad-hoc REXML::Formatter,而不涉及REXML源。A post on the ruby-talk ml建议使用以下代码:
class OrderedAttributes < REXML::Formatters::Pretty
def write_element(elm, out)
att = elm.attributes
class <<att
alias _each_attribute each_attribute
def each_attribute(&b)
to_enum(:_each_attribute).sort_by {|x| x.name}.each(&b)
end
end
super(elm, out)
end
end
fmt = OrderedAttributes.new
fmt.write(doc, $stdout)发布于 2009-02-22 21:46:27
如果您正在修改一个配置文件,并且格式化很重要,那么通过REXML读取它可能更容易,而通过regexps进行修改可能更容易。
此外,请记住,通过REXML生成大量XML的速度非常慢。我有一个站点,它必须读取和写入大量XML;我发现对于读取,REXML已经足够快了,但是对于写入,我必须使用libxml。实际上,libxml安装起来太麻烦了,而且它的ruby库又很不成熟,所以我最终使用erb来替换已经编写好的XML文档的某些部分。
祝好运!
https://stackoverflow.com/questions/574724
复制相似问题