A class that defines the set of Attributes
of an Element
and provides operations for accessing elements in that set.
# File tmp/rubies/ruby-2.7.6/lib/rexml/element.rb, line 993
def initialize element
@element = element
end
# File tmp/rubies/ruby-2.7.6/lib/rexml/element.rb, line 1008
def [](name)
attr = get_attribute(name)
return attr.value unless attr.nil?
return nil
end
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, ornil
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='<'/>" doc.root.attributes['att'] #-> '<' doc.root.attributes['bar:att'] #-> '2'
# File tmp/rubies/ruby-2.7.6/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
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 tmp/rubies/ruby-2.7.6/lib/rexml/element.rb, line 1231
def add( attribute )
self[attribute.name] = attribute
end
Adds an attribute, overriding any existing attribute by the same name. Namespaces are significant.
- attribute
-
An
Attribute
# File tmp/rubies/ruby-2.7.6/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
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'/>"
# File tmp/rubies/ruby-2.7.6/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
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 theAttributes
that were removed
# File tmp/rubies/ruby-2.7.6/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
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 tmp/rubies/ruby-2.7.6/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
# File tmp/rubies/ruby-2.7.6/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
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 tmp/rubies/ruby-2.7.6/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
# File tmp/rubies/ruby-2.7.6/lib/rexml/element.rb, line 1021
def length
c = 0
each_attribute { c+=1 }
c
end
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 tmp/rubies/ruby-2.7.6/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
# File tmp/rubies/ruby-2.7.6/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
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 tmp/rubies/ruby-2.7.6/lib/rexml/element.rb, line 1014
def to_a
enum_for(:each_attribute).to_a
end