class REXML::Attributes

A class that defines the set of Attributes of an Element and provides operations for accessing elements in that set.

Public Class Methods

new(element) click to toggle source

Constructor

element

the Element of which this is an Attribute

# File lib/rexml/element.rb, line 993
def initialize element
  @element = element
end

Public Instance Methods

<<( attribute )
Alias for: add
[](name) click to toggle source

Fetches an attribute value. If you want to get the Attribute itself, use get_attribute()

name

an XPath attribute name. Namespaces are relevant here.

Returns

the String value of the matching attribute, or nil if no matching attribute was found. This is the unnormalized value (with entities expanded).

doc = Document.new "<a foo:att='1' bar:att='2' att='&lt;'/>"
doc.root.attributes['att']         #-> '<'
doc.root.attributes['bar:att']     #-> '2'
# File lib/rexml/element.rb, line 1008
def [](name)
  attr = get_attribute(name)
  return attr.value unless attr.nil?
  return nil
end
[]=( name, value ) click to toggle source

Sets an attribute, overwriting any existing attribute value by the same name. Namespace is significant.

name

the name of the attribute

value

(optional) If supplied, the value of the attribute. If nil, any existing matching attribute is deleted.

Returns

Owning element

doc = Document.new "<a x:foo='1' foo='3'/>"
doc.root.attributes['y:foo'] = '2'
doc.root.attributes['foo'] = '4'
doc.root.attributes['x:foo'] = nil
# File lib/rexml/element.rb, line 1112
def []=( name, value )
  if value.nil?             # Delete the named attribute
    attr = get_attribute(name)
    delete attr
    return
  end

  unless value.kind_of? Attribute
    if @element.document and @element.document.doctype
      value = Text::normalize( value, @element.document.doctype )
    else
      value = Text::normalize( value, nil )
    end
    value = Attribute.new(name, value)
  end
  value.element = @element
  old_attr = fetch(value.name, nil)
  if old_attr.nil?
    store(value.name, value)
  elsif old_attr.kind_of? Hash
    old_attr[value.prefix] = value
  elsif old_attr.prefix != value.prefix
    # Check for conflicting namespaces
    if value.prefix != "xmlns" and old_attr.prefix != "xmlns"
      old_namespace = old_attr.namespace
      new_namespace = value.namespace
      if old_namespace == new_namespace
        raise ParseException.new(
                "Namespace conflict in adding attribute \"#{value.name}\": "+
                "Prefix \"#{old_attr.prefix}\" = \"#{old_namespace}\" and "+
                "prefix \"#{value.prefix}\" = \"#{new_namespace}\"")
      end
    end
    store value.name, {old_attr.prefix => old_attr,
                       value.prefix    => value}
  else
    store value.name, value
  end
  return @element
end
add( attribute ) click to toggle source

Adds an attribute, overriding any existing attribute by the same name. Namespaces are significant.

attribute

An Attribute

# File lib/rexml/element.rb, line 1231
def add( attribute )
  self[attribute.name] = attribute
end
Also aliased as: <<
delete( attribute ) click to toggle source

Removes an attribute

attribute

either a String, which is the name of the attribute to remove – namespaces are significant here – or the attribute to remove.

Returns

the owning element

doc = Document.new "<a y:foo='0' x:foo='1' foo='3' z:foo='4'/>"
doc.root.attributes.delete 'foo'   #-> <a y:foo='0' x:foo='1' z:foo='4'/>"
doc.root.attributes.delete 'x:foo' #-> <a y:foo='0' z:foo='4'/>"
attr = doc.root.attributes.get_attribute('y:foo')
doc.root.attributes.delete attr    #-> <a z:foo='4'/>"
Calls superclass method Hash#delete
# File lib/rexml/element.rb, line 1201
def delete( attribute )
  name = nil
  prefix = nil
  if attribute.kind_of? Attribute
    name = attribute.name
    prefix = attribute.prefix
  else
    attribute =~ Namespace::NAMESPLIT
    prefix, name = $1, $2
    prefix = '' unless prefix
  end
  old = fetch(name, nil)
  if old.kind_of? Hash # the supplied attribute is one of many
    old.delete(prefix)
    if old.size == 1
      repl = nil
      old.each_value{|v| repl = v}
      store name, repl
    end
  elsif old.nil?
    return @element
  else # the supplied attribute is a top-level one
    super(name)
  end
  @element
end
delete_all( name ) click to toggle source

Deletes all attributes matching a name. Namespaces are significant.

name

A String; all attributes that match this path will be removed

Returns

an Array of the Attributes that were removed

# File lib/rexml/element.rb, line 1241
def delete_all( name )
  rv = []
  each_attribute { |attribute|
    rv << attribute if attribute.expanded_name == name
  }
  rv.each{ |attr| attr.remove }
  return rv
end
each() { |expanded_name, value| ... } click to toggle source

Iterates over each attribute of an Element, yielding the expanded name and value as a pair of Strings.

doc = Document.new '<a x="1" y="2"/>'
doc.root.attributes.each {|name, value| p name+" => "+value }
# File lib/rexml/element.rb, line 1051
def each
  return to_enum(__method__) unless block_given?
  each_attribute do |attr|
    yield [attr.expanded_name, attr.value]
  end
end
each_attribute() { |attribute| ... } click to toggle source

Iterates over the attributes of an Element. Yields actual Attribute nodes, not String values.

doc = Document.new '<a x="1" y="2"/>'
doc.root.attributes.each_attribute {|attr|
  p attr.expanded_name+" => "+attr.value
}
# File lib/rexml/element.rb, line 1035
def each_attribute # :yields: attribute
  return to_enum(__method__) unless block_given?
  each_value do |val|
    if val.kind_of? Attribute
      yield val
    else
      val.each_value { |atr| yield atr }
    end
  end
end
get_attribute( name ) click to toggle source

Fetches an attribute

name

the name by which to search for the attribute. Can be a prefix:name namespace name.

Returns

The first matching attribute, or nil if there was none. This

value is an Attribute node, not the String value of the attribute.

doc = Document.new '<a x:foo="1" foo="2" bar="3"/>'
doc.root.attributes.get_attribute("foo").value    #-> "2"
doc.root.attributes.get_attribute("x:foo").value  #-> "1"
# File lib/rexml/element.rb, line 1067
def get_attribute( name )
  attr = fetch( name, nil )
  if attr.nil?
    return nil if name.nil?
    # Look for prefix
    name =~ Namespace::NAMESPLIT
    prefix, n = $1, $2
    if prefix
      attr = fetch( n, nil )
      # check prefix
      if attr == nil
      elsif attr.kind_of? Attribute
        return attr if prefix == attr.prefix
      else
        attr = attr[ prefix ]
        return attr
      end
    end
    element_document = @element.document
    if element_document and element_document.doctype
      expn = @element.expanded_name
      expn = element_document.doctype.name if expn.size == 0
      attr_val = element_document.doctype.attribute_of(expn, name)
      return Attribute.new( name, attr_val ) if attr_val
    end
    return nil
  end
  if attr.kind_of? Hash
    attr = attr[ @element.prefix ]
  end
  return attr
end
get_attribute_ns(namespace, name) click to toggle source

The get_attribute_ns method retrieves a method by its namespace and name. Thus it is possible to reliably identify an attribute even if an XML processor has changed the prefix.

Method contributed by Henrik Martensson

# File lib/rexml/element.rb, line 1255
def get_attribute_ns(namespace, name)
  result = nil
  each_attribute() { |attribute|
    if name == attribute.name &&
      namespace == attribute.namespace() &&
      ( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
      # foo will match xmlns:foo, but only if foo isn't also an attribute
      result = attribute if !result or !namespace.empty? or
                            !attribute.fully_expanded_name.index(':')
    end
  }
  result
end
length() click to toggle source

Returns the number of attributes the owning Element contains.

doc = Document "<a x='1' y='2' foo:x='3'/>"
doc.root.attributes.length        #-> 3
# File lib/rexml/element.rb, line 1021
def length
  c = 0
  each_attribute { c+=1 }
  c
end
Also aliased as: size
namespaces() click to toggle source
# File lib/rexml/element.rb, line 1175
def namespaces
  namespaces = {}
  each_attribute do |attribute|
    namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
  end
  if @element.document and @element.document.doctype
    expn = @element.expanded_name
    expn = @element.document.doctype.name if expn.size == 0
    @element.document.doctype.attributes_of(expn).each {
      |attribute|
      namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
    }
  end
  namespaces
end
prefixes() click to toggle source

Returns an array of Strings containing all of the prefixes declared by this set of # attributes. The array does not include the default namespace declaration, if one exists.

doc = Document.new("<a xmlns='foo' xmlns:x='bar' xmlns:y='twee' "+
      "z='glorp' p:k='gru'/>")
prefixes = doc.root.attributes.prefixes    #-> ['x', 'y']
# File lib/rexml/element.rb, line 1159
def prefixes
  ns = []
  each_attribute do |attribute|
    ns << attribute.name if attribute.prefix == 'xmlns'
  end
  if @element.document and @element.document.doctype
    expn = @element.expanded_name
    expn = @element.document.doctype.name if expn.size == 0
    @element.document.doctype.attributes_of(expn).each {
      |attribute|
      ns << attribute.name if attribute.prefix == 'xmlns'
    }
  end
  ns
end
size()
Alias for: length
to_a() click to toggle source
# File lib/rexml/element.rb, line 1014
def to_a
  enum_for(:each_attribute).to_a
end