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

### Home Classes Methods

### In Files

- rexml/parsers/sax2parser.rb

### Parent

Object

### Methods

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

### Class/Module Index

Quicksearch

- Array
- Float
- Integer
- 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 11
    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 25
    def add_listener( listener )
      @parser.add_listener( listener )
    end

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

                   # File rexml/parsers/sax2parser.rb, line 77
    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 59
    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 86
    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 21
    def source
      @parser.source
    end