Class: SXRB::Callbacks

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

Instance Method Summary collapse

Constructor Details

#initializeCallbacks

Returns a new instance of Callbacks.


11
12
13
14
# File 'lib/sxrb/callbacks.rb', line 11

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

Instance Method Details

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


51
52
53
54
55
56
# File 'lib/sxrb/callbacks.rb', line 51

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

options:

recursive

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

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

#on_characters(chars) ⇒ Object


25
26
27
28
29
30
31
32
33
34
35
# File 'lib/sxrb/callbacks.rb', line 25

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


37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/sxrb/callbacks.rb', line 37

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


16
17
18
19
20
21
22
23
# File 'lib/sxrb/callbacks.rb', line 16

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