From: Erik Terpstra Date: 2003-10-03T00:26:52+09:00 Subject: Re: xml in Ruby 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 %{ Joe 28 Engineering Ken 26 Engineering } 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 %{ I. Wannabuy
53 Party Lane Anywhere CA 12345
Large Purple Dinosaur, Generic 35 24.99 Catapult 1 149.95 300 foot measuring tape 1 9.95
} 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