Class: REXML::Parsers::BaseParser (Ruby 2.7.5)
Description: Class : REXML::Parsers::BaseParser - Ruby 2.7.5

### Home Classes Methods

### In Files

- rexml/parsers/baseparser.rb

### Parent

Object

### Methods

- ::new
- #add_listener
- #empty?
- #entity
- #has_next?
- #normalize
- #peek
- #position
- #pull
- #stream=
- #unnormalize
- #unshift

### 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::ReferenceWriter
- REXML::SAX2Listener
- REXML::Security
- REXML::Source
- REXML::SourceFactory
- REXML::StreamListener
- 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::XPathNode
- REXML::XPathParser
- Symbol

No matching classes.

# REXML::Parsers::BaseParser

# Using the Pull Parser¶ ↑

This API is experimental, and subject to change.

    parser = PullParser.new( "<a>text<b att='val'/>txet</a>" )
    while parser.has_next?
      res = parser.next
      puts res[1]['att'] if res.start_tag? and res[0] == 'b'
    end

See the `PullEvent` class for information on the content of the results. The data is identical to the arguments passed for the various events to the `StreamListener` API.

Notice that:

    parser = PullParser.new( "<a>BAD DOCUMENT" )
    while parser.has_next?
      res = parser.next
      raise res[1] if res.error?
    end

Nat Price gave me some good ideas for the API.

### Constants

ATTDEF
ATTDEF_RE
ATTLISTDECL_PATTERN
ATTLISTDECL_START
ATTRIBUTE_PATTERN
ATTTYPE
ATTVALUE
CDATA_END
CDATA_PATTERN
CDATA_START
CLOSE_MATCH
COMBININGCHAR
COMMENT_PATTERN
COMMENT_START
DEFAULTDECL
DEFAULT_ENTITIES
DIGIT
DOCTYPE_END
DOCTYPE_START
ELEMENTDECL_PATTERN
ELEMENTDECL_START
ENCODING
ENTITYDECL
ENTITYDEF
ENTITYVALUE
ENTITY_START
ENUMERATEDTYPE
ENUMERATION
EREFERENCE
EXTENDER
EXTERNALID
EXTERNAL_ID_PUBLIC
EXTERNAL_ID_SYSTEM
GEDECL
INSTRUCTION_PATTERN
INSTRUCTION_START
LETTER
NAME
NAMECHAR
NCNAME_STR
NDATADECL
NMTOKEN
NMTOKENS
NOTATIONDECL_START
NOTATIONTYPE
PEDECL
PEDEF
PEREFERENCE
PUBIDCHAR

  `Entity` constants

PUBIDLITERAL
PUBLIC_ID
QNAME
QNAME_STR
REFERENCE
REFERENCE_RE
STANDALONE
SYSTEMENTITY
SYSTEMLITERAL
TAG_MATCH
TEXT_PATTERN
UNAME_STR

  Just for backward compatibility. For example, kramdown uses this. It's not used in `REXML`.

VERSION
XMLDECL_PATTERN
XMLDECL_START

### Attributes

source[R]

### Public Class Methods

new( source ) click to toggle source

                   # File rexml/parsers/baseparser.rb, line 115
    def initialize( source )
      self.stream = source
      @listeners = []
    end

### Public Instance Methods

add_listener( listener ) click to toggle source

                   # File rexml/parsers/baseparser.rb, line 120
    def add_listener( listener )
      @listeners << listener
    end

empty?() click to toggle source

Returns true if there are no more events

                   # File rexml/parsers/baseparser.rb, line 146
    def empty?
      return (@source.empty? and @stack.empty?)
    end

entity( reference, entities ) click to toggle source

                   # File rexml/parsers/baseparser.rb, line 438
    def entity( reference, entities )
      value = nil
      value = entities[ reference ] if entities
      if not value
        value = DEFAULT_ENTITIES[ reference ]
        value = value[2] if value
      end
      unnormalize( value, entities ) if value
    end

has_next?() click to toggle source

Returns true if there are more events. Synonymous with !empty?

                   # File rexml/parsers/baseparser.rb, line 151
    def has_next?
      return !(@source.empty? and @stack.empty?)
    end

normalize( input, entities=nil, entity_filter=nil ) click to toggle source

Escapes all possible entities

                   # File rexml/parsers/baseparser.rb, line 449
    def normalize( input, entities=nil, entity_filter=nil )
      copy = input.clone
      # Doing it like this rather than in a loop improves the speed
      copy.gsub!( EREFERENCE, '&amp;' )
      entities.each do |key, value|
        copy.gsub!( value, "&#{key};" ) unless entity_filter and
                                    entity_filter.include?(entity)
      end if entities
      copy.gsub!( EREFERENCE, '&amp;' )
      DEFAULT_ENTITIES.each do |key, value|
        copy.gsub!( value[3], value[1] )
      end
      copy
    end

peek(depth=0) click to toggle source

Peek at the `depth` event in the stack. The first element on the stack is at depth 0. If `depth` is -1, will parse to the end of the input stream and return the last event, which is always :end_document. Be aware that this causes the stream to be parsed up to the `depth` event, so you can effectively pre-parse the entire document (pull the entire thing into memory) using this method.

                   # File rexml/parsers/baseparser.rb, line 167
    def peek depth=0
      raise %Q[Illegal argument "#{depth}"] if depth < -1
      temp = []
      if depth == -1
        temp.push(pull()) until empty?
      else
        while @stack.size+temp.size < depth+1
          temp.push(pull())
        end
      end
      @stack += temp if temp.size > 0
      @stack[depth]
    end

position() click to toggle source

                   # File rexml/parsers/baseparser.rb, line 136
    def position
      if @source.respond_to? :position
        @source.position
      else
        # FIXME
        0
      end
    end

pull() click to toggle source

Returns the next event. This is a `PullEvent` object.

                   # File rexml/parsers/baseparser.rb, line 182
    def pull
      pull_event.tap do |event|
        @listeners.each do |listener|
          listener.receive event
        end
      end
    end

stream=( source ) click to toggle source

                   # File rexml/parsers/baseparser.rb, line 126
    def stream=( source )
      @source = SourceFactory.create_from( source )
      @closed = nil
      @document_status = nil
      @tags = []
      @stack = []
      @entities = []
      @nsstack = []
    end

unnormalize( string, entities=nil, filter=nil ) click to toggle source

Unescapes all possible entities

                   # File rexml/parsers/baseparser.rb, line 465
    def unnormalize( string, entities=nil, filter=nil )
      rv = string.clone
      rv.gsub!( /\r\n?/, "\n" )
      matches = rv.scan( REFERENCE_RE )
      return rv if matches.size == 0
      rv.gsub!( /&#0*((?:\d+)|(?:x[a-fA-F0-9]+));/ ) {
        m=$1
        m = "0#{m}" if m[0] == ?x
        [Integer(m)].pack('U*')
      }
      matches.collect!{|x|x[0]}.compact!
      if matches.size > 0
        matches.each do |entity_reference|
          unless filter and filter.include?(entity_reference)
            entity_value = entity( entity_reference, entities )
            if entity_value
              re = /&#{entity_reference};/
              rv.gsub!( re, entity_value )
            else
              er = DEFAULT_ENTITIES[entity_reference]
              rv.gsub!( er[0], er[2] ) if er
            end
          end
        end
        rv.gsub!( /&amp;/, '&' )
      end
      rv
    end

unshift(token) click to toggle source

Push an event back on the head of the stream. This method has (theoretically) infinite depth.

                   # File rexml/parsers/baseparser.rb, line 157
    def unshift token
      @stack.unshift(token)
    end