# Mapping xml to active record objects

**URL:** <https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074>\
**Category:** Rails\
**Created:** [February 19, 2007, 6:04pm UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074 "2007-02-19T18:04:17Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [February 19, 2007, 6:04pm UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/1 "2007-02-19T18:04:17Z")

</div>

I’ve built a simple service that returns an xml feed like so:

 blah blah 1 blah blah 2 etc..

What is a quick way to map this result to an array of user objects?

Thanks

Marlon

---

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [February 19, 2007, 7:02pm UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/2 "2007-02-19T19:02:26Z")

</div>

Just to answer my own question: Hpricot!

Very, very easy to do this now. Here’s an example.

doc = HJpricot(open(“[http://locahost:3000/user/list](http://locahost:3000/user/list)”))  
(doc/:user).each do |user|  
u = User.new  
u.id = (user/:login).innerHTML  
u.first\_name = (user:/:first\_name).innerHTML  
users.push(u)  
end

This has got to be the easiest thing I’ve ever done to consume XML.

On 2/19/07, Marlon M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> <first_name>blah</first_name>
> 
> ```
> 
> Marlon

–  
“They put a hot wire to my head  
'Cause of the things I did and said  
And made these feelings go away  
Model citizen in every way”

---

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [February 20, 2007, 7:25am UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/3 "2007-02-20T07:25:38Z")

</div>

Here’s another option… If your xml elements match your User model’s  
attribute names, you can just convert the xml to a hash and loop through  
its contents:

xml =   
users = []  
Hash.from\_xml(xml)[‘users’][‘user’].each { |user\_vals|  
users \<\< User.new(user\_vals)  
}

b

---

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [February 22, 2007, 7:29am UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/4 "2007-02-22T07:29:38Z")

</div>

I’ve got an almost identical problem, except my data looks like:

 ...

I’m really struggling with Hpricot - my brain just isn’t working today  
(probably because of the aircon problems at work today…). If  
someone could show me how to map _this_ to an array of User objects,  
I’d greatly appreciate it.

Thanks in advance

Dave M.

---

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [February 22, 2007, 9:44am UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/5 "2007-02-22T09:44:53Z")

</div>

Sorry, I think the quick and easy stops once you start having attributes  
on your elements (or, have elements that don’t match your user’s  
fields).

Take a look at ReXML:

[http://www.germane-software.com/software/rexml/docs/tutorial.html](http://www.germane-software.com/software/rexml/docs/tutorial.html)

Comes with standard with Ruby, IIRC.

b

---

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [February 22, 2007, 9:20pm UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/6 "2007-02-22T21:20:45Z")

</div>

Um, that’s not even XML. But if it were XML (e.g. \<first\_name\>blah\</  
first\_name\>) you could do something like this:

# require ‘rubygems’ # if installed via Gems

require ‘xml/libxml’  
doc = XML::Document.file(‘users.xml’)

doc.find(’//user’).each do |user|  
u = User.new  
u.id = user.find\_first(’@id’).content  
u.first\_name = user.find\_first(‘first\_name’).content  
u.last\_name = user.find\_first(‘last\_name’).content  
users.push(u)  
end

---

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [February 22, 2007, 8:32pm UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/7 "2007-02-22T20:32:39Z")

</div>

Yep, that’s kind of what I suspected.

Thanks

Dave M.

---

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [April 19, 2007, 4:52pm UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/8 "2007-04-19T16:52:08Z")

</div>

actually, it is xml

the is shorthand for

---

<div class="post-metadata">

**Author:** ![Marlon\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@Marlon\_M](https://www.ruby-forum.com/u/Marlon_M)\
**Post date:** [February 22, 2007, 9:30pm UTC](https://www.ruby-forum.com/t/mapping-xml-to-active-record-objects/86074/9 "2007-02-22T21:30:46Z")

</div>

yep, that’s what I was thinking about the format, but given that feed,  
you  
could also do something ugly like this:

require ‘rubygems’  
require ‘hpricot’

doc = Hpricot(’  
  
  
\<first\_name=“blah”/\>  
\<last\_name=“blah”/\>  
  
  
\<first\_name=“blah”/\>  
\<last\_name=“blah”/\>  
  
  
’  
)

(doc/“user”).each do |user|  
puts “user id = #{user.attributes[‘id’]}”  
puts “first\_name = #{user.children  
[0].to\_s.scan(/first\_name=”([^“]\*)”/).to\_s}"  
end

On 2/22/07, Mark T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> u = User.new
> u.id = user.find_first('@id').content
> u.first_name = user.find_first('first_name').content
> u.last_name = user.find_first('last_name').content
> users.push(u)
> 
> ```
> 
> end
> 
> >

–  
“We all had delusions in our heads,  
we all had our minds made up for us,  
we had to believe in something,  
…so we did.”
