Class: Moxml::NodeSet

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/moxml/node_set.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nodes, context, parent_node = nil) ⇒ NodeSet

Returns a new instance of NodeSet.



9
10
11
12
13
14
# File 'lib/moxml/node_set.rb', line 9

def initialize(nodes, context, parent_node = nil)
  @nodes = Array(nodes)
  @context = context
  @wrapped = Array.new(@nodes.size)
  @parent_node = parent_node
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



7
8
9
# File 'lib/moxml/node_set.rb', line 7

def context
  @context
end

Instance Method Details

#+(other) ⇒ Object



73
74
75
# File 'lib/moxml/node_set.rb', line 73

def +(other)
  self.class.new(@nodes + other.native_nodes, @context, @parent_node)
end

#<<(node) ⇒ Object Also known as: push



77
78
79
80
81
82
# File 'lib/moxml/node_set.rb', line 77

def <<(node)
  native_node = node.is_a?(Node) ? node.native : node
  @nodes << native_node
  @wrapped << nil
  self
end

#==(other) ⇒ Object



102
103
104
105
106
107
108
# File 'lib/moxml/node_set.rb', line 102

def ==(other)
  self.class == other.class &&
    length == other.length &&
    @nodes.each_with_index.all? do |_node, index|
      self[index] == other[index]
    end
end

#[](index) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/moxml/node_set.rb', line 33

def [](index)
  case index
  when Integer
    actual = index.negative? ? @nodes.size + index : index
    return nil unless actual >= 0 && actual < @nodes.size

    @wrapped[actual] ||= wrap_with_parent(@nodes[actual])
  when Range
    self.class.new(@nodes[index], @context)
  end
end

#delete(node) ⇒ Object

Delete a node from the set Accepts both wrapped Moxml nodes and native nodes



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/moxml/node_set.rb', line 121

def delete(node)
  native_node = node.is_a?(Node) ? node.native : node
  idx = @nodes.index(native_node)
  if idx
    @nodes.delete_at(idx)
    @wrapped.delete_at(idx)
  else
    @nodes.delete(native_node)
  end
  self
end

#eachObject



23
24
25
26
27
28
29
30
31
# File 'lib/moxml/node_set.rb', line 23

def each
  return to_enum(:each) unless block_given?

  @nodes.each_with_index do |node, i|
    @wrapped[i] ||= wrap_with_parent(node)
    yield @wrapped[i]
  end
  self
end

#empty?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/moxml/node_set.rb', line 57

def empty?
  @nodes.empty?
end

#first(n = nil) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/moxml/node_set.rb', line 45

def first(n = nil)
  if n.nil?
    @nodes.empty? ? nil : self[0]
  else
    n.times.filter_map { |i| self[i] }
  end
end

#lastObject



53
54
55
# File 'lib/moxml/node_set.rb', line 53

def last
  @nodes.empty? ? nil : self[@nodes.size - 1]
end

#native_nodesObject

The raw native nodes — adapter-internal work only (issue #26). The public surface is wrapper-only: every Enumerable access goes through #each/#[]/#to_a, which wrap.



19
20
21
# File 'lib/moxml/node_set.rb', line 19

def native_nodes
  @nodes
end

#removeObject



114
115
116
117
# File 'lib/moxml/node_set.rb', line 114

def remove
  each(&:remove)
  self
end

#sizeObject Also known as: length



61
62
63
# File 'lib/moxml/node_set.rb', line 61

def size
  @nodes.size
end

#textObject



110
111
112
# File 'lib/moxml/node_set.rb', line 110

def text
  map(&:text).join
end

#to_aObject



66
67
68
69
70
71
# File 'lib/moxml/node_set.rb', line 66

def to_a
  @nodes.each_with_index do |_node, i|
    @wrapped[i] ||= wrap_with_parent(@nodes[i])
  end
  @wrapped.compact
end

#uniq_by_nativeObject

Deduplicate nodes based on native object identity This is crucial for XPath operations like descendant-or-self which may yield the same native node multiple times



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/moxml/node_set.rb', line 88

def uniq_by_native
  seen = {}
  unique_natives = @nodes.select do |native|
    id = native.object_id
    if seen[id]
      false
    else
      seen[id] = true
      true
    end
  end
  self.class.new(unique_natives, @context)
end