Class: NdrImport::Helpers::File::XmlStreaming::Cursor

Inherits:
Object
  • Object
show all
Defined in:
lib/ndr_import/helpers/file/xml_streaming.rb

Overview

Object to track state as the XML is iterated over, and detect when an element of interest is entered.

Defined Under Namespace

Classes: StackItem

Instance Method Summary collapse

Constructor Details

#initialize(xpath, pattern_match_xpath) ⇒ Cursor

Returns a new instance of Cursor.



36
37
38
39
40
41
# File 'lib/ndr_import/helpers/file/xml_streaming.rb', line 36

def initialize(xpath, pattern_match_xpath)
  @xpath = xpath
  @pattern_match_xpath = pattern_match_xpath
  @stack = []
  @match_depth = nil
end

Instance Method Details

#enter(node) ⇒ Object



52
53
54
# File 'lib/ndr_import/helpers/file/xml_streaming.rb', line 52

def enter(node)
  @stack.push StackItem.new(node.name, node.attributes, node.empty_element?)
end

#in?(node) ⇒ Boolean

Has this cursor already passed inside a similar node? attribute comparison allows for e.g.: <SameName>

<SameName code="N"/>

</SameName>

Returns:

  • (Boolean)


48
49
50
# File 'lib/ndr_import/helpers/file/xml_streaming.rb', line 48

def in?(node)
  @stack.detect { |item| item.name == node.name && item.attrs == node.attributes }
end

#leave(_node) ⇒ Object



56
57
58
59
# File 'lib/ndr_import/helpers/file/xml_streaming.rb', line 56

def leave(_node)
  @stack.pop
  @match_depth = nil if @match_depth && @stack.length < @match_depth
end

#matches?Boolean

Does the element that the cursor is currently on match what is being looked for?

Returns:

  • (Boolean)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/ndr_import/helpers/file/xml_streaming.rb', line 63

def matches?
  # Can't match again if we're inside a match already:
  return false if @matched_depth

  match = current_stack_match?

  # "empty element" matches are yielded immediately, without
  # tagging the stack as having matched, because there won't
  # be an equivalent closing tag to end the match with later.
  if in_empty_element?
    @stack.pop
  elsif match
    @match_depth = @stack.length
  end

  match
end