to_xml в Hash со строковым массивом завершается с ошибкой Не все элементы отвечают to_xml - PullRequest
0 голосов
/ 02 января 2011

to_xml в Hash с массивом строк завершается с ошибкой Не все элементы реагируют на 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'

Есть ли предпочтительный способ изменить поведение Hash.to_xml для возврата

<records>
 <record>001</record>
 <record>002</record>
</records>

...

Ответы [ 2 ]

4 голосов
/ 03 января 2011

Как и сказал DigitalRoss, в Ruby 1.9 это работает из коробки с ActiveSupport 3:

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), вы можете получить аналогичныеповедение в Ruby 1.8 с ActiveSupport 2.3.9:

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.

4 голосов
/ 02 января 2011

Нет, потому что "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 отдельно от структуры данных.

...