| 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.
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. |
doc = Document.new "<a foo:att='1' bar:att='2' att='3'/>" doc.root.attributes['att'] #-> '3' doc.root.attributes['bar:att'] #-> '2'
# File lib/rexml/element.rb, line 1014
1014: def [](name)
1015: attr = get_attribute(name)
1016: return attr.value unless attr.nil?
1017: return nil
1018: 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 lib/rexml/element.rb, line 1116
1116: def []=( name, value )
1117: if value.nil? # Delete the named attribute
1118: attr = get_attribute(name)
1119: delete attr
1120: return
1121: end
1122: value = Attribute.new(name, value) unless value.kind_of? Attribute
1123: value.element = @element
1124: old_attr = fetch(value.name, nil)
1125: if old_attr.nil?
1126: store(value.name, value)
1127: elsif old_attr.kind_of? Hash
1128: old_attr[value.prefix] = value
1129: elsif old_attr.prefix != value.prefix
1130: # Check for conflicting namespaces
1131: raise ParseException.new(
1132: "Namespace conflict in adding attribute \"#{value.name}\": "+
1133: "Prefix \"#{old_attr.prefix}\" = "+
1134: "\"#{@element.namespace(old_attr.prefix)}\" and prefix "+
1135: "\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if
1136: value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
1137: @element.namespace( old_attr.prefix ) ==
1138: @element.namespace( value.prefix )
1139: store value.name, { old_attr.prefix => old_attr,
1140: value.prefix => value }
1141: else
1142: store value.name, value
1143: end
1144: return @element
1145: 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 lib/rexml/element.rb, line 1195
1195: def delete( attribute )
1196: name = nil
1197: prefix = nil
1198: if attribute.kind_of? Attribute
1199: name = attribute.name
1200: prefix = attribute.prefix
1201: else
1202: attribute =~ Namespace::NAMESPLIT
1203: prefix, name = $1, $2
1204: prefix = '' unless prefix
1205: end
1206: old = fetch(name, nil)
1207: attr = nil
1208: if old.kind_of? Hash # the supplied attribute is one of many
1209: attr = old.delete(prefix)
1210: if old.size == 1
1211: repl = nil
1212: old.each_value{|v| repl = v}
1213: store name, repl
1214: end
1215: elsif old.nil?
1216: return @element
1217: else # the supplied attribute is a top-level one
1218: attr = old
1219: res = super(name)
1220: end
1221: @element
1222: 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 lib/rexml/element.rb, line 1237
1237: def delete_all( name )
1238: rv = []
1239: each_attribute { |attribute|
1240: rv << attribute if attribute.expanded_name == name
1241: }
1242: rv.each{ |attr| attr.remove }
1243: return rv
1244: end
Itterates 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 1056
1056: def each
1057: each_attribute do |attr|
1058: yield attr.expanded_name, attr.value
1059: end
1060: end
Itterates 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 1041
1041: def each_attribute # :yields: attribute
1042: each_value do |val|
1043: if val.kind_of? Attribute
1044: yield val
1045: else
1046: val.each_value { |atr| yield atr }
1047: end
1048: end
1049: 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 lib/rexml/element.rb, line 1071
1071: def get_attribute( name )
1072: attr = fetch( name, nil )
1073: if attr.nil?
1074: return nil if name.nil?
1075: # Look for prefix
1076: name =~ Namespace::NAMESPLIT
1077: prefix, n = $1, $2
1078: if prefix
1079: attr = fetch( n, nil )
1080: # check prefix
1081: if attr == nil
1082: elsif attr.kind_of? Attribute
1083: return attr if prefix == attr.prefix
1084: else
1085: attr = attr[ prefix ]
1086: return attr
1087: end
1088: end
1089: element_document = @element.document
1090: if element_document and element_document.doctype
1091: expn = @element.expanded_name
1092: expn = element_document.doctype.name if expn.size == 0
1093: attr_val = element_document.doctype.attribute_of(expn, name)
1094: return Attribute.new( name, attr_val ) if attr_val
1095: end
1096: return nil
1097: end
1098: if attr.kind_of? Hash
1099: attr = attr[ @element.prefix ]
1100: end
1101: return attr
1102: 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 lib/rexml/element.rb, line 1251
1251: def get_attribute_ns(namespace, name)
1252: each_attribute() { |attribute|
1253: if name == attribute.name &&
1254: namespace == attribute.namespace()
1255: return attribute
1256: end
1257: }
1258: nil
1259: end
# File lib/rexml/element.rb, line 1169
1169: def namespaces
1170: namespaces = {}
1171: each_attribute do |attribute|
1172: namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
1173: end
1174: if @element.document and @element.document.doctype
1175: expn = @element.expanded_name
1176: expn = @element.document.doctype.name if expn.size == 0
1177: @element.document.doctype.attributes_of(expn).each {
1178: |attribute|
1179: namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
1180: }
1181: end
1182: namespaces
1183: 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 lib/rexml/element.rb, line 1153
1153: def prefixes
1154: ns = []
1155: each_attribute do |attribute|
1156: ns << attribute.name if attribute.prefix == 'xmlns'
1157: end
1158: if @element.document and @element.document.doctype
1159: expn = @element.expanded_name
1160: expn = @element.document.doctype.name if expn.size == 0
1161: @element.document.doctype.attributes_of(expn).each {
1162: |attribute|
1163: ns << attribute.name if attribute.prefix == 'xmlns'
1164: }
1165: end
1166: ns
1167: end