--------------040605010606080801050607 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 13.01.2008 13:37, Marc Hoeppner wrote: > Thanks for the great responses! > > Just for clarification though: > > tag_start identifies an element like "gene" ala > > def tag_start(name, attrib) > if name gene" > do something here > end > end > > So tag_end is then used if I want to puts everything that was done with > the element and its children like storing some values in an array or > something? Yeah, you could do that. Basically it's completely up to you. The parser just hands off events for parsed XML items (like starting tags, closing tags, text data etc.) in the order found in the document. I have attached another example of an idiom that I use frequently. This may not be needed in your case but who knows? Basic idea is that the event listener creates nested listeners (one per element) and hands processing off to them while maintaining a stack of listeners. That way you can do different processing based on element name, attributes or whatever. Might be overkill for your simple example but OTOH if you do need to do complex processing steps based on elements this might be exactly what you need. For example, you can store any information you need in a nested listener and do all the processing in end tag. Kind regards robert --------------040605010606080801050607 Content-Type: text/plain; name exml-stream.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename exml-stream.rb" #!/bin/env ruby # Robert Klemme 2007 require 'rexml/document' require 'rexml/streamlistener' require 'delegate' class StreamListener < Delegator def initialize @current estedStreamListener.new end def tag_start(name, attrs) sl istener(name, attrs).new sl.parent current @current l sl.tag_start(name, attrs) end def tag_end(name) @current.tag_end(name) @current current.parent end def __getobj__ @current or raise "Cannot handle beyond root" end private def listener(name, attrs) # more complex code here for specific # nested listeners NestedStreamListener end end class BaseNestedStreamListener include REXML::StreamListener # structure attr_accessor :parent protected # parents from the root def parents res ] sl elf while sl res.unshift sl sl l.parent end res end end class NestedStreamListener < BaseNestedStreamListener attr_accessor :tag_name def tag_start(name, attrs) # demo only self.tag_name ame parents.each do |par| print par.tag_name, " " end puts @text " end def tag_end(name) print " ", @text.inspect, "\n" end def text(s) (@text || ") << s end alias cdata text end REXML::Document.parse_stream( DATA, StreamListener.new ) __END__ <root> <Gene-ref> <name>foo</name> <start>17</start> <end>42</end> </Gene-ref> <Gene-ref> <name>bar</name> <start>43</start> <end>50</end> </Gene-ref> </root> --------------040605010606080801050607--