class Nokogiri::XML::NodeSet - nokogiri-1.6.3.1 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::Node#css or Nokogiri::XML::Node#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 14
    def initialize document, list = []
      @document = document
      document.decorate(self)
      list.each { |x| self << x }
      yield self if block_given?
    end

### Public Instance Methods

%(path, ns = document.root ? document.root.namespaces : {})
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)
    {
      nokogiriNodeSetTuple *tuple, *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, nokogiriNodeSetTuple, tuple);
      Data_Get_Struct(rb_other, nokogiriNodeSetTuple, other);

      intersection = xmlXPathIntersection(tuple->node_set, other->node_set);
      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)
    {
      nokogiriNodeSetTuple *tuple, *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, nokogiriNodeSetTuple, tuple);
      Data_Get_Struct(rb_other, nokogiriNodeSetTuple, other);

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

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

/(*paths)
Alias for: search
<<(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 319
    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 141
    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;
      nokogiriNodeSetTuple *tuple;
      Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
      node_set = tuple->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

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

    # File lib/nokogiri/xml/node_set.rb, line 181
    def add_class name
      each do |el|
        classes = el['class'].to_s.split(/\s+/)
        el['class'] = classes.push(name).uniq.join " "
      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 57
    def after datum
      last.after datum
    end

at(path, ns = document.root ? document.root.namespaces : {}) click to toggle source

If path is a string, search this document for `path` returning the first Node. Otherwise, index in to the array with `path`.

    # File lib/nokogiri/xml/node_set.rb, line 149
    def at path, ns = document.root ? document.root.namespaces : {}
      return self[path] if path.is_a?(Numeric)
      search(path, ns).first
    end

Also aliased as: %
at_css(*rules) click to toggle source

Search this NodeSet for the first occurrence of CSS `rules`. Equivalent to `css(rules).first` See #css for more information.

    # File lib/nokogiri/xml/node_set.rb, line 169
    def at_css *rules
      css(*rules).first
    end

at_xpath(*paths) click to toggle source

Search this NodeSet for the first occurrence of XPath `paths`. Equivalent to `xpath(paths).first` See #xpath for more information.

    # File lib/nokogiri/xml/node_set.rb, line 160
    def at_xpath *paths
      xpath(*paths).first
    end

attr(key, value = nil, &blk) click to toggle source

Set the attribute `key` to `value` or the return value of `blk` on all Node objects in the NodeSet.

    # File lib/nokogiri/xml/node_set.rb, line 212
    def attr key, value = nil, &blk
      unless Hash === key || key && (value || blk)
        return first.attribute(key)
      end

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

      hash.each { |k,v| each { |el| el[k] = v || blk[el] } }

      self
    end

Also aliased as: set, attribute
attribute(key, value = nil, &blk)
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 51
    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 331
    def children
      inject(NodeSet.new(document)) { |set, node| set += node.children }
    end

css(*paths) click to toggle source

Search this NodeSet for css `paths`

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

    # File lib/nokogiri/xml/node_set.rb, line 94
    def css *paths
      handler = ![
        Hash, String, Symbol
      ].include?(paths.last.class) ? paths.pop : nil

      ns = paths.last.is_a?(Hash) ? paths.pop : nil

      sub_set = NodeSet.new(document)

      each do |node|
        doc = node.document
        search_ns = ns || (doc.root ? doc.root.namespaces : {})

        xpaths = paths.map { |rule|
          [
            CSS.xpath_for(rule.to_s, :prefix => ".//", :ns => search_ns),
            CSS.xpath_for(rule.to_s, :prefix => "self::", :ns => search_ns)
          ].join(' | ')
        }

        sub_set += node.xpath(*(xpaths + [search_ns, handler].compact))
      end
      document.decorate(sub_set)
      sub_set
    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)
    {
        nokogiriNodeSetTuple *tuple;
        xmlNodePtr node;
        xmlNodeSetPtr cur;
        int i;

        if (!(rb_obj_is_kind_of(rb_node, cNokogiriXmlNode) || rb_obj_is_kind_of(rb_node, cNokogiriXmlNamespace)))
            rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");

        Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
        Data_Get_Struct(rb_node, xmlNode, node);
        cur = tuple->node_set;

        if (xmlXPathNodeSetContains(cur, node)) {
            for (i = 0; i < cur->nodeNr; i++)
                if (cur->nodeTab[i] == node) break;

            cur->nodeNr--;
            for (;i < cur->nodeNr;i++)
                cur->nodeTab[i] = cur->nodeTab[i + 1];
            cur->nodeTab[cur->nodeNr] = NULL;
            return rb_node;
        }
        return Qnil ;
    }

dup click to toggle source

Duplicate this node set

    static VALUE duplicate(VALUE self)
    {
      nokogiriNodeSetTuple *tuple;
      xmlNodeSetPtr dupl;

      Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);

      dupl = xmlXPathNodeSetMerge(NULL, tuple->node_set);

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

each() { |self| ... } click to toggle source

Iterate over each node, yielding to `block`

    # File lib/nokogiri/xml/node_set.rb, line 235
    def each(&block)
      0.upto(length - 1) do |x|
        yield self[x]
      end
    end

empty?() click to toggle source

Is this NodeSet empty?

    # File lib/nokogiri/xml/node_set.rb, line 38
    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 175
    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 23
    def first n = nil
      return self[0] unless n
      list = []
      n.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)
    {
      nokogiriNodeSetTuple *tuple;
      xmlNodePtr node;

      if(!(rb_obj_is_kind_of(rb_node, cNokogiriXmlNode) || rb_obj_is_kind_of(rb_node, cNokogiriXmlNamespace)))
        rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");

      Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
      Data_Get_Struct(rb_node, xmlNode, node);

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

index(node) click to toggle source

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

    # File lib/nokogiri/xml/node_set.rb, line 44
    def index(node)
      each_with_index { |member, j| return j if member == node }
      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 250
    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

    # File lib/nokogiri/xml/node_set.rb, line 243
    def inner_text
      collect{|j| j.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 348
    def inspect
      "[#{map { |c| c.inspect }.join ', '}]"
    end

last() click to toggle source

Get the last element of the NodeSet.

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

length click to toggle source

Get the length of the node set

    static VALUE length(VALUE self)
    {
      nokogiriNodeSetTuple *tuple;
      Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);

      return tuple->node_set ? INT2NUM(tuple->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 302
    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)
    {
      nokogiriNodeSetTuple *tuple;
      xmlNodePtr node;

      if(!(rb_obj_is_kind_of(rb_node, cNokogiriXmlNode) || rb_obj_is_kind_of(rb_node, cNokogiriXmlNamespace)))
        rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace");

      Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
      Data_Get_Struct(rb_node, xmlNode, node);
      xmlXPathNodeSetAdd(tuple->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 228
    def remove_attr name
      each { |el| el.delete name }
      self
    end

remove_class(name = nil) click to toggle source

Remove the class attribute `name` from all Node objects in the NodeSet. If `name` is nil, remove the class attribute from all Nodes in the NodeSet.

    # File lib/nokogiri/xml/node_set.rb, line 193
    def remove_class name = nil
      each do |el|
        if name
          classes = el['class'].to_s.split(/\s+/)
          if classes.empty?
            el.delete 'class'
          else
            el['class'] = (classes - [name]).uniq.join " "
          end
        else
          el.delete "class"
        end
      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 338
    def reverse
      node_set = NodeSet.new(document)
      (length - 1).downto(0) do |x|
        node_set.push self[x]
      end
      node_set
    end

search(*paths) click to toggle source

Search this document for `paths`

For more information see Nokogiri::XML::Node#css and Nokogiri::XML::Node#xpath

    # File lib/nokogiri/xml/node_set.rb, line 69
    def search *paths
      handler = ![
        Hash, String, Symbol
      ].include?(paths.last.class) ? paths.pop : nil

      ns = paths.last.is_a?(Hash) ? paths.pop : nil

      sub_set = NodeSet.new(document)

      paths.each do |path|
        sub_set += send(
          path =~ /^(\.\/|\/|\.\.|\.$)/ ? :xpath : :css,
          *(paths + [ns, handler]).compact
        )
      end

      document.decorate(sub_set)
      sub_set
    end

Also aliased as: /
set(key, value = nil, &blk)
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 310
    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;
      nokogiriNodeSetTuple *tuple;
      Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
      node_set = tuple->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 set;
      VALUE *elts;
      VALUE list;
      int i;
      nokogiriNodeSetTuple *tuple;

      Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
      set = tuple->node_set;

      elts = calloc((size_t)set->nodeNr, sizeof(VALUE *));
      for(i = 0; i < set->nodeNr; i++) {
        if (XML_NAMESPACE_DECL == set->nodeTab[i]->type)
          elts[i] = Nokogiri_wrap_xml_namespace2(rb_iv_get(self, "@document"), (xmlNsPtr)(set->nodeTab[i]));
        else
          elts[i] = Nokogiri_wrap_xml_node(Qnil, set->nodeTab[i]);
      }

      list = rb_ary_new4((long)set->nodeNr, elts);

      /*free(elts); */

      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 273
    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 267
    def to_s
      map { |x| x.to_s }.join
    end

to_xhtml(*args) click to toggle source

Convert this NodeSet to XHTML

    # File lib/nokogiri/xml/node_set.rb, line 286
    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 292
    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 ;
      nokogiriNodeSetTuple *tuple;

      Data_Get_Struct(self, nokogiriNodeSetTuple, tuple);
      node_set = tuple->node_set;
      nodeNr = node_set->nodeNr ;
      for (j = 0 ; j < nodeNr ; j++) {
        if (XML_NAMESPACE_DECL != node_set->nodeTab[j]->type) {
          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, &blk) click to toggle source

Wrap this NodeSet with `html` or the results of the builder in `blk`

    # File lib/nokogiri/xml/node_set.rb, line 256
    def wrap(html, &blk)
      each do |j|
        new_parent = document.parse(html).first
        j.add_next_sibling(new_parent)
        new_parent.add_child(j)
      end
      self
    end

xpath(*paths) click to toggle source

Search this NodeSet for XPath `paths`

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

    # File lib/nokogiri/xml/node_set.rb, line 124
    def xpath *paths
      handler = ![
        Hash, String, Symbol
      ].include?(paths.last.class) ? paths.pop : nil

      ns = paths.last.is_a?(Hash) ? paths.pop : nil

      sub_set = NodeSet.new(document)
      each do |node|
        sub_set += node.xpath(*(paths + [ns, handler].compact))
      end
      document.decorate(sub_set)
      sub_set
    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)
    {
      nokogiriNodeSetTuple *tuple, *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, nokogiriNodeSetTuple, tuple);
      Data_Get_Struct(rb_other, nokogiriNodeSetTuple, other);

      new = xmlXPathNodeSetMerge(NULL, tuple->node_set);
      new = xmlXPathNodeSetMerge(new, other->node_set);

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

Also aliased as: +