class Nokogiri::XML::NodeSet - nokogiri-1.10.3 Documentation

# class Nokogiri::XML::NodeSet

A NodeSet contains a list of Nokogiri::XML::Node objects. Typically a NodeSet is return as a result of searching a Document via Nokogiri::XML::Searchable#css or Nokogiri::XML::Searchable#xpath

### Attributes

document[RW]

The Document this NodeSet is associated with

### Public Class Methods

new(document, list = []) { |self| ... } click to toggle source

Create a NodeSet with `document` defaulting to `list`

    # File lib/nokogiri/xml/node_set.rb, line 17
    def initialize document, list = []
      @document = document
      document.decorate(self)
      list.each { |x| self << x }
      yield self if block_given?
    end

### Public Instance Methods

%(*args)
Alias for: at
&(node_set) click to toggle source

Set Intersection — Returns a new NodeSet containing nodes common to the two NodeSets.

    static VALUE intersection(VALUE self, VALUE rb_other)
    {
      xmlNodeSetPtr node_set, other ;
      xmlNodeSetPtr intersection;

      if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
        rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");

      Data_Get_Struct(self, xmlNodeSet, node_set);
      Data_Get_Struct(rb_other, xmlNodeSet, other);

      intersection = xmlXPathIntersection(node_set, other);
      return Nokogiri_wrap_xml_node_set(intersection, rb_iv_get(self, "@document"));
    }

+(p1)
Alias for: |
-(node_set) click to toggle source

Difference - returns a new NodeSet that is a copy of this NodeSet, removing each item that also appears in `node_set`

    static VALUE minus(VALUE self, VALUE rb_other)
    {
      xmlNodeSetPtr node_set, other;
      xmlNodeSetPtr new;
      int j ;

      if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
        rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");

      Data_Get_Struct(self, xmlNodeSet, node_set);
      Data_Get_Struct(rb_other, xmlNodeSet, other);

      new = xmlXPathNodeSetMerge(NULL, node_set);
      for (j = 0 ; j < other->nodeNr ; ++j) {
        xpath_node_set_del(new, other->nodeTab[j]);
      }

      return Nokogiri_wrap_xml_node_set(new, rb_iv_get(self, "@document"));
    }

<<(p1)
Alias for: push
==(other) click to toggle source

Equality – Two NodeSets are equal if the contain the same number of elements and if each element is equal to the corresponding element in the other NodeSet

    # File lib/nokogiri/xml/node_set.rb, line 327
    def == other
      return false unless other.is_a?(Nokogiri::XML::NodeSet)
      return false unless length == other.length
      each_with_index do |node, i|
        return false unless node == other[i]
      end
      true
    end

>(selector) click to toggle source

Search this NodeSet's nodes' immediate children using CSS selector `selector`

    # File lib/nokogiri/xml/node_set.rb, line 105
    def > selector
      ns = document.root.namespaces
      xpath CSS.xpath_for(selector, :prefix => "./", :ns => ns).first
    end

[index] → Node or nil click to toggle source
[start, length] → NodeSet or nil
[range] → NodeSet or nil

Element reference - returns the node at `index`, or returns a NodeSet containing nodes starting at `start` and continuing for `length` elements, or returns a NodeSet containing nodes specified by `range`. Negative `indices` count backward from the end of the `node_set` (-1 is the last node). Returns nil if the `index` (or `start`) are out of range.

    static VALUE slice(int argc, VALUE *argv, VALUE self)
    {
      VALUE arg ;
      long beg, len ;
      xmlNodeSetPtr node_set;

      Data_Get_Struct(self, xmlNodeSet, node_set);

      if (argc == 2) {
        beg = NUM2LONG(argv[0]);
        len = NUM2LONG(argv[1]);
        if (beg < 0) {
          beg += node_set->nodeNr ;
        }
        return subseq(self, beg, len);
      }

      if (argc != 1) {
        rb_scan_args(argc, argv, "11", NULL, NULL);
      }
      arg = argv[0];

      if (FIXNUM_P(arg)) {
        return index_at(self, FIX2LONG(arg));
      }

      /* if arg is Range */
      switch (rb_range_beg_len(arg, &beg, &len, (long)node_set->nodeNr, 0)) {
      case Qfalse:
        break;
      case Qnil:
        return Qnil;
      default:
        return subseq(self, beg, len);
      }

      return index_at(self, NUM2LONG(arg));
    }

