Class: XmlNodeStream::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/xml_node_stream/parser.rb,
lib/xml_node_stream/parser/base.rb

Overview

The abstract parser class that wraps the actual parser implementation.

Defined Under Namespace

Modules: Base

Constant Summary collapse

SUPPORTED_PARSERS =
[:nokogiri, :libxml, :rexml]

Class Method Summary collapse

Class Method Details

.parse(io) {|Node| ... } ⇒ Node

Parse the document specified in io. This can be either a Stream, URI, Pathname, or String. If it is a String, it can either be a XML document, file system path, or URI. The parser will figure it out. If a block is given, it will be yielded to with each node as it is parsed.

Parameters:

  • io (IO, String, URI, Pathname)

    the input source to parse

Yields:

  • (Node)

    each node as it is parsed

Returns:

  • (Node)

    the root node of the parsed document



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/xml_node_stream/parser.rb', line 41

def parse(io, &block)
  close_stream = true
  io = URI.parse(io) if io.is_a?(String) && io.match?(%r{\Ahttp(s)?://})

  if io.is_a?(String) && io.match?(/<[^>]+>/m)
    io = StringIO.new(io)
  elsif io.is_a?(String)
    unless File.exist?(io)
      raise ArgumentError.new("File not found: #{io}")
    end
    io = File.open(io, "r:UTF-8")
  elsif io.is_a?(Pathname)
    unless io.exist?
      raise ArgumentError.new("File not found: #{io}")
    end
    io = io.open("r:UTF-8")
  elsif io.is_a?(URI)
    io = HttpStream.new(io)
  else
    close_stream = false
  end

  begin
    parser = parser_class(parser_name).new(&block)
    parser.parse_stream(io)
    parser.root
  ensure
    if close_stream
      begin
        io.close
      rescue
        # Ignore errors during close to ensure cleanup completes
        nil
      end
    end
  end
end

.parser_nameSymbol

Get the name of the current parser.

Returns:

  • (Symbol)

    the current parser name



30
31
32
# File 'lib/xml_node_stream/parser.rb', line 30

def parser_name
  @parser_name ||= :rexml
end

.parser_name=(parser) ⇒ Symbol

Set the parser implementation. The parser argument should be one of :nokogiri, :libxml, or :rexml. If this method is not called, it will default to :rexml which is the slowest choice possible. If you set the parser to one of the other values, though, you'll need to make sure you have the nokogiri gem or libxml-ruby gem installed.

Parameters:

  • parser (Symbol, String)

    the parser name (:nokogiri, :libxml, or :rexml)

Returns:

  • (Symbol)

    the parser name

Raises:

  • (ArgumentError)

    if parser is not one of the supported parsers



20
21
22
23
24
25
# File 'lib/xml_node_stream/parser.rb', line 20

def parser_name=(parser)
  parser_sym = parser&.to_sym
  raise ArgumentError.new("must be one of #{SUPPORTED_PARSERS.inspect}") unless SUPPORTED_PARSERS.include?(parser_sym)

  @parser_name = parser_sym
end