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

#nodesObject (readonly)

Returns the value of attribute nodes.



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

def nodes
  @nodes
end

Instance Method Details

#+(other) ⇒ Object



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

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

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



70
71
72
73
74
75
76
# File 'lib/moxml/node_set.rb', line 70

def <<(node)
  # If it's a wrapped Moxml node, unwrap to native before storing
  native_node = node.respond_to?(:native) ? node.native : node
  @nodes << native_node
  @wrapped << nil
  self
end

#==(other) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/moxml/node_set.rb', line 96

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



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/moxml/node_set.rb', line 26

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



115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/moxml/node_set.rb', line 115

def delete(node)
  # If it's a wrapped Moxml node, unwrap to native
  native_node = node.respond_to?(:native) ? 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



16
17
18
19
20
21
22
23
24
# File 'lib/moxml/node_set.rb', line 16

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)


50
51
52
# File 'lib/moxml/node_set.rb', line 50

def empty?
  @nodes.empty?
end

#first(n = nil) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/moxml/node_set.rb', line 38

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

#lastObject



46
47
48
# File 'lib/moxml/node_set.rb', line 46

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

#removeObject



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

def remove
  each(&:remove)
  self
end

#sizeObject Also known as: length



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

def size
  @nodes.size
end

#textObject



104
105
106
# File 'lib/moxml/node_set.rb', line 104

def text
  map(&:text).join
end

#to_aObject



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

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



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/moxml/node_set.rb', line 82

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