add_class(name) click to toggle source

Add the class attribute `name` to all Node objects in the NodeSet.

See Nokogiri::XML::Node#add_class for more information.

    # File lib/nokogiri/xml/node_set.rb, line 142
    def add_class name
      each do |el|
        el.add_class(name)
      end
      self
    end

after(datum) click to toggle source

Insert `datum` after the last Node in this NodeSet

    # File lib/nokogiri/xml/node_set.rb, line 65
    def after datum
      last.after datum
    end

append_class(name) click to toggle source

Append the class attribute `name` to all Node objects in the NodeSet.

See Nokogiri::XML::Node#append_class for more information.

    # File lib/nokogiri/xml/node_set.rb, line 154
    def append_class name
      each do |el|
        el.append_class(name)
      end
      self
    end

search *paths, [namespace-bindings, xpath-variable-bindings, custom-handler-class] click to toggle source

Search this object for `paths`, and return only the first result. `paths` must be one or more XPath or CSS queries.

See Nokogiri::XML::Searchable#search for more information.

Or, if passed an integer, index into the NodeSet:

    node_set.at(3) # same as node_set[3]

Calls superclass method Nokogiri::XML::Searchable#at

    # File lib/nokogiri/xml/node_set.rb, line 122
    def at *args
      if args.length == 1 && args.first.is_a?(Numeric)
        return self[args.first]
      end

      super(*args)
    end

Also aliased as: %
attr(key, value = nil, &block) click to toggle source

Set attributes on each Node in the NodeSet, or get an attribute from the first Node in the NodeSet.

To get an attribute from the first Node in a NodeSet:

    node_set.attr("href") # => "https://www.nokogiri.org"

Note that an empty NodeSet will return nil when `#attr` is called as a getter.

To set an attribute on each node, `key` can either be an attribute name, or a Hash of attribute names and values. When called as a setter, `#attr` returns the NodeSet.

If `key` is an attribute name, then either `value` or `block` must be passed.

If `key` is a Hash then attributes will be set for each key/value pair:

    node_set.attr("href" => "https://www.nokogiri.org", "class" => "member")

If `value` is passed, it will be used as the attribute value for all nodes:

    node_set.attr("href", "https://www.nokogiri.org")

If `block` is passed, it will be called on each Node object in the NodeSet and the return value used as the attribute value for that node:

    node_set.attr("class") { |node| node.name }

    # File lib/nokogiri/xml/node_set.rb, line 206
    def attr key, value = nil, &block
      unless key.is_a?(Hash) || (key && (value || block))
        return first ? first.attribute(key) : nil
      end

      hash = key.is_a?(Hash) ? key : { key => value }

      hash.each do |k,v|
        each do |node|
          node[k] = v || block.call(node)
        end
      end

      self
    end

Also aliased as: set, attribute
attribute(key, value = nil, &block)
Alias for: attr
before(datum) click to toggle source

Insert `datum` before the first Node in this NodeSet

    # File lib/nokogiri/xml/node_set.rb, line 59
    def before datum
      first.before datum
    end

children() click to toggle source

Returns a new NodeSet containing all the children of all the nodes in the NodeSet

    # File lib/nokogiri/xml/node_set.rb, line 339
    def children
      node_set = NodeSet.new(document)
      each do |node|
        node.children.each { |n| node_set.push(n) }
      end
      node_set
    end

clone()
Alias for: dup
css *rules, [namespace-bindings, custom-pseudo-class] click to toggle source

Search this node set for CSS `rules`. `rules` must be one or more CSS selectors. For example:

For more information see Nokogiri::XML::Searchable#css

    # File lib/nokogiri/xml/node_set.rb, line 79
    def css *args
      rules, handler, ns, _ = extract_params(args)
      paths = css_rules_to_xpath(rules, ns)

      inject(NodeSet.new(document)) do |set, node|
        set + xpath_internal(node, paths, handler, ns, nil)
      end
    end

