From: Sandy Thomson Date: 2009-03-18T01:25:08+09:00 Subject: Re: XML to CSV with REXML - I'm sure this should be easy... > What you are really interested in is each performance (each performance > generates one line of output). So simply deepen your loop: > > xml.elements.each("//event") do |e| > e.elements.each("//performance") do |p| > > Now do exactly what you're doing and just append the performance date. > So, for example: > > require 'rexml/document' > include REXML > output = "" > class REXML::Element > def textof(xpaths_arr); xpaths_arr.map {|x| elements[x].text}; end > end > xml = Document.new(s) > xp = %w{title category venue/name > venue/address/address1 venue/address/town} > xml.elements.each("//event") do |e| > e.elements.each("//performance") do |p| > output << > [e.attributes['id'], > e.textof(xp), > p.attributes['date']].flatten.join("|") + "\n" > end > end > > m. Ok, so this is plainly much neater, thanks Matt :) ...but, whilst it works for one event with multiple dates, as soon as I add a second event it iterates through all of the dates against every event, so for 2 events each with 2 dates it outputs 8 lines... Here's the code as it now stands: require 'rexml/document' include REXML output = "" class REXML::Element def textof(xpaths_arr); xpaths_arr.map {|x| elements[x].text}; end end xml = REXML::Document.new(File.open("data.xml")) csv_file = File.new("data.csv", "w") xp = %w{title category venue/name venue/address/address1 venue/address/town} xml.elements.each("//event") do |e| e.elements.each("//performance") do |p| csv_file.puts output + [e.attributes['id'], e.textof(xp), p.attributes['date']].flatten.join("|") + "\n" end end -- Posted via http://www.ruby-forum.com/.