class Nokogiri::XML::NodeSet

def attr(key, value = nil, &block)


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

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

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

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

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

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

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

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

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

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

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

attribute from the first Node in the NodeSet.
Set attributes on each Node in the NodeSet, or get an
##
def attr(key, value = nil, &block)
  unless key.is_a?(Hash) || (key && (value || block))
    return first&.attribute(key)
  end
  hash = key.is_a?(Hash) ? key : { key => value }
  hash.each do |k, v|
    each do |node|
      node[k] = v || yield(node)
    end
  end
  self
end