Class: XMLCodec::XMLStreamObjectParser

Inherits:
Nokogiri::XML::SAX::Document
  • Object
show all
Defined in:
lib/stream_object_parser.rb

Overview

This is a XML Stream parser that returns ruby objects for whole elements. To do this a class must be defined as descending from XMLElement and having set elname or elnames. To use it all you have to do is define a listener that responds to methods of the form el_<element name> and define the importers for the elements as subclasses of XMLElement.

The listener will be passed XMLSOParserElement objects. The two relevant methods for it’s use are XMLSOParserElement#get_object and XMLSOParserElement#consume.

Instance Method Summary collapse

Constructor Details

#initialize(base_element, listener = nil) ⇒ XMLStreamObjectParser

Create a new parser with a listener.



65
66
67
68
69
70
71
72
73
74
# File 'lib/stream_object_parser.rb', line 65

def initialize(base_element, listener=nil)
  @base_element = base_element
  @listener = listener
  @children = Hash.new([])
  @currel = 0
  @elements = [XMLSOParserElement.new(nil, nil, nil, nil, nil, 0)]
  @id = 0
  @top_element = nil
  @allvalue = 0
end

Instance Method Details

#characters(text) ⇒ Object

:nodoc:



121
122
123
124
125
126
127
# File 'lib/stream_object_parser.rb', line 121

def characters(text) #:nodoc:
  if @allvalue > 0
    curr_element.get_object.value << text
  else
    curr_element.add_child(text)
  end
end

#end_element(name) ⇒ Object

:nodoc:



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/stream_object_parser.rb', line 129

def end_element(name) #:nodoc:
  elclass =  get_elclass(name)
  if @allvalue > 1
    # We're closing an allvalue subelement, just output it and pop
    curr_element.get_object.value << XMLUtils.create_close_tag(name) 
    @allvalue -= 1  
  else
    obj = curr_element
    
    if @listener.respond_to?("el_"+name)
      @listener.send("el_"+name, obj)
    end
    
    if not obj.consumed
      real_obj = obj.get_object

      if prev_element && real_obj
        prev_element.add_child(real_obj)
      end
      
      @top_element = obj
    end
        
    @elements.pop
    @currel -= 1
    @allvalue = 0
  end
end

#parse(text) ⇒ Object

Parse the text with the stream parser calling the listener on any events that it listens to.



96
97
98
99
# File 'lib/stream_object_parser.rb', line 96

def parse(text)
  parser = Nokogiri::XML::SAX::Parser.new(self)
  parser.parse(text)
end

#start_element(name, attrs) ⇒ Object

:nodoc:



107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/stream_object_parser.rb', line 107

def start_element(name, attrs) #:nodoc:
  elclass =  get_elclass(name)
  if @allvalue > 0
    curr_element.get_object.value << XMLUtils.create_open_tag(name,attrs)
    @allvalue += 1
  else
    @elements << XMLSOParserElement.new(name, attrs, elclass, 
                                        curr_element, next_id, 
                                        curr_element.depth+1)
    @currel += 1
    @allvalue = 1 if elclass && elclass.allvalue?
  end
end

#top_elementObject

Get the current top element of the parse. This is usually used to get the root at the end of the parse.



103
104
105
# File 'lib/stream_object_parser.rb', line 103

def top_element
  @top_element.get_object if @top_element
end