Class REXML::Attributes
In: lib/rexml/element.rb
Parent: Hash

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

Methods

<<   []   []=   add   delete   delete_all   each   each_attribute   get_attribute   get_attribute_ns   length   namespaces   new   prefixes   size   to_a  

Public Class methods

Constructor

element:the Element of which this is an Attribute

[Source]

     # File lib/rexml/element.rb, line 957
957:     def initialize element
958:       @element = element
959:     end

Public Instance methods

<<( attribute )

Alias for add

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'

[Source]

     # File lib/rexml/element.rb, line 972
972:     def [](name)
973:       attr = get_attribute(name)
974:       return attr.value unless attr.nil?
975:       return nil
976:     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

[Source]

      # File lib/rexml/element.rb, line 1074
1074:     def []=( name, value )
1075:       if value.nil?             # Delete the named attribute
1076:         attr = get_attribute(name)
1077:         delete attr
1078:         return
1079:       end
1080:       element_document = @element.document
1081:       unless value.kind_of? Attribute
1082:         if @element.document and @element.document.doctype
1083:           value = Text::normalize( value, @element.document.doctype )
1084:         else
1085:           value = Text::normalize( value, nil )
1086:         end
1087:         value = Attribute.new(name, value)
1088:       end
1089:       value.element = @element
1090:       old_attr = fetch(value.name, nil)
1091:       if old_attr.nil?
1092:         store(value.name, value)
1093:       elsif old_attr.kind_of? Hash
1094:         old_attr[value.prefix] = value
1095:       elsif old_attr.prefix != value.prefix
1096:         # Check for conflicting namespaces
1097:         raise ParseException.new( 
1098:           "Namespace conflict in adding attribute \"#{value.name}\": "+
1099:           "Prefix \"#{old_attr.prefix}\" = "+
1100:           "\"#{@element.namespace(old_attr.prefix)}\" and prefix "+
1101:           "\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if 
1102:           value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
1103:           @element.namespace( old_attr.prefix ) == 
1104:             @element.namespace( value.prefix )
1105:           store value.name, { old_attr.prefix   => old_attr,
1106:             value.prefix                => value }
1107:       else
1108:         store value.name, value
1109:       end
1110:       return @element
1111:     end

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

attribute:An Attribute

[Source]

      # File lib/rexml/element.rb, line 1193
1193:     def add( attribute )
1194:       self[attribute.name] = attribute
1195:     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'/>"

[Source]

      # File lib/rexml/element.rb, line 1161
1161:     def delete( attribute )
1162:       name = nil
1163:       prefix = nil
1164:       if attribute.kind_of? Attribute
1165:         name = attribute.name
1166:         prefix = attribute.prefix
1167:       else
1168:         attribute =~ Namespace::NAMESPLIT
1169:         prefix, name = $1, $2
1170:         prefix = '' unless prefix
1171:       end
1172:       old = fetch(name, nil)
1173:       attr = nil
1174:       if old.kind_of? Hash # the supplied attribute is one of many
1175:         attr = old.delete(prefix)
1176:         if old.size == 1
1177:           repl = nil
1178:           old.each_value{|v| repl = v}
1179:           store name, repl
1180:         end
1181:       elsif old.nil?
1182:         return @element
1183:       else # the supplied attribute is a top-level one
1184:         attr = old
1185:         res = super(name)
1186:       end
1187:       @element
1188:     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

[Source]

      # File lib/rexml/element.rb, line 1203
1203:     def delete_all( name )
1204:       rv = []
1205:       each_attribute { |attribute| 
1206:         rv << attribute if attribute.expanded_name == name
1207:       }
1208:       rv.each{ |attr| attr.remove }
1209:       return rv
1210:     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 }

[Source]

      # File lib/rexml/element.rb, line 1014
1014:     def each
1015:       each_attribute do |attr|
1016:         yield attr.expanded_name, attr.value
1017:       end
1018:     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
 }

[Source]

      # File lib/rexml/element.rb, line 999
 999:     def each_attribute # :yields: attribute
1000:       each_value do |val|
1001:         if val.kind_of? Attribute
1002:           yield val
1003:         else
1004:           val.each_value { |atr| yield atr }
1005:         end
1006:       end
1007:     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"

[Source]

      # File lib/rexml/element.rb, line 1029
1029:     def get_attribute( name )
1030:       attr = fetch( name, nil )
1031:       if attr.nil?
1032:         return nil if name.nil?
1033:         # Look for prefix
1034:         name =~ Namespace::NAMESPLIT
1035:         prefix, n = $1, $2
1036:         if prefix
1037:           attr = fetch( n, nil )
1038:           # check prefix
1039:           if attr == nil
1040:           elsif attr.kind_of? Attribute
1041:             return attr if prefix == attr.prefix
1042:           else
1043:             attr = attr[ prefix ]
1044:             return attr
1045:           end
1046:         end
1047:         element_document = @element.document
1048:         if element_document and element_document.doctype
1049:           expn = @element.expanded_name
1050:           expn = element_document.doctype.name if expn.size == 0
1051:           attr_val = element_document.doctype.attribute_of(expn, name)
1052:           return Attribute.new( name, attr_val ) if attr_val
1053:         end
1054:         return nil
1055:       end
1056:       if attr.kind_of? Hash
1057:         attr = attr[ @element.prefix ]
1058:       end
1059:       return attr
1060:     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

[Source]

      # File lib/rexml/element.rb, line 1217
1217:     def get_attribute_ns(namespace, name)
1218:       each_attribute() { |attribute|
1219:         if name == attribute.name &&
1220:           namespace == attribute.namespace()
1221:           return attribute
1222:         end
1223:       }
1224:       nil
1225:     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

[Source]

     # File lib/rexml/element.rb, line 985
985:     def length
986:       c = 0
987:       each_attribute { c+=1 }
988:       c
989:     end

[Source]

      # File lib/rexml/element.rb, line 1135
1135:     def namespaces
1136:       namespaces = {}
1137:       each_attribute do |attribute|
1138:         namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
1139:       end
1140:       if @element.document and @element.document.doctype
1141:         expn = @element.expanded_name
1142:         expn = @element.document.doctype.name if expn.size == 0
1143:         @element.document.doctype.attributes_of(expn).each {
1144:           |attribute|
1145:           namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
1146:         }
1147:       end
1148:       namespaces
1149:     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']

[Source]

      # File lib/rexml/element.rb, line 1119
1119:     def prefixes
1120:       ns = []
1121:       each_attribute do |attribute|
1122:         ns << attribute.name if attribute.prefix == 'xmlns'
1123:       end
1124:       if @element.document and @element.document.doctype
1125:         expn = @element.expanded_name
1126:         expn = @element.document.doctype.name if expn.size == 0
1127:         @element.document.doctype.attributes_of(expn).each {
1128:           |attribute|
1129:           ns << attribute.name if attribute.prefix == 'xmlns'
1130:         }
1131:       end
1132:       ns
1133:     end
size()

Alias for length

[Source]

     # File lib/rexml/element.rb, line 978
978:     def to_a
979:       values.flatten
980:     end

[Validate]