Class: REXML::Parsers::SAX2Parser (Ruby 2.3.7)
Description: Class : REXML::Parsers::SAX2Parser - Ruby 2.3.7

- Home
- Core 2.3.7
- Std-lib 2.3.7
- Downloads

Support for the Ruby 2.3 series has ended. See here for reference.

### Home Classes Methods

### In Files

- rexml/parsers/sax2parser.rb

### Parent

Object

### Methods

- ::new
- #add_listener
- #deafen
- #listen
- #parse
- #source

### Class/Module Index

Quicksearch

- Array
- Fixnum
- Float
- Object
- REXML
- REXML::AttlistDecl
- REXML::Attribute
- REXML::Attributes
- REXML::CData
- REXML::Child
- REXML::Comment
- REXML::DTD
- REXML::DTD::AttlistDecl
- REXML::DTD::ElementDecl
- REXML::DTD::EntityDecl
- REXML::DTD::NotationDecl
- REXML::DTD::Parser
- REXML::Declaration
- REXML::DocType
- REXML::Document
- REXML::Element
- REXML::ElementDecl
- REXML::Elements
- REXML::Encoding
- REXML::Entity
- REXML::EntityConst
- REXML::ExternalEntity
- REXML::Formatters
- REXML::Formatters::Default
- REXML::Formatters::Pretty
- REXML::Formatters::Transitive
- REXML::Functions
- REXML::IOSource
- REXML::Instruction
- REXML::Light
- REXML::Light::Node
- REXML::Namespace
- REXML::Node
- REXML::NotationDecl
- REXML::Output
- REXML::Parent
- REXML::ParseException
- REXML::Parsers
- REXML::Parsers::BaseParser
- REXML::Parsers::LightParser
- REXML::Parsers::PullEvent
- REXML::Parsers::PullParser
- REXML::Parsers::SAX2Parser
- REXML::Parsers::StreamParser
- REXML::Parsers::TreeParser
- REXML::Parsers::UltraLightParser
- REXML::Parsers::XPathParser
- REXML::QuickPath
- REXML::SAX2Listener
- REXML::Security
- REXML::Source
- REXML::SourceFactory
- REXML::StreamListener
- REXML::SyncEnumerator
- REXML::Text
- REXML::UndefinedNamespaceException
- REXML::Validation
- REXML::Validation::Choice
- REXML::Validation::Event
- REXML::Validation::Interleave
- REXML::Validation::OneOrMore
- REXML::Validation::Optional
- REXML::Validation::Ref
- REXML::Validation::RelaxNG
- REXML::Validation::Sequence
- REXML::Validation::State
- REXML::Validation::ValidationException
- REXML::Validation::Validator
- REXML::Validation::ZeroOrMore
- REXML::XMLDecl
- REXML::XMLTokens
- REXML::XPath
- REXML::XPathParser
- Symbol

No matching classes.

# REXML::Parsers::SAX2Parser

SAX2Parser

### Public Class Methods

new(source) click to toggle source

                   # File rexml/parsers/sax2parser.rb, line 10
    def initialize source
      @parser = BaseParser.new(source)
      @listeners = []
      @procs = []
      @namespace_stack = []
      @has_listeners = false
      @tag_stack = []
      @entities = {}
    end

### Public Instance Methods

add_listener( listener ) click to toggle source

                   # File rexml/parsers/sax2parser.rb, line 24
    def add_listener( listener )
      @parser.add_listener( listener )
    end

deafen( listener=nil, &blok ) click to toggle source

                   # File rexml/parsers/sax2parser.rb, line 76
    def deafen( listener=nil, &blok )
      if listener
        @listeners.delete_if {|item| item[-1] == listener }
        @has_listeners = false if @listeners.size == 0
      else
        @procs.delete_if {|item| item[-1] == blok }
      end
    end

listen( *args, &blok ) click to toggle source

Listen arguments:

Symbol, Array, Block

    Listen to Symbol events on Array elements

Symbol, Block

    Listen to Symbol events

Array, Listener

    Listen to all events on Array elements

Array, Block

    Listen to :start_element events on Array elements

Listener

    Listen to All events

Symbol can be one of: :start_element, :end_element, :start_prefix_mapping, :end_prefix_mapping, :characters, :processing_instruction, :doctype, :attlistdecl, :elementdecl, :entitydecl, :notationdecl, :cdata, :xmldecl, :comment

