Hash上的to_xml与字符串数组失败,并非所有元素都响应to_xml

时间:2011-01-02 06:25:51

标签: ruby-on-rails ruby jruby

带有字符串数组的Hash上的

to_xml失败,并非所有元素都响应to_xml

 >>r={"records"=>["001","002"]}

 => {"records"=>["001", "002"]}

 >>r.to_xml

 RuntimeError: Not all elements respond
 to to_xml   from
/jruby/../1.8/gems/activesupport2.3.9/lib/active_support/core_ext/array/conversions.rb:163:in `to_xml'

是否有一种rails更改Hash.to_xml行为以返回

的首选方法
<records>
 <record>001</record>
 <record>002</record>
</records>

...

2 个答案:

答案 0 :(得分:4)

不,因为"001""002"无法知道如何成为<record>001</record>。这些字符串就是:字符串。他们不知道它们是在带有数组的散列中使用,更不用说这些字符串共享一个密钥,需要单独化。

您可以执行以下操作:

record = Struct.new(:value) do
  def to_xml
    "<record>#{value}</record>"
  end
end

r = { "records" => [ record.new("001"), record.new("002") ] }
r.to_xml

或者,使用Builder之类的工具将xml与数据结构分开。

答案 1 :(得分:4)

就像DigitalRoss所说,这似乎在带有ActiveSupport 3的Ruby 1.9中开箱即用:

ruby-1.9.2-p0 > require 'active_support/all'
 => true 
ruby-1.9.2-p0 > r={"records"=>["001","002"]}
 => {"records"=>["001", "002"]} 
ruby-1.9.2-p0 > puts r.to_xml
<?xml version="1.0" encoding="UTF-8"?>
<hash>
  <records type="array">
    <record>001</record>
    <record>002</record>
  </records>
</hash>

至少在MRI上(你使用的是JRuby),你可以在使用ActiveSupport 2.3.9的Ruby 1.8上获得类似的行为:

require 'rubygems'
gem 'activesupport', '~>2.3'
require 'active_support'
class String
  def to_xml(options = {})
    root = options[:root] || 'string'
    options[:builder].tag! root, self
  end
end

哪个给你......

ruby-1.8.7-head > load 'myexample.rb'
 => true 
ruby-1.8.7-head > r={"records"=>["001","002"]}
 => {"records"=>["001", "002"]} 
ruby-1.8.7-head > puts r.to_xml
<?xml version="1.0" encoding="UTF-8"?>
<hash>
  <records type="array">
    <record>001</record>
    <record>002</record>
  </records>
</hash>

请注意,我的代码不适用于Ruby 1.9和ActiveRecord 3。