| 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 996
996: def [](name)
997: attr = get_attribute(name)
998: return attr.value unless attr.nil?
999: return nil
1000: 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 1098
1098: def []=( name, value )
1099: if value.nil? # Delete the named attribute
1100: attr = get_attribute(name)
1101: delete attr
1102: return
1103: end
1104: value = Attribute.new(name, value) unless value.kind_of? Attribute
1105: value.element = @element
1106: old_attr = fetch(value.name, nil)
1107: if old_attr.nil?
1108: store(value.name, value)
1109: elsif old_attr.kind_of? Hash
1110: old_attr[value.prefix] = value
1111: elsif old_attr.prefix != value.prefix
1112: # Check for conflicting namespaces
1113: raise ParseException.new(
1114: "Namespace conflict in adding attribute \"#{value.name}\": "+
1115: "Prefix \"#{old_attr.prefix}\" = "+
1116: "\"#{@element.namespace(old_attr.prefix)}\" and prefix "+
1117: "\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if
1118: value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
1119: @element.namespace( old_attr.prefix ) ==
1120: @element.namespace( value.prefix )
1121: store value.name, { old_attr.prefix => old_attr,
1122: value.prefix => value }
1123: else
1124: store value.name, value
1125: end
1126: return @element
1127: 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 1177
1177: def delete( attribute )
1178: name = nil
1179: prefix = nil
1180: if attribute.kind_of? Attribute
1181: name = attribute.name
1182: prefix = attribute.prefix
1183: else
1184: attribute =~ Namespace::NAMESPLIT
1185: prefix, name = $1, $2
1186: prefix = '' unless prefix
1187: end
1188: old = fetch(name, nil)
1189: attr = nil
1190: if old.kind_of? Hash # the supplied attribute is one of many
1191: attr = old.delete(prefix)
1192: if old.size == 1
1193: repl = nil
1194: old.each_value{|v| repl = v}
1195: store name, repl
1196: end
1197: elsif old.nil?
1198: return @element
1199: else # the supplied attribute is a top-level one
1200: attr = old
1201: res = super(name)
1202: end
1203: @element
1204: 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 1219
1219: def delete_all( name )
1220: rv = []
1221: each_attribute { |attribute|
1222: rv << attribute if attribute.expanded_name == name
1223: }
1224: rv.each{ |attr| attr.remove }
1225: return rv
1226: 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 1038
1038: def each
1039: each_attribute do |attr|
1040: yield attr.expanded_name, attr.value
1041: end
1042: 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 1023
1023: def each_attribute # :yields: attribute
1024: each_value do |val|
1025: if val.kind_of? Attribute
1026: yield val
1027: else
1028: val.each_value { |atr| yield atr }
1029: end
1030: end
1031: 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 1053
1053: def get_attribute( name )
1054: attr = fetch( name, nil )
1055: if attr.nil?
1056: return nil if name.nil?
1057: # Look for prefix
1058: name =~ Namespace::NAMESPLIT
1059: prefix, n = $1, $2
1060: if prefix
1061: attr = fetch( n, nil )
1062: # check prefix
1063: if attr == nil
1064: elsif attr.kind_of? Attribute
1065: return attr if prefix == attr.prefix
1066: else
1067: attr = attr[ prefix ]
1068: return attr
1069: end
1070: end
1071: element_document = @element.document
1072: if element_document and element_document.doctype
1073: expn = @element.expanded_name
1074: expn = element_document.doctype.name if expn.size == 0
1075: attr_val = element_document.doctype.attribute_of(expn, name)
1076: return Attribute.new( name, attr_val ) if attr_val
1077: end
1078: return nil
1079: end
1080: if attr.kind_of? Hash
1081: attr = attr[ @element.prefix ]
1082: end
1083: return attr
1084: 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 1233
1233: def get_attribute_ns(namespace, name)
1234: each_attribute() { |attribute|
1235: if name == attribute.name &&
1236: namespace == attribute.namespace()
1237: return attribute
1238: end
1239: }
1240: nil
1241: end
# File lib/rexml/element.rb, line 1151
1151: def namespaces
1152: namespaces = []
1153: each_attribute do |attribute|
1154: namespaces << attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
1155: end
1156: if @element.document and @element.document.doctype
1157: expn = @element.expanded_name
1158: expn = @element.document.doctype.name if expn.size == 0
1159: @element.document.doctype.attributes_of(expn).each {
1160: |attribute|
1161: namespaces << attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
1162: }
1163: end
1164: namespaces
1165: 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 1135
1135: def prefixes
1136: ns = []
1137: each_attribute do |attribute|
1138: ns << attribute.name if attribute.prefix == '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: ns << attribute.name if attribute.prefix == 'xmlns'
1146: }
1147: end
1148: ns
1149: end