Class: SXRB::Callbacks

Inherits:
Object
  • Object
show all
Includes:
LibXML::XML::SaxParser::Callbacks
Defined in:
lib/sxrb/callbacks.rb

Overview

This class provides callbacks for SAX API which are configured with sxrb DSL. It’s behavior is configured by DSL via Proxy class objects, and should not be used outside of this scope. Currently it has only been tested with LibXML implementation of SAX, but set of method that object needs to provide is defined by standard, so using it with different backend should be automatic.

Instance Method Summary collapse

Constructor Details

#initializeCallbacks

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Callbacks.



18
19
20
21
# File 'lib/sxrb/callbacks.rb', line 18

def initialize
  @stack = []
  @rules_map = Hash.new {|h,k| h[k] = Rules.new}
end

Instance Method Details

#add_callback(type, rule_path, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



62
63
64
65
66
67
# File 'lib/sxrb/callbacks.rb', line 62

def add_callback(type, rule_path, &block)
  @rules_map[Regexp.new "^#{rule_path}$"].tap do |rules|
    rules.rules[type] = block
    rules.recursive = (type == :element) # true / false
  end
end

#add_rule(rule, rule_path, options) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



70
71
72
73
74
# File 'lib/sxrb/callbacks.rb', line 70

def add_rule(rule, rule_path, options)
  operator = options[:recursive] ? '.*' : ' '
  new_rule = rule_path + operator + rule
  new_rule.strip
end

#on_characters(chars) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/sxrb/callbacks.rb', line 34

def on_characters(chars)
  if @stack.last.is_a? TextNode
    @stack.last.append_text chars
  else
    TextNode.new(chars).tap do |node|
      invoke_callback(:characters, node)
      @stack.push node
      @current_element.append node if @current_element
    end
  end
end

#on_end_element_ns(name, prefix, uri) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/sxrb/callbacks.rb', line 47

def on_end_element_ns(name, prefix, uri)
  @stack.pop if @stack.last.is_a? TextNode

  if @current_element
    invoke_callback(:element, @current_element) if current_matching_rules.any?(&:recursive)
    @current_element = @current_element.parent
  end

  invoke_callback(:end, @stack.last)
  @stack.pop.tap do |node|
    raise SXRB::TagMismatchError if node.name != name
  end
end

#on_start_element_ns(name, attributes, prefix, uri, namespaces) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



24
25
26
27
28
29
30
31
# File 'lib/sxrb/callbacks.rb', line 24

def on_start_element_ns(name, attributes, prefix, uri, namespaces)
  Node.new(name, attributes, prefix, uri, namespaces).tap do |node|
    @stack.push(node)
    invoke_callback(:start, node)
    @current_element.append node if @current_element
    @current_element = node if current_matching_rules.any?(&:recursive) || @current_element
  end
end