Module RSS::ListenerMixin
In: lib/rss/0.9.rb
lib/rss/1.0.rb
lib/rss/parser.rb

Methods

Constants

CONTENT_PATTERN = /\s*([^=]+)=(["'])([^\2]+?)\2/
NAMESPLIT = /^(?:([\w:][-\w\d.]*):)?([\w:][-\w\d.]*)/

Attributes

do_validate  [RW] 
ignore_unknown_element  [RW] 
rss  [R] 

Public Class methods

[Source]

     # File lib/rss/parser.rb, line 271
271:     def initialize
272:       @rss = nil
273:       @ignore_unknown_element = true
274:       @do_validate = true
275:       @ns_stack = [{}]
276:       @tag_stack = [[]]
277:       @text_stack = ['']
278:       @proc_stack = []
279:       @last_element = nil
280:       @version = @encoding = @standalone = nil
281:       @xml_stylesheets = []
282:     end

Public Instance methods

[Source]

     # File lib/rss/parser.rb, line 289
289:     def instruction(name, content)
290:       if name == "xml-stylesheet"
291:         params = parse_pi_content(content)
292:         if params.has_key?("href")
293:           @xml_stylesheets << XMLStyleSheet.new(*params)
294:         end
295:       end
296:     end

[Source]

     # File lib/rss/parser.rb, line 322
322:     def tag_end(name)
323:       if DEBUG
324:         p "end tag #{name}"
325:         p @tag_stack
326:       end
327:       text = @text_stack.pop
328:       tags = @tag_stack.pop
329:       pr = @proc_stack.pop
330:       pr.call(text, tags) unless pr.nil?
331:       @ns_stack.pop
332:     end

[Source]

     # File lib/rss/parser.rb, line 298
298:     def tag_start(name, attributes)
299:       @text_stack.push('')
300: 
301:       ns = @ns_stack.last.dup
302:       attrs = {}
303:       attributes.each do |n, v|
304:         if /\Axmlns(?:\z|:)/ =~ n
305:           ns[$POSTMATCH] = v
306:         else
307:           attrs[n] = v
308:         end
309:       end
310:       @ns_stack.push(ns)
311: 
312:       prefix, local = split_name(name)
313:       @tag_stack.last.push([_ns(ns, prefix), local])
314:       @tag_stack.push([])
315:       if respond_to?("start_#{local}", true)
316:         __send__("start_#{local}", local, prefix, attrs, ns.dup)
317:       else
318:         start_else_element(local, prefix, attrs, ns.dup)
319:       end
320:     end

[Source]

     # File lib/rss/parser.rb, line 334
334:     def text(data)
335:       @text_stack.last << data
336:     end

set instance vars for version, encoding, standalone

[Source]

     # File lib/rss/parser.rb, line 285
285:     def xmldecl(version, encoding, standalone)
286:       @version, @encoding, @standalone = version, encoding, standalone
287:     end

Private Instance methods

[Source]

     # File lib/rss/parser.rb, line 339
339:     def _ns(ns, prefix)
340:       ns.fetch(prefix, "")
341:     end

[Source]

     # File lib/rss/parser.rb, line 380
380:     def check_ns(tag_name, prefix, ns, require_uri)
381:       if @do_validate
382:         if _ns(ns, prefix) == require_uri
383:           #ns.delete(prefix)
384:         else
385:           raise NSError.new(tag_name, prefix, require_uri)
386:         end
387:       end
388:     end

Extract the first name="value" pair from content. Works with single quotes according to the constant CONTENT_PATTERN. Return a Hash.

[Source]

     # File lib/rss/parser.rb, line 347
347:     def parse_pi_content(content)
348:       params = {}
349:       content.scan(CONTENT_PATTERN) do |name, quote, value|
350:         params[name] = value
351:       end
352:       params
353:     end

[Source]

     # File lib/rss/parser.rb, line 375
375:     def split_name(name)
376:       name =~ NAMESPLIT
377:       [$1 || '', $2]
378:     end

[Source]

     # File lib/rss/1.0.rb, line 438
438:     def start_RDF(tag_name, prefix, attrs, ns)
439:       check_ns(tag_name, prefix, ns, RDF::URI)
440: 
441:       @rss = RDF.new(@version, @encoding, @standalone)
442:       @rss.do_validate = @do_validate
443:       @rss.xml_stylesheets = @xml_stylesheets
444:       @last_element = @rss
445:       @proc_stack.push Proc.new { |text, tags|
446:         @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
447:       }
448:     end

[Source]

     # File lib/rss/parser.rb, line 355
355:     def start_else_element(local, prefix, attrs, ns)
356:       class_name = self.class.class_name(_ns(ns, prefix), local)
357:       current_class = @last_element.class
358:       if current_class.constants.include?(class_name)
359:         next_class = current_class.const_get(class_name)
360:         start_have_something_element(local, prefix, attrs, ns, next_class)
361:       else
362:         if !@do_validate or @ignore_unknown_element
363:           @proc_stack.push(nil)
364:         else
365:           parent = "ROOT ELEMENT???"
366:           if current_class.tag_name
367:             parent = current_class.tag_name
368:           end
369:           raise NotExpectedTagError.new(local, _ns(ns, prefix), parent)
370:         end
371:       end
372:     end

[Source]

     # File lib/rss/parser.rb, line 390
390:     def start_get_text_element(tag_name, prefix, ns, required_uri)
391:       @proc_stack.push Proc.new {|text, tags|
392:         setter = self.class.setter(required_uri, tag_name)
393:         if @last_element.respond_to?(setter)
394:           @last_element.__send__(setter, text.to_s)
395:         else
396:           if @do_validate and !@ignore_unknown_element
397:             raise NotExpectedTagError.new(tag_name, _ns(ns, prefix),
398:                                           @last_element.tag_name)
399:           end
400:         end
401:       }
402:     end

[Source]

     # File lib/rss/parser.rb, line 404
404:     def start_have_something_element(tag_name, prefix, attrs, ns, klass)
405: 
406:       check_ns(tag_name, prefix, ns, klass.required_uri)
407: 
408:       attributes = {}
409:       klass.get_attributes.each do |a_name, a_uri, required, element_name|
410: 
411:         if a_uri.is_a?(String) or !a_uri.respond_to?(:include?)
412:           a_uri = [a_uri]
413:         end
414:         unless a_uri == [""]
415:           for prefix, uri in ns
416:             if a_uri.include?(uri)
417:               val = attrs["#{prefix}:#{a_name}"]
418:               break if val
419:             end
420:           end
421:         end
422:         if val.nil? and a_uri.include?("")
423:           val = attrs[a_name]
424:         end
425: 
426:         if @do_validate and required and val.nil?
427:           unless a_uri.include?("")
428:             for prefix, uri in ns
429:               if a_uri.include?(uri)
430:                 a_name = "#{prefix}:#{a_name}"
431:               end
432:             end
433:           end
434:           raise MissingAttributeError.new(tag_name, a_name)
435:         end
436: 
437:         attributes[a_name] = val
438:       end
439: 
440:       previous = @last_element
441:       next_element = klass.new(@do_validate, attributes)
442:       previous.instance_eval {set_next_element(tag_name, next_element)}
443:       @last_element = next_element
444:       @proc_stack.push Proc.new { |text, tags|
445:         p(@last_element.class) if DEBUG
446:         @last_element.content = text if klass.have_content?
447:         if @do_validate
448:           @last_element.validate_for_stream(tags, @ignore_unknown_element)
449:         end
450:         @last_element = previous
451:       }
452:     end

[Source]

     # File lib/rss/0.9.rb, line 409
409:     def start_rss(tag_name, prefix, attrs, ns)
410:       check_ns(tag_name, prefix, ns, "")
411:       
412:       @rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
413:       @rss.do_validate = @do_validate
414:       @rss.xml_stylesheets = @xml_stylesheets
415:       @last_element = @rss
416:       @proc_stack.push Proc.new { |text, tags|
417:         @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
418:       }
419:     end

[Validate]