delete(node) click to toggle source

Delete `node` from the Nodeset, if it is a member. Returns the deleted node if found, otherwise returns nil.

    static VALUE
    delete(VALUE self, VALUE rb_node)
    {
      xmlNodeSetPtr node_set;
      xmlNodePtr node;

      Check_Node_Set_Node_Type(rb_node);

      Data_Get_Struct(self, xmlNodeSet, node_set);
      Data_Get_Struct(rb_node, xmlNode, node);

      if (xmlXPathNodeSetContains(node_set, node)) {
        xpath_node_set_del(node_set, node);
        return rb_node;
      }
      return Qnil ;
    }

dup click to toggle source

Duplicate this NodeSet. Note that the Nodes contained in the NodeSet are not duplicated (similar to how Array and other Enumerable classes work).

    static VALUE duplicate(VALUE self)
    {
      xmlNodeSetPtr node_set;
      xmlNodeSetPtr dupl;

      Data_Get_Struct(self, xmlNodeSet, node_set);

      dupl = xmlXPathNodeSetMerge(NULL, node_set);

      return Nokogiri_wrap_xml_node_set(dupl, rb_iv_get(self, "@document"));
    }

Also aliased as: clone
each() { |self| ... } click to toggle source

Iterate over each node, yielding to `block`

    # File lib/nokogiri/xml/node_set.rb, line 234
    def each
      return to_enum unless block_given?

      0.upto(length - 1) do |x|
        yield self[x]
      end
      self
    end

empty?() click to toggle source

Is this NodeSet empty?

    # File lib/nokogiri/xml/node_set.rb, line 41
    def empty?
      length == 0
    end

filter(expr) click to toggle source

Filter this list for nodes that match `expr`

    # File lib/nokogiri/xml/node_set.rb, line 133
    def filter expr
      find_all { |node| node.matches?(expr) }
    end

first(n = nil) click to toggle source

Get the first element of the NodeSet.

    # File lib/nokogiri/xml/node_set.rb, line 26
    def first n = nil
      return self[0] unless n
      list = []
      [n, length].min.times { |i| list << self[i] }
      list
    end

include?(node) click to toggle source

Returns true if any member of node set equals `node`.

    static VALUE include_eh(VALUE self, VALUE rb_node)
    {
      xmlNodeSetPtr node_set;
      xmlNodePtr node;

      Check_Node_Set_Node_Type(rb_node);

      Data_Get_Struct(self, xmlNodeSet, node_set);
      Data_Get_Struct(rb_node, xmlNode, node);

      return (xmlXPathNodeSetContains(node_set, node) ? Qtrue : Qfalse);
    }

index(node = nil) { |member| ... } click to toggle source

Returns the index of the first node in self that is == to `node` or meets the given block. Returns nil if no match is found.

    # File lib/nokogiri/xml/node_set.rb, line 47
    def index(node = nil)
      if node
        warn "given block not used" if block_given?
        each_with_index { |member, j| return j if member == node }
      elsif block_given?
        each_with_index { |member, j| return j if yield(member) }
      end
      nil
    end

inner_html(*args) click to toggle source

Get the inner html of all contained Node objects

    # File lib/nokogiri/xml/node_set.rb, line 263
    def inner_html *args
      collect{|j| j.inner_html(*args) }.join('')
    end

inner_text() click to toggle source

Get the inner text of all contained Node objects

Note: This joins the text of all Node objects in the NodeSet:

    doc = Nokogiri::XML('<xml><a><d>foo</d><d>bar</d></a></xml>')
    doc.css('d').text # => "foobar"

Instead, if you want to return the text of all nodes in the NodeSet:

    doc.css('d').map(&:text) # => ["foo", "bar"]

See Nokogiri::XML::Node#content for more information.

    # File lib/nokogiri/xml/node_set.rb, line 256
    def inner_text
      collect(&:inner_text).join('')
    end

Also aliased as: text
inspect() click to toggle source

