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.



44
45
46
47
48
49
# File 'lib/oga/xml/node_set.rb', line 44

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

  @nodes.each { |node| take_ownership(node) } if owner
end

Instance Attribute Details

#ownerOga::XML::Node

Returns:



38
39
40
# File 'lib/oga/xml/node_set.rb', line 38

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:



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

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:



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

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:



174
175
176
# File 'lib/oga/xml/node_set.rb', line 174

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)


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

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:



225
226
227
# File 'lib/oga/xml/node_set.rb', line 225

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

#delete(node) ⇒ Object

Removes a node from the current set only.



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

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

  remove_ownership(removed) if removed

  removed
end

#each {|| ... } ⇒ Object

Yields the supplied block for every node.

Yield Parameters:



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

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

#empty?TrueClass|FalseClass

Returns true if the set is empty.

Returns:

  • (TrueClass|FalseClass)


74
75
76
# File 'lib/oga/xml/node_set.rb', line 74

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)


216
217
218
# File 'lib/oga/xml/node_set.rb', line 216

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

#index(node) ⇒ Fixnum

Returns the index of the given node.

Parameters:

Returns:

  • (Fixnum)


96
97
98
# File 'lib/oga/xml/node_set.rb', line 96

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)


160
161
162
163
164
165
166
# File 'lib/oga/xml/node_set.rb', line 160

def insert(index, node)
  return if @nodes.include?(node)

  @nodes.insert(index, node)

  take_ownership(node)
end

#inspectString

Returns:

  • (String)


305
306
307
308
309
# File 'lib/oga/xml/node_set.rb', line 305

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

  "NodeSet(#{values})"
end

#lastOga::XML::Node

Returns the last node in the set.

Returns:



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

def last
  @nodes[-1]
end

#lengthFixnum Also known as: count, size

Returns the amount of nodes in the set.

Returns:

  • (Fixnum)


83
84
85
# File 'lib/oga/xml/node_set.rb', line 83

def length
  @nodes.length
end

#popOga::XML::Node

Pops a node from the end of the set.

Returns:



146
147
148
149
150
151
152
# File 'lib/oga/xml/node_set.rb', line 146

def pop
  node = @nodes.pop

  remove_ownership(node)

  node
end

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

Pushes the node at the end of the set.

Parameters:



105
106
107
108
109
110
111
# File 'lib/oga/xml/node_set.rb', line 105

def push(node)
  return if @nodes.include?(node)

  @nodes << node

  take_ownership(node)
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.



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/oga/xml/node_set.rb', line 235

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
    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:



133
134
135
136
137
138
139
# File 'lib/oga/xml/node_set.rb', line 133

def shift
  node = @nodes.shift

  remove_ownership(node)

  node
end

#textString

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

Returns:

  • (String)


290
291
292
293
294
295
296
297
298
299
300
# File 'lib/oga/xml/node_set.rb', line 290

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)


183
184
185
# File 'lib/oga/xml/node_set.rb', line 183

def to_a
  @nodes
end

#unshift(node) ⇒ Object

Pushes the node at the start of the set.

Parameters:



120
121
122
123
124
125
126
# File 'lib/oga/xml/node_set.rb', line 120

def unshift(node)
  return if @nodes.include?(node)

  @nodes.unshift(node)

  take_ownership(node)
end