Class: Oga::XML::NodeSet

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

Overview

The NodeSet class contains a set of unique Node instances that can be queried and modified. Optionally NodeSet instances can take ownership of a node (besides just containing it). This allows the nodes to query their previous and next elements.

There are two types of sets:

  1. Regular node sets
  2. Owned node sets

Both behave similar to Ruby’s Array class. The difference between an owned and regular node set is that an owned set modifies nodes that are added or removed by certain operations. For example, when a node is added to an owned set the node_set attribute of said node points to the set it was just added to.

Owned node sets are used when building a DOM tree with Parser. By taking ownership of nodes in a set Oga makes it possible to use these sets as following:

document = Oga::XML::Document.new
element  = Oga::XML::Element.new

document.children << element

element.node_set == document.children # => true

If ownership was not handled then you’d have to manually set the element variable’s node_set attribute after pushing it into a set.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nodes = [], owner = nil) ⇒ NodeSet

Returns a new instance of NodeSet

Parameters:

  • nodes (Array) (defaults to: [])

    The nodes to add to the set.

  • owner (Oga::XML::NodeSet) (defaults to: nil)

    The owner of the set.



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/oga/xml/node_set.rb', line 40

def initialize(nodes = [], owner = nil)
  @nodes    = nodes
  @owner    = owner
  @existing = {}

  @nodes.each_with_index do |node, index|
    mark_existing(node)

    take_ownership(node, index) if @owner
  end
end

Instance Attribute Details

#ownerOga::XML::Node

Returns:



36
37
38
# File 'lib/oga/xml/node_set.rb', line 36

def owner
  @owner
end

Instance Method Details

#+(other) ⇒ Oga::XML::NodeSet

Creates a new set based on the current and the specified set. The newly created set does not inherit ownership rules of the current set.

Parameters:

Returns:



185
186
187
# File 'lib/oga/xml/node_set.rb', line 185

def +(other)
  self.class.new(to_a | other.to_a)
end

#==(other) ⇒ Object

Returns true if the current node set and the one given in other are equal to each other.

Parameters:



193
194
195
# File 'lib/oga/xml/node_set.rb', line 193

def ==(other)
  other.is_a?(NodeSet) && other.equal_nodes?(@nodes)
end

#[](index) ⇒ Oga::XML::Node

Returns the node for the given index.

Parameters:

  • index (Fixnum)

Returns:



169
170
171
# File 'lib/oga/xml/node_set.rb', line 169

def [](index)
  @nodes[index]
end

#attribute(name) ⇒ Array Also known as: attr

Returns the values of the given attribute.

Parameters:

  • name (String|Symbol)

    The name of the attribute.

Returns:

  • (Array)


256
257
258
259
260
261
262
263
264
265
266
# File 'lib/oga/xml/node_set.rb', line 256

def attribute(name)
  values = []

  @nodes.each do |node|
    if node.respond_to?(:attribute)
      values << node.attribute(name)
    end
  end

  values
end

#concat(other) ⇒ Object

Adds the nodes of the given node set to the current node set.

Parameters:



210
211
212
# File 'lib/oga/xml/node_set.rb', line 210

def concat(other)
  other.each { |node| push(node) }
end

#delete(node) ⇒ Object

Removes a node from the current set only.



240
241
242
243
244
245
246
247
248
249
250
# File 'lib/oga/xml/node_set.rb', line 240

def delete(node)
  removed = @nodes.delete(node)

  if removed
    unmark_existing(removed)

    remove_ownership(removed) if @owner
  end

  removed
end

#each {|| ... } ⇒ Object

Yields the supplied block for every node.

Yield Parameters:



55
56
57
58
59
# File 'lib/oga/xml/node_set.rb', line 55

def each
  return to_enum(:each) unless block_given?

  @nodes.each { |node| yield node }
end

#empty?TrueClass|FalseClass

Returns true if the set is empty.

Returns:

  • (TrueClass|FalseClass)


71
72
73
# File 'lib/oga/xml/node_set.rb', line 71

def empty?
  @nodes.empty?
end

#equal_nodes?(nodes) ⇒ Boolean

Returns true if the nodes given in nodes are equal to those specified in the current @nodes variable. This method allows two NodeSet instances to compare each other without the need of exposing @nodes to the public.

Parameters:

Returns:

  • (Boolean)


203
204
205
# File 'lib/oga/xml/node_set.rb', line 203

def equal_nodes?(nodes)
  @nodes == nodes
end

#index(node) ⇒ Fixnum

Returns the index of the given node.

Parameters:

Returns:

  • (Fixnum)


89
90
91
# File 'lib/oga/xml/node_set.rb', line 89

def index(node)
  @nodes.index(node)
end

#insert(index, node) ⇒ Object

Inserts a node into the set at the given index.

Parameters:

  • index (Fixnum)

    The index to insert the node at.

  • node (Oga::XML::Node)


155
156
157
158
159
160
161
162
163
# File 'lib/oga/xml/node_set.rb', line 155

def insert(index, node)
  return if exists?(node)

  @nodes.insert(index, node)

  mark_existing(node)

  take_ownership(node, index) if @owner
end

#inspectString

Returns:

  • (String)


286
287
288
289
290
# File 'lib/oga/xml/node_set.rb', line 286

def inspect
  values = @nodes.map(&:inspect).join(', ')

  "NodeSet(#{values})"
end

#lastOga::XML::Node

Returns the last node in the set.

Returns:



64
65
66
# File 'lib/oga/xml/node_set.rb', line 64

def last
  @nodes[-1]
end

#lengthFixnum Also known as: count, size

Returns the amount of nodes in the set.

Returns:

  • (Fixnum)


78
79
80
# File 'lib/oga/xml/node_set.rb', line 78

def length
  @nodes.length
end

#popOga::XML::Node

Pops a node from the end of the set.

Returns:



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/oga/xml/node_set.rb', line 139

def pop
  node = @nodes.pop

  if node
    unmark_existing(node)

    remove_ownership(node) if @owner
  end

  node
end

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

Pushes the node at the end of the set.

Parameters:



96
97
98
99
100
101
102
103
104
# File 'lib/oga/xml/node_set.rb', line 96

def push(node)
  return if exists?(node)

  @nodes << node

  mark_existing(node)

  take_ownership(node, length - 1) if @owner
end

#removeObject

Removes the current nodes from their owning set. The nodes are not removed from the current set.

This method is intended to remove nodes from an XML document/node.



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/oga/xml/node_set.rb', line 218

def remove
  sets = []

  # First we gather all the sets to remove nodse from, then we remove the
  # actual nodes. This is done as you can not reliably remove elements
  # from an Array while iterating on that same Array.
  @nodes.each do |node|
    if node.node_set
      sets << node.node_set

      node.node_set = nil
      node.next     = nil
      node.previous = nil
    end
  end

  sets.each do |set|
    @nodes.each { |node| set.delete(node) }
  end
end

#shiftOga::XML::Node

Shifts a node from the start of the set.

Returns:



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/oga/xml/node_set.rb', line 124

def shift
  node = @nodes.shift

  if node
    unmark_existing(node)

    remove_ownership(node) if @owner
  end

  node
end

#textString

Returns the text of all nodes in the set, ignoring comment nodes.

Returns:

  • (String)


273
274
275
276
277
278
279
280
281
282
283
# File 'lib/oga/xml/node_set.rb', line 273

def text
  text = ''

  @nodes.each do |node|
    if node.respond_to?(:text) and !node.is_a?(Comment)
      text << node.text
    end
  end

  text
end

#to_aArray

Converts the current set to an Array.

Returns:

  • (Array)


176
177
178
# File 'lib/oga/xml/node_set.rb', line 176

def to_a
  @nodes
end

#unshift(node) ⇒ Object

Pushes the node at the start of the set.

Parameters:



111
112
113
114
115
116
117
118
119
# File 'lib/oga/xml/node_set.rb', line 111

def unshift(node)
  return if exists?(node)

  @nodes.unshift(node)

  mark_existing(node)

  take_ownership(node, 0) if @owner
end