Last year I made a quick hack that could do something like that.
I didn't have much experience with Ruby back then, so it is a quick and 
very dirty solution. But the following works:


require 'XML'

y = XML %{
         <employees>
                 <employee>
                         <name>Joe</name>
                         <age>28</age>
                         <department>
                                 <name>Engineering</name>
                         </department>
                 </employee>
                 <employee>
                         <name>Ken</name>
                         <age>26</age>
                         <department>
                                 <name>Engineering</name>
                         </department>
                 </employee>
         </employees>
}

puts y.employees.employee[0].age
y.employees.employee[0].age = '9'
puts y.employees.employee[0].age

y.employees.employee.each do |employee|
         puts "name: #{employee.name}, age: #{employee.age}"
end



doc = XML %{
         <order>
                 <customer>
                         <name>I. Wannabuy</name>
                         <address>
                                 <street>53 Party Lane</street>
                                 <city>Anywhere</city>
                                 <state>CA</state>
                                 <zip>12345</zip>
                         </address>
                 </customer>
                 <item>
                         <description>Large Purple Dinosaur, 
Generic</description>
                         <quantity>35</quantity>
                         <price>24.99</price>
                 </item>
                 <item>
                         <description>Catapult</description>
                         <quantity>1</quantity>
                         <price>149.95</price>
                 </item>
                 <item>
                         <description>300 foot measuring tape</description>
                         <quantity>1</quantity>
                         <price>9.95</price>
                 </item>
         </order>
}

def calc_total(order)
         total = 0
         order.item.each do |item|
                 total += item.price.to_f * item.quantity.to_i
         end
         return total
end

puts "total: #{calc_total(doc.order)}"












======================================================

This is the file XML.rb that makes it work:

======================================================


require 'xmltreebuilder'
require 'perlvalue'

ELEMENT_NODE = 1; ATTRIBUTE_NODE = 2; TEXT_NODE = 3

module Kernel
         def XML(xml)
                 RNX.new(xml)
         end
end

class RNX
         def initialize(xml)
                 @level = 0; @line = @source = ''; @path = []
                 builder = XML::DOM::Builder.new
                 begin
                         dom = builder.parse xml.gsub(/\s+/, '')
                 rescue
                         puts "#{$0}: #{$!} (in line #{builder.line}"; 
exit 1
                 end
                 dom.documentElement.normalize
                 traverse dom
                 eval %{
                         @#{dom.documentElement.nodeName} = PerlValue.new
                         #{@source}

                         def self.#{dom.documentElement.nodeName}
                                 return @#{dom.documentElement.nodeName}
                         end
                 }
         end

         def traverse(node)
                 index = 0
                 node.childNodes.each do |n|
                         if n.nodeType == ELEMENT_NODE
                                 @path[@level] = n.nodeName
                                 if (n.nextSibling and 
n.nextSibling.nodeName == n.nodeName) or (n.previousSibling and 
n.previousSibling.nodeName == n.nodeName)
                                         @path[@level] += "[#{index}]"
                                         index += 1
                                 end
                                 @line = @path.join('.')
                                 @level += 1; traverse n; @level -= 1
                                 @path.delete_at(@level)
                         elsif n.nodeType == TEXT_NODE
                                 @line += " = '#{n.data}'\n" if n.data 
=~ /\S/ #optional!!!
                                 @source += "@#{@line}"
                         end
                 end
         end
end