There is an additional symbol that can be listened for: :progress. This will be called for every event generated, passing in the current stream position.

Array contains regular expressions or strings which will be matched against fully qualified element names.

Listener must implement the methods in SAX2Listener

Block will be passed the same arguments as a SAX2Listener method would be, where the method name is the same as the matched Symbol. See the SAX2Listener for more information.

                   # File rexml/parsers/sax2parser.rb, line 58
    def listen( *args, &blok )
      if args[0].kind_of? Symbol
        if args.size == 2
          args[1].each { |match| @procs << [args[0], match, blok] }
        else
          add( [args[0], nil, blok] )
        end
      elsif args[0].kind_of? Array
        if args.size == 2
          args[0].each { |match| add( [nil, match, args[1]] ) }
        else
          args[0].each { |match| add( [ :start_element, match, blok ] ) }
        end
      else
        add([nil, nil, args[0]])
      end
    end

parse() click to toggle source

                   # File rexml/parsers/sax2parser.rb, line 85
    def parse
      @procs.each { |sym,match,block| block.call if sym == :start_document }
      @listeners.each { |sym,match,block|
        block.start_document if sym == :start_document or sym.nil?
      }
      context = []
      while true
        event = @parser.pull
        case event[0]
        when :end_document
          handle( :end_document )
          break
        when :start_doctype
          handle( :doctype, *event[1..-1])
        when :end_doctype
          context = context[1]
        when :start_element
          @tag_stack.push(event[1])
          # find the observers for namespaces
          procs = get_procs( :start_prefix_mapping, event[1] )
          listeners = get_listeners( :start_prefix_mapping, event[1] )
          if procs or listeners
            # break out the namespace declarations
            # The attributes live in event[2]
            event[2].each {|n, v| event[2][n] = @parser.normalize(v)}
            nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ }
            nsdecl.collect! { |n, value| [ n[6..-1], value ] }
            @namespace_stack.push({})
            nsdecl.each do |n,v|
              @namespace_stack[-1][n] = v
              # notify observers of namespaces
              procs.each { |ob| ob.call( n, v ) } if procs
              listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners
            end
          end
          event[1] =~ Namespace::NAMESPLIT
          prefix = $1
          local = $2
          uri = get_namespace(prefix)
          # find the observers for start_element
          procs = get_procs( :start_element, event[1] )
          listeners = get_listeners( :start_element, event[1] )
          # notify observers
          procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs
          listeners.each { |ob|
            ob.start_element( uri, local, event[1], event[2] )
          } if listeners
        when :end_element
          @tag_stack.pop
          event[1] =~ Namespace::NAMESPLIT
          prefix = $1
          local = $2
          uri = get_namespace(prefix)
          # find the observers for start_element
          procs = get_procs( :end_element, event[1] )
          listeners = get_listeners( :end_element, event[1] )
          # notify observers
          procs.each { |ob| ob.call( uri, local, event[1] ) } if procs
          listeners.each { |ob|
            ob.end_element( uri, local, event[1] )
          } if listeners

          namespace_mapping = @namespace_stack.pop
          # find the observers for namespaces
          procs = get_procs( :end_prefix_mapping, event[1] )
          listeners = get_listeners( :end_prefix_mapping, event[1] )
          if procs or listeners
            namespace_mapping.each do |ns_prefix, ns_uri|
              # notify observers of namespaces
              procs.each { |ob| ob.call( ns_prefix ) } if procs
              listeners.each { |ob| ob.end_prefix_mapping(ns_prefix) } if listeners
            end
          end
        when :text
          #normalized = @parser.normalize( event[1] )
          #handle( :characters, normalized )
          copy = event[1].clone

          esub = proc { |match|
            if @entities.has_key?($1)
              @entities[$1].gsub(Text::REFERENCE, &esub)
            else
              match
            end
          }

          copy.gsub!( Text::REFERENCE, &esub )
          copy.gsub!( Text::NUMERICENTITY ) {|m|
            m=$1
            m = "0#{m}" if m[0] == ?x
            [Integer(m)].pack('U*')
          }
          handle( :characters, copy )
        when :entitydecl
          handle_entitydecl( event )
        when :processing_instruction, :comment, :attlistdecl,
          :elementdecl, :cdata, :notationdecl, :xmldecl
          handle( *event )
        end
        handle( :progress, @parser.position )
      end
    end

source() click to toggle source

                   # File rexml/parsers/sax2parser.rb, line 20
    def source
      @parser.source
    end