# Rexml - StreamListener - Where I am in the XML?

**URL:** <https://www.ruby-forum.com/t/rexml-streamlistener-where-i-am-in-the-xml/86385>\
**Category:** Ruby\
**Created:** [February 21, 2007, 10:25pm UTC](https://www.ruby-forum.com/t/rexml-streamlistener-where-i-am-in-the-xml/86385 "2007-02-21T22:25:36Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 21, 2007, 10:25pm UTC](https://www.ruby-forum.com/t/rexml-streamlistener-where-i-am-in-the-xml/86385/1 "2007-02-21T22:25:36Z")

</div>

Hi,

I’m using REXML::StreamListener to analyze a big xml file. My ruby  
code looks like this:

— code start here —

require ‘rexml/document’  
require ‘rexml/streamlistener’

class MyListener  
include REXML::StreamListener  
def tag\_start(name, attrs)  
# anything to do …  
end  
def text(text)  
# anything to do …  
end  
end

REXML::Document.parse\_stream( File.open( xmlfile), MyListener.new)

— code ends here —

At the “tag\_start” method I need sometimes the information where I am  
in the xml. What is my parent tag and so on. Is there is a method to  
get this information at this time?

Regards

Michael

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2007, 2:08am UTC](https://www.ruby-forum.com/t/rexml-streamlistener-where-i-am-in-the-xml/86385/2 "2007-02-22T02:08:17Z")

</div>

removed\_email\_address@domain.invalid wrote:

> class MyListener
> 
> — code ends here —
> 
> At the “tag\_start” method I need sometimes the information where I am  
> in the xml. What is my parent tag and so on. Is there is a method to  
> get this information at this time?

In general, the big value of a stream parser is that it is not holding  
onto much state, so memory needs stay small regardless of the size of  
the XML. State tracking is left to the application developer.

The REXML pull-parser lets you peek at the next event; not sure offhand  
if it goes the other way. But I suspect that with the stream and pull  
parsers (one of which sits on the other under the hood, so they are more  
or less the same), once an event is off the stack, it is gone.

Stream parsing works really well when you have a large source of  
regularly structured data (e.g., XML dump of a database table), such  
that you can grab and stash in memory just what you need, work with it  
(perhaps as a transient DOM), then discard it and move on.

–  
James B.

“Trying to port the desktop metaphor to the Web is like working  
on how to fuel your car with hay because that is what horses eat.”  
- Dare Obasanjo

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2007, 3:41am UTC](https://www.ruby-forum.com/t/rexml-streamlistener-where-i-am-in-the-xml/86385/3 "2007-02-22T03:41:23Z")

</div>

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

> I’m using REXML::StreamListener to analyze a big xml file. My ruby  
> code looks like this:  
> …  
> At the “tag\_start” method I need sometimes the information where I am  
> in the xml. What is my parent tag and so on. Is there is a method to  
> get this information at this time?

Hi,

I’ve used REXML::Parsers::PullParser instead of stream parsing (same  
general idea), here’s an example of a function that waits until it  
sees a tag that matches element\_name and then pulls the text from it:

```
def self.get_element_text(filename, element_name)
  parser = REXML::Parsers::PullParser.new(File.new(filename))
  text = false
  while parser.has_next?
    el = parser.pull
    if el.start_element? and el[0] == element_name
      text = parser.peek[0]
      break
    end
  end
  return text
end

```

So, while the above certainly won’t work for your application, you  
could try playing a little with parser.peek to see if you can find the  
child node (or next node, whatever) that you’re looking for.

HTH,  
Keith

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 22, 2007, 11:56am UTC](https://www.ruby-forum.com/t/rexml-streamlistener-where-i-am-in-the-xml/86385/4 "2007-02-22T11:56:15Z")

</div>

@James: I know a SAX parser in another language that has to use like  
the REXML::StreamListener. You have additional the information that -  
for example - a FirstName-Tag is a member of a User-Tag and so on.  
You’re right, if I use REXML::StreamListener, I can track the stack  
for my self. But there was a chance that I have oversight the right  
function in REXML::StreamListener only 🙂

@Keith: I will check the REXML::Parsers::PullParser. Thanks for the  
info 🙂

Michael