Return a nicely formated string representation

    # File lib/nokogiri/xml/node_set.rb, line 360
    def inspect
      "[#{map(&:inspect).join ', '}]"
    end

last() click to toggle source

Get the last element of the NodeSet.

    # File lib/nokogiri/xml/node_set.rb, line 35
    def last
      self[-1]
    end

length click to toggle source

Get the length of the node set

    static VALUE length(VALUE self)
    {
      xmlNodeSetPtr node_set;

      Data_Get_Struct(self, xmlNodeSet, node_set);

      return node_set ? INT2NUM(node_set->nodeNr) : INT2NUM(0);
    }

Also aliased as: size
pop() click to toggle source

Removes the last element from set and returns it, or `nil` if the set is empty

    # File lib/nokogiri/xml/node_set.rb, line 310
    def pop
      return nil if length == 0
      delete last
    end

push(node) click to toggle source

Append `node` to the NodeSet.

    static VALUE push(VALUE self, VALUE rb_node)
    {
      xmlNodeSetPtr node_set;
      xmlNodePtr node;

      Check_Node_Set_Node_Type(rb_node);

      Data_Get_Struct(self, xmlNodeSet, node_set);
      Data_Get_Struct(rb_node, xmlNode, node);

      xmlXPathNodeSetAdd(node_set, node);

      return self;
    }

Also aliased as: <<
remove()
Alias for: unlink
remove_attr(name) click to toggle source

Remove the attributed named `name` from all Node objects in the NodeSet

    # File lib/nokogiri/xml/node_set.rb, line 226
    def remove_attr name
      each { |el| el.delete name }
      self
    end

Also aliased as: remove_attribute
remove_attribute(name)
Alias for: remove_attr
remove_class(name = nil) click to toggle source

Remove the class attribute `name` from all Node objects in the NodeSet.

See Nokogiri::XML::Node#remove_class for more information.

    # File lib/nokogiri/xml/node_set.rb, line 166
    def remove_class name = nil
      each do |el|
        el.remove_class(name)
      end
      self
    end

reverse() click to toggle source

Returns a new NodeSet containing all the nodes in the NodeSet in reverse order

    # File lib/nokogiri/xml/node_set.rb, line 350
    def reverse
      node_set = NodeSet.new(document)
      (length - 1).downto(0) do |x|
        node_set.push self[x]
      end
      node_set
    end

set(key, value = nil, &block)
Alias for: attr
shift() click to toggle source

Returns the first element of the NodeSet and removes it. Returns `nil` if the set is empty.

    # File lib/nokogiri/xml/node_set.rb, line 318
    def shift
      return nil if length == 0
      delete first
    end

size()
Alias for: length
slice(index) → Node or nil click to toggle source
slice(start, length) → NodeSet or nil
slice(range) → NodeSet or nil

Element reference - returns the node at `index`, or returns a NodeSet containing nodes starting at `start` and continuing for `length` elements, or returns a NodeSet containing nodes specified by `range`. Negative `indices` count backward from the end of the `node_set` (-1 is the last node). Returns nil if the `index` (or `start`) are out of range.

    static VALUE slice(int argc, VALUE *argv, VALUE self)
    {
      VALUE arg ;
      long beg, len ;
      xmlNodeSetPtr node_set;

      Data_Get_Struct(self, xmlNodeSet, node_set);

      if (argc == 2) {
        beg = NUM2LONG(argv[0]);
        len = NUM2LONG(argv[1]);
        if (beg < 0) {
          beg += node_set->nodeNr ;
        }
        return subseq(self, beg, len);
      }

      if (argc != 1) {
        rb_scan_args(argc, argv, "11", NULL, NULL);
      }
      arg = argv[0];

      if (FIXNUM_P(arg)) {
        return index_at(self, FIX2LONG(arg));
      }

      /* if arg is Range */
      switch (rb_range_beg_len(arg, &beg, &len, (long)node_set->nodeNr, 0)) {
      case Qfalse:
        break;
      case Qnil:
        return Qnil;
      default:
        return subseq(self, beg, len);
      }

      return index_at(self, NUM2LONG(arg));
    }

text()
Alias for: inner_text
to_a click to toggle source

Return this list as an Array

    static VALUE to_array(VALUE self, VALUE rb_node)
    {
      xmlNodeSetPtr node_set ;
      VALUE list;
      int i;

      Data_Get_Struct(self, xmlNodeSet, node_set);

      list = rb_ary_new2(node_set->nodeNr);
      for(i = 0; i < node_set->nodeNr; i++) {
        VALUE elt = Nokogiri_wrap_xml_node_set_node(node_set->nodeTab[i], self);
        rb_ary_push( list, elt );
      }

      return list;
    }

Also aliased as: to_ary
to_ary()
Alias for: to_a
to_html(*args) click to toggle source

Convert this NodeSet to HTML

    # File lib/nokogiri/xml/node_set.rb, line 281
    def to_html *args
      if Nokogiri.jruby?
        options = args.first.is_a?(Hash) ? args.shift : {}
        if !options[:save_with]
          options[:save_with] = Node::SaveOptions::NO_DECLARATION | Node::SaveOptions::NO_EMPTY_TAGS | Node::SaveOptions::AS_HTML
        end
        args.insert(0, options)
      end
      map { |x| x.to_html(*args) }.join
    end

to_s() click to toggle source

Convert this NodeSet to a string.

    # File lib/nokogiri/xml/node_set.rb, line 275
    def to_s
      map(&:to_s).join
    end

to_xhtml(*args) click to toggle source

Convert this NodeSet to XHTML

    # File lib/nokogiri/xml/node_set.rb, line 294
    def to_xhtml *args
      map { |x| x.to_xhtml(*args) }.join
    end

to_xml(*args) click to toggle source

Convert this NodeSet to XML

    # File lib/nokogiri/xml/node_set.rb, line 300
    def to_xml *args
      map { |x| x.to_xml(*args) }.join
    end

unlink click to toggle source

Unlink this NodeSet and all Node objects it contains from their current context.

    static VALUE unlink_nodeset(VALUE self)
    {
      xmlNodeSetPtr node_set;
      int j, nodeNr ;

      Data_Get_Struct(self, xmlNodeSet, node_set);

      nodeNr = node_set->nodeNr ;
      for (j = 0 ; j < nodeNr ; j++) {
        if (! NOKOGIRI_NAMESPACE_EH(node_set->nodeTab[j])) {
          VALUE node ;
          xmlNodePtr node_ptr;
          node = Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[j]);
          rb_funcall(node, rb_intern("unlink"), 0); /* modifies the C struct out from under the object */
          Data_Get_Struct(node, xmlNode, node_ptr);
          node_set->nodeTab[j] = node_ptr ;
        }
      }
      return self ;
    }

Also aliased as: remove
wrap(html) click to toggle source

Wrap this NodeSet with `html`

    # File lib/nokogiri/xml/node_set.rb, line 269
    def wrap html
      map { |node| node.wrap html }
    end

xpath *paths, [namespace-bindings, variable-bindings, custom-handler-class] click to toggle source

Search this node set for XPath `paths`. `paths` must be one or more XPath queries.

For more information see Nokogiri::XML::Searchable#xpath

    # File lib/nokogiri/xml/node_set.rb, line 95
    def xpath *args
      paths, handler, ns, binds = extract_params(args)

      inject(NodeSet.new(document)) do |set, node|
        set + xpath_internal(node, paths, handler, ns, binds)
      end
    end

|(node_set) click to toggle source

Returns a new set built by merging the set and the elements of the given set.

    static VALUE set_union(VALUE self, VALUE rb_other)
    {
      xmlNodeSetPtr node_set, other;
      xmlNodeSetPtr new;

      if(!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet))
        rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");

      Data_Get_Struct(self, xmlNodeSet, node_set);
      Data_Get_Struct(rb_other, xmlNodeSet, other);

      new = xmlXPathNodeSetMerge(NULL, node_set);
      new = xmlXPathNodeSetMerge(new, other);

      return Nokogiri_wrap_xml_node_set(new, rb_iv_get(self, "@document"));
    }

Also aliased as: +