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
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
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"));
}
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"));
}
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
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
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));
}
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
Search this NodeSet for the first occurrence of CSS rules. Equivalent to css(rules).first See NodeSet#css for more information.
# File lib/nokogiri/xml/node_set.rb, line 169 def at_css *rules css(*rules).first end
Search this NodeSet for the first occurrence of XPath paths. Equivalent to xpath(paths).first See NodeSet#xpath for more information.
# File lib/nokogiri/xml/node_set.rb, line 160 def at_xpath *paths xpath(*paths).first end
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
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 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 ;
}
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"));
}
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
Is this NodeSet empty?
# File lib/nokogiri/xml/node_set.rb, line 38 def empty? length == 0 end
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
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
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);
}
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
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
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
Return a nicely formated string representation
# File lib/nokogiri/xml/node_set.rb, line 348 def inspect "[#{map { |c| c.inspect }.join ', '}]" end
Get the last element of the NodeSet.
# File lib/nokogiri/xml/node_set.rb, line 32 def last self[-1] end
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);
}
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
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;
}
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
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
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
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));
}
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;
}
# 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
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
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
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 ;
}
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
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
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"));
}
Generated with the Darkfish Rdoc Generator 2.