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