Hash
A class that defines the set of Attributes of an Element and provides operations for accessing elements in that set.
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='<'/>" doc.root.attributes['att'] #-> '<' doc.root.attributes['bar:att'] #-> '2'
# File rexml/element.rb, line 987
def [](name)
attr = get_attribute(name)
return attr.value unless attr.nil?
return nil
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 rexml/element.rb, line 1089
def []=( name, value )
if value.nil? # Delete the named attribute
attr = get_attribute(name)
delete attr
return
end
element_document = @element.document
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
raise ParseException.new(
"Namespace conflict in adding attribute \"#{value.name}\": "+
"Prefix \"#{old_attr.prefix}\" = "+
"\"#{@element.namespace(old_attr.prefix)}\" and prefix "+
"\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if
value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
@element.namespace( old_attr.prefix ) ==
@element.namespace( value.prefix )
store value.name, { old_attr.prefix => old_attr,
value.prefix => value }
else
store value.name, value
end
return @element
end
Adds an attribute, overriding any existing attribute by the same name. Namespaces are significant.
attribute |
An Attribute |
# File rexml/element.rb, line 1208
def add( attribute )
self[attribute.name] = attribute
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 rexml/element.rb, line 1176
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)
attr = nil
if old.kind_of? Hash # the supplied attribute is one of many
attr = 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
attr = old
res = super(name)
end
@element
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 the Attributes that were removed |
# File rexml/element.rb, line 1218
def delete_all( name )
rv = []
each_attribute { |attribute|
rv << attribute if attribute.expanded_name == name
}
rv.each{ |attr| attr.remove }
return rv
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 rexml/element.rb, line 1029
def each
each_attribute do |attr|
yield [attr.expanded_name, attr.value]
end
end
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 rexml/element.rb, line 1014
def each_attribute # :yields: attribute
each_value do |val|
if val.kind_of? Attribute
yield val
else
val.each_value { |atr| yield atr }
end
end
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 rexml/element.rb, line 1044
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
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 rexml/element.rb, line 1232
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
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 rexml/element.rb, line 1000
def length
c = 0
each_attribute { c+=1 }
c
end
# File rexml/element.rb, line 1150
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
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 rexml/element.rb, line 1134
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