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
Source
# File lib/rexml/element.rb, line 2159 def initialize element @element = element end
Creates and returns a new REXML::Attributes object. The element given by argument element is stored, but its own attributes are not modified:
ele = REXML::Element.new('foo') attrs = REXML::Attributes.new(ele) attrs.object_id == ele.attributes.object_id # => false
Other instance methods in class REXML::Attributes may refer to:
-
element.document. -
element.prefix. -
element.expanded_name.
Public Instance Methods
# File lib/rexml/element.rb, line 2184 def [](name) attr = get_attribute(name) attr&.value end
Returns the value for the attribute given by name, if it exists; otherwise nil. The value returned is the unnormalized attribute value, with entities expanded:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> ele.attributes['att'] # => "<" ele.attributes['bar:att'] # => "2" ele.attributes['nosuch'] # => nil
Related: get_attribute (returns an Attribute object).
Source
# File lib/rexml/element.rb, line 2335 def []=( name, value ) if value.nil? # Delete the named attribute delete name return end if value.kind_of? Attribute # Use attribute's expanded name to avoid inconsistency. # TODO: Explicitly document that inconsistent names are allowed, or raise/warn about inconsistency. name = value.expanded_name else doctype = @element.document&.doctype if doctype value = Text::normalize( value, doctype ) else value = Text::normalize( value, nil ) end value = Attribute.new(name, value) end value.element = @element store name, value @element end
When value is non-nil, assigns that to the attribute for the given name, overwriting the previous value if it exists:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> attrs = ele.attributes attrs['foo:att'] = '2' # => "2" attrs['baz:att'] = '3' # => "3"
When value is nil, deletes the attribute if it exists:
attrs['baz:att'] = nil attrs.include?('baz:att') # => false
Source
# File lib/rexml/element.rb, line 2443 def add( attribute ) self[attribute.expanded_name] = attribute end
Adds attribute attribute, replacing the previous attribute of the same name if it exists; returns attribute:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> attrs = ele.attributes attrs # => {"foo:att" => foo:att='1', "bar:att" => bar:att='2', "att" => att='<'} attrs.add(REXML::Attribute.new('foo:att', '2')) # => foo:att='2' attrs.add(REXML::Attribute.new('baz', '3')) # => baz='3' attrs.include?('baz') # => true
# File lib/rexml/element.rb, line 2415 def delete(attribute_or_name) key = attribute_or_name key = attribute_or_name.expanded_name if attribute_or_name.kind_of? Attribute super(key) @element end
Removes a specified attribute if it exists; returns the attributes’ element.
When string argument name is given, removes the attribute of that name if it exists:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> attrs = ele.attributes attrs.delete('foo:att') # => <ele bar:att='2' att='<'/> attrs.delete('foo:att') # => <ele bar:att='2' att='<'/>
When attribute argument attribute is given, removes that attribute if it exists:
attr = REXML::Attribute.new('bar:att', '2') attrs.delete(attr) # => <ele att='<'/> # => <ele att='<'/> attrs.delete(attr) # => <ele att='<'/> # => <ele/>
# File lib/rexml/element.rb, line 2466 def delete_all( name ) attributes = each_attribute.select do |attribute| # For <element xmlns:foo="url" ns:foo="value"/> # delete_all('foo') should not delete xmlns:foo="url" # because it is a namespace declaration, not a normal attribute. (!attribute.namespace_declaration? && attribute.name == name) || attribute.expanded_name == name end attributes.each do |attribute| delete attribute.expanded_name end attributes end
Removes all attributes matching the given name; returns an array of the removed attributes:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' att='<' foo:other='2' other='3'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' att='<' foo:other='2' other='3'/> attrs = ele.attributes attrs.delete_all('att') # => [foo:att='1', att='<'] attrs.each_attribute.map(&:expanded_name) #=> ['foo:other', 'other']
# File lib/rexml/element.rb, line 2282 def each return to_enum(__method__) unless block_given? each_attribute do |attr| yield [attr.expanded_name, attr.value] end end
Calls the given block with each expanded-name/value pair:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> ele.attributes.each do |expanded_name, value| p [expanded_name, value] end
Output:
["foo:att", "1"] ["bar:att", "2"] ["att", "<"]
This method doesn’t iterate attributes in the DTD. This may be a bug.
Source
# File lib/rexml/element.rb, line 2254 def each_attribute(&block) # :yields: attribute each_own_attribute(&block) end
Calls the given block with each REXML::Attribute object:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> ele.attributes.each_attribute do |attr| p [attr.class, attr] end
Output:
[REXML::Attribute, foo:att='1'] [REXML::Attribute, bar:att='2'] [REXML::Attribute, att='<']
This method doesn’t iterate attributes in the DTD. This may be a bug.
# File lib/rexml/element.rb, line 2308 def get_attribute( name ) fetch(name, nil) || attlist_attributes[name] end
Returns the REXML::Attribute object for the given name:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> attrs = ele.attributes attrs.get_attribute('foo:att') # => foo:att='1' attrs.get_attribute('foo:att').class # => REXML::Attribute attrs.get_attribute('bar:att') # => bar:att='2' attrs.get_attribute('att') # => att='<' attrs.get_attribute('nosuch') # => nil
# File lib/rexml/element.rb, line 2496 def get_attribute_ns(namespace, name) each_effective_attribute.find do |attribute| if attribute.namespace_declaration? # namespace declarations are not considered as attributes in this method. # For example: <elem1 xmlns="" xmlns:foo="url" /><elem2 xmlns="bar" xmlns:foo="url" /> # Both elem1.get_attribute_ns('', 'foo') and elem2.get_attribute_ns('bar', 'foo') # should not match. false elsif namespace.empty? && !attribute.prefix.empty? # If prefix is present, namespace url shouldn't be empty, so it never matches. # For example, <elem foo:att="value" />, even if attribute.namespace returns '', # it just means that namespace lookup failed, it shouldn't match. false else name == attribute.name && namespace == attribute.namespace() end end end
Returns the REXML::Attribute object among the attributes that matches the given namespace and name:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> attrs = ele.attributes attrs.get_attribute_ns('http://foo', 'att') # => foo:att='1' attrs.get_attribute_ns('http://foo', 'nosuch') # => nil
Source
# File lib/rexml/element.rb, line 2223 def length c = 0 each_attribute { c+=1 } c end
Returns the count of attributes:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> ele.attributes.length # => 3
Source
# File lib/rexml/element.rb, line 2383 def namespaces _calculate_namespaces end
Returns a hash of name/value pairs for the namespaces:
xml_string = '<a xmlns="foo" xmlns:x="bar" xmlns:y="twee" z="glorp"/>' d = REXML::Document.new(xml_string) d.root.attributes.namespaces # => {"xmlns"=>"foo", "x"=>"bar", "y"=>"twee"}
# File lib/rexml/element.rb, line 2370 def prefixes namespaces.keys - ['xmlns'] end
Returns an array of prefix strings in the attributes. The array does not include the default namespace declaration, if one exists.
xml_string = '<a xmlns="foo" xmlns:x="bar" xmlns:y="twee" z="glorp"/>' d = REXML::Document.new(xml_string) d.root.attributes.prefixes # => ["x", "y"]
# File lib/rexml/element.rb, line 2205 def to_a enum_for(:each_attribute).to_a end
Returns an array of REXML::Attribute objects representing the attributes:
xml_string = <<-EOT <root xmlns:foo="http://foo" xmlns:bar="http://bar"> <ele foo:att='1' bar:att='2' att='<'/> </root> EOT d = REXML::Document.new(xml_string) ele = d.root.elements['//ele'] # => <a foo:att='1' bar:att='2' att='<'/> attrs = ele.attributes.to_a # => [foo:att='1', bar:att='2', att='<'] attrs.first.class # => REXML::Attribute