| 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. 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 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
# 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
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 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 |
# 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 }
# 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
}
# 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"
# 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
# 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
# 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']
# 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