# Array to\_xml

**URL:** <https://www.ruby-forum.com/t/array-to-xml/150299>\
**Category:** Rails\
**Created:** [October 7, 2008, 3:31am UTC](https://www.ruby-forum.com/t/array-to-xml/150299 "2008-10-07T03:31:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@sam](https://www.ruby-forum.com/u/sam)\
**Post date:** [October 7, 2008, 3:31am UTC](https://www.ruby-forum.com/t/array-to-xml/150299/1 "2008-10-07T03:31:00Z")

</div>

Why is it that…

{code}

> > myarray = [“one”]  
> > =\> [“one”]
> 
> > myarray.to\_xml  
> > RuntimeError: Not all elements respond to to\_xml  
> > from /foo/vendor/rails/activerecord/lib/…/…/activesupport/lib/  
> > active\_support/core\_ext/array/conversions.rb:62:in `to\_xml’  
> > from (irb):94
> 
> >

{code}

… however …

{code}

> > myarray2 = [{:one =\> “onevalue”}]  
> > =\> [{:one=\>“onevalue”}]
> 
> > myarray2.to\_xml  
> > =\> "\<?xml version=\"1.0\" encoding=\"UTF-8\"?\>\n\<records type="array  
> > “\>\n \n onevalue\n \n\n”
> 
> >

{code}

Is there a way I can convert an array to xml without having to wrap  
each element in a hash???

---

<div class="post-metadata">

**Author:** ![sam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@sam](https://www.ruby-forum.com/u/sam)\
**Post date:** [October 7, 2008, 3:58am UTC](https://www.ruby-forum.com/t/array-to-xml/150299/2 "2008-10-07T03:58:33Z")

</div>

What do you want the resulting XML to look like? Usually XML has name/  
value format.

You can do this:

class Symbol  
def to\_xml  
{self =\> self.to\_s}.to\_xml  
end  
end

and then you can call :hello.to\_xml

=\> hello

That’s a little dangerous, though, and it may turn out that you should  
rethink the XML schema, and use hashes in general.

---

<div class="post-metadata">

**Author:** ![sam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@sam](https://www.ruby-forum.com/u/sam)\
**Post date:** [October 7, 2008, 4:16am UTC](https://www.ruby-forum.com/t/array-to-xml/150299/3 "2008-10-07T04:16:41Z")

</div>

On 7 Oct 2008, at 02:30, Sam wrote:

> from (irb):94  
> “\>\n \n onevalue\n \n\n”
> 
> > >

In a nutshell, strings don’t have a to\_xml method, but hashes do.

> {code}
> 
> Is there a way I can convert an array to xml without having to wrap  
> each element in a hash???

What do you want the output to look like ?

Fred

---

<div class="post-metadata">

**Author:** ![sam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@sam](https://www.ruby-forum.com/u/sam)\
**Post date:** [October 7, 2008, 7:31am UTC](https://www.ruby-forum.com/t/array-to-xml/150299/4 "2008-10-07T07:31:33Z")

</div>

The standard thing to do is put classes in there instead of strings,  
so each error would be an instance of class Error, which would respond  
to to\_xml with foo or whatever. See, for example, Pat  
Maddox’s Blog:

> **[eli.st](http://evang.eli.st/blog/2007/2/22/my-rails-gotcha-custom-to_xml-in-a-hash-or-array)**
>
> This domain may be for sale!

If you are worried about reversibility, you can change active\_support  
\core\_ext\array\conversions so that the to\_xml method looks like this  
at the top:

```
      options[:root] ||= all? { |e| e.is_a?(first.class) &&

```

first.class.to\_s != “Hash” } ? first.class.to\_s.underscore.pluralize :  
“records”  
map!{|e| (e.class.name == “String”) ? {options[:root].to\_sym  
=\> e} : e}

```
      raise "Not all elements respond to to_xml" unless all? { |e|

```

e.respond\_to? :to\_xml }

```
      options[:children] ||= options[:root].singularize
      options[:indent] ||= 2
      options[:builder] ||= Builder::XmlMarkup.new(:indent =>

```

options[:indent])

The XML you get back isn’t pretty, but it doesn’t crash:

\<?xml version=\"1.0\" encoding=\"UTF-8\"?\> foo bar 

Cleaning it up more than this might be a bit tricky. If this is  
something a lot of people would like, I’d look at it some more, but I  
think it’s pretty unusual, and it’s usually easier to use objects.

-Michael

---

<div class="post-metadata">

**Author:** ![sam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@sam](https://www.ruby-forum.com/u/sam)\
**Post date:** [October 7, 2008, 4:55am UTC](https://www.ruby-forum.com/t/array-to-xml/150299/5 "2008-10-07T04:55:16Z")

</div>

I’m wanting something like…

 foo bar

I find it really interesting that a Rails controller will accept xml  
like…

`one``two`

… and transform it into a hash…

{ :process\_codes =\> { :code =\> [“one”, “two”] } }

… but will not go back the other way when I want to convey errors…

{ :errors =\> { :error =\> [“foo”, “bar”] } }

---

<div class="post-metadata">

**Author:** ![sam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/5f9b8f/32.png) [@sam](https://www.ruby-forum.com/u/sam)\
**Post date:** [October 7, 2008, 7:55am UTC](https://www.ruby-forum.com/t/array-to-xml/150299/6 "2008-10-07T07:55:35Z")

</div>

Thanks Michael.

I’ve taken the easy (and hacky) way out by using an  
ActiveRecord::Errors object which is transformed implements to\_xml  
quite nicely.  
The hacky bit is that I’m not always adding an error that coincides  
with an attribute of the model I’m exploiting … eg,

errors.add( :code, “#{code} is not found” )

…when my model object doesn’t actually have a “code” attribute.  
Also… under some scenarios I may not have a model instance at all  
but need to create one in order to gain access to the to\_xml friendly  
Errors object by doing something like…

errors = Player.new.errors

… which is of course hacky, but more readily thrown together than  
implementing a custom errors class or modifying the conversions.rb  
The Errors object is also nice because it allows multiple errors with  
the same key…

errors.add( :code, “#{code} is not found” )  
errors.add( :code, “#{code} has already been processed” )
