Rails: rendering XML adds <hash> tag
Asked Answered
L

2

13

I've got a Rails controller which is going to output a hash in XML format - for example:

class MyController < ApplicationController
  # GET /example.xml
  def index        
    @output = {"a" => "b"}

    respond_to do |format|
      format.xml  {render :xml => @output}
    end
  end
end

However, Rails adds a <hash> tag, which I don't want, i.e.:

<hash>
  <a>
    b
  </a>
</hash>

How can I just output this instead?

<a>
  b
</a>
Louque answered 5/6, 2011 at 8:58 Comment(0)
R
19

I think if you're converting an object to XML, you need a tag which wraps everything, but you can customise the tag name for the wrapper:

def index        
  @output = {"a" => "b"}

  respond_to do |format|
    format.xml  {render :xml => @output.to_xml(:root => 'output')}
  end
end

Which will result in:

<output>
  <a>
    b
  </a>
</output>
Ruddock answered 5/6, 2011 at 9:13 Comment(4)
That'll do what I need. Thanks!Louque
The tag "output" may fit his needs, but it doesn't answer the question. nothing was removed.... it was just replaced. root is still there.Cresida
XML can only have a single root element, so whilst it would be trivial to remove the root element and just output the <a />, the example would've broken down as soon as he wanted to output more than one attribute. The purpose of this answer was to highlight the importance of the single root element, as well as show him how to change the name of the root element.Ruddock
Who cares what the xml spec is? It's completely irrelevant to the question!!!! What if we're talking to an API that doesn't use root elements? Should we tell our client, we can't use that API -- they're bad people who didn't follow the spec? What if we need to compose bits of xml separately from several sources that happen to be hashes? If you can't answer the actual question, don't waste everyone's bandwith with your sanctimony.Lenoralenore
S
7

I was having the same Issue;

This is my XML:

<?xml version="1.0" encoding="UTF-8"?>
<Contacts>
  <Contact type="array">
  </Contact>
</Contacts>

I was using this:

entries.to_xml

to convert hash data into XML, but this wraps entries' data into <hash></hash>

So I modified:

entries.to_xml(root: "Contacts")

but that still wrapped the converted XML in 'Contacts'. modifying my XML code to

<Contacts>
 <Contacts>
  <Contact type="array">
   <Contact>
    <Name></Name>
    <Email></Email>
    <Phone></Phone>
   </Contact>
  </Contact>
 </Contacts>
</Contacts>

So it adds an extra ROOT that I don't wan't there.

Now solution to this what worked for me is:

 entries["Contacts"].to_xml(root: "Contacts")

that avoids <hash></hash> or any additional root to be included. Cheers!!

Sigmoid answered 30/9, 2013 at 8:44 Comment(2)
On applying your solution getting this error NoMethodError: undefined method `to_xml' for nil:NilClassProportion
@KartikAgarwal Seems like your entries object doesn't have "Contacts" populated. Can you check why that happens?Sigmoid

© 2022 - 2024 — McMap. All rights reserved.