@@ -945,19 +945,45 @@ def xpath
945
945
# Attributes #
946
946
#################################################
947
947
948
- # Fetches an attribute value or a child.
948
+ # :call-seq:
949
+ # [index] -> object
950
+ # [attr_name] -> attr_value
951
+ # [attr_sym] -> attr_value
952
+ #
953
+ # With integer argument +index+ given,
954
+ # returns the child at offset +index+, or +nil+ if none:
955
+ #
956
+ # d = REXML::Document.new '><root><a/>text<b/>more<c/></root>'
957
+ # root = d.root
958
+ # (0..root.size).each do |index|
959
+ # node = root[index]
960
+ # p "#{index}: #{node} (#{node.class})"
961
+ # end
962
+ #
963
+ # Output:
964
+ #
965
+ # "0: <a/> (REXML::Element)"
966
+ # "1: text (REXML::Text)"
967
+ # "2: <b/> (REXML::Element)"
968
+ # "3: more (REXML::Text)"
969
+ # "4: <c/> (REXML::Element)"
970
+ # "5: (NilClass)"
971
+ #
972
+ # With string argument +attr_name+ given,
973
+ # returns the string value for the given attribute name if it exists,
974
+ # otherwise +nil+:
975
+ #
976
+ # d = REXML::Document.new('<root attr="value"></root>')
977
+ # root = d.root
978
+ # root['attr'] # => "value"
979
+ # root['nosuch'] # => nil
949
980
#
950
- # If String or Symbol is specified, it's treated as attribute
951
- # name. Attribute value as String or +nil+ is returned. This case
952
- # is shortcut of +attributes[name]+.
981
+ # With symbol argument +attr_sym+ given,
982
+ # returns <tt>[attr_sym.to_s]</tt>:
953
983
#
954
- # If Integer is specified, it's treated as the index of
955
- # child. It returns Nth child.
984
+ # root[:attr] # => "value"
985
+ # root[:nosuch] # => nil
956
986
#
957
- # doc = REXML::Document.new("<a attr='1'><b/><c/></a>")
958
- # doc.root["attr"] # => "1"
959
- # doc.root.attributes["attr"] # => "1"
960
- # doc.root[1] # => <c/>
961
987
def []( name_or_index )
962
988
case name_or_index
963
989
when String
@@ -969,6 +995,36 @@ def [](name_or_index)
969
995
end
970
996
end
971
997
998
+
999
+ # :call-seq:
1000
+ # attribute(name, namespace = nil)
1001
+ #
1002
+ # Returns the string value for the given attribute name.
1003
+ #
1004
+ # With only argument +name+ given,
1005
+ # returns the value of the named attribute if it exists, otherwise +nil+:
1006
+ #
1007
+ # xml_string = <<-EOT
1008
+ # <root xmlns="ns0">
1009
+ # <a xmlns="ns1" attr="value"></a>
1010
+ # <b xmlns="ns2" attr="value"></b>
1011
+ # <c attr="value"/>
1012
+ # </root>
1013
+ # EOT
1014
+ # d = REXML::Document.new(xml_string)
1015
+ # root = d.root
1016
+ # a = root[1] # => <a xmlns='ns1' attr='value'/>
1017
+ # a.attribute('attr') # => attr='value'
1018
+ # a.attribute('nope') # => nil
1019
+ #
1020
+ # With arguments +name+ and +namespace+ given,
1021
+ # returns the value of the named attribute if it exists, otherwise +nil+:
1022
+ #
1023
+ # xml_string = "<root xmlns:a='a' a:x='a:x' x='x'/>"
1024
+ # document = REXML::Document.new(xml_string)
1025
+ # document.root.attribute("x") # => x='x'
1026
+ # document.root.attribute("x", "a") # => a:x='a:x'
1027
+ #
972
1028
def attribute ( name , namespace = nil )
973
1029
prefix = nil
974
1030
if namespaces . respond_to? :key
@@ -992,29 +1048,46 @@ def attribute( name, namespace=nil )
992
1048
993
1049
end
994
1050
995
- # Evaluates to +true+ if this element has any attributes set, false
996
- # otherwise.
1051
+ # :call-seq:
1052
+ # has_attributes? -> true or false
1053
+ #
1054
+ # Returns +true+ if the element has attributes, +false+ otherwise:
1055
+ #
1056
+ # d = REXML::Document.new('<root><a attr="val"/><b/></root>')
1057
+ # a, b = *d.root
1058
+ # a.has_attributes? # => true
1059
+ # b.has_attributes? # => false
1060
+ #
997
1061
def has_attributes?
998
1062
return !@attributes . empty?
999
1063
end
1000
1064
1065
+ # :call-seq:
1066
+ # add_attribute(name, value) -> value
1067
+ # add_attribute(attribute) -> attribute
1068
+ #
1001
1069
# Adds an attribute to this element, overwriting any existing attribute
1002
1070
# by the same name.
1003
- # key::
1004
- # can be either an Attribute or a String. If an Attribute,
1005
- # the attribute is added to the list of Element attributes. If String,
1006
- # the argument is used as the name of the new attribute, and the value
1007
- # parameter must be supplied.
1008
- # value::
1009
- # Required if +key+ is a String, and ignored if the first argument is
1010
- # an Attribute. This is a String, and is used as the value
1011
- # of the new Attribute. This should be the unnormalized value of the
1012
- # attribute (without entities).
1013
- # Returns:: the Attribute added
1014
- # e = Element.new 'e'
1015
- # e.add_attribute( 'a', 'b' ) #-> <e a='b'/>
1016
- # e.add_attribute( 'x:a', 'c' ) #-> <e a='b' x:a='c'/>
1017
- # e.add_attribute Attribute.new('b', 'd') #-> <e a='b' x:a='c' b='d'/>
1071
+ #
1072
+ # With string argument +name+ and object +value+ are given,
1073
+ # adds the attribute created with that name and value:
1074
+ #
1075
+ # e = REXML::Element.new
1076
+ # e.add_attribute('attr', 'value') # => "value"
1077
+ # e['attr'] # => "value"
1078
+ # e.add_attribute('attr', 'VALUE') # => "VALUE"
1079
+ # e['attr'] # => "VALUE"
1080
+ #
1081
+ # With only attribute object +attribute+ given,
1082
+ # adds the given attribute:
1083
+ #
1084
+ # a = REXML::Attribute.new('attr', 'value')
1085
+ # e.add_attribute(a) # => attr='value'
1086
+ # e['attr'] # => "value"
1087
+ # a = REXML::Attribute.new('attr', 'VALUE')
1088
+ # e.add_attribute(a) # => attr='VALUE'
1089
+ # e['attr'] # => "VALUE"
1090
+ #
1018
1091
def add_attribute ( key , value = nil )
1019
1092
if key . kind_of? Attribute
1020
1093
@attributes << key
@@ -1023,10 +1096,29 @@ def add_attribute( key, value=nil )
1023
1096
end
1024
1097
end
1025
1098
1026
- # Add multiple attributes to this element.
1027
- # hash:: is either a hash, or array of arrays
1028
- # el.add_attributes( {"name1"=>"value1", "name2"=>"value2"} )
1029
- # el.add_attributes( [ ["name1","value1"], ["name2"=>"value2"] ] )
1099
+ # :call-seq:
1100
+ # add_attributes(hash) -> hash
1101
+ # add_attributes(array)
1102
+ #
1103
+ # Adds zero or more attributes to the element;
1104
+ # returns the argument.
1105
+ #
1106
+ # If hash argument +hash+ is given,
1107
+ # each key must be a string;
1108
+ # adds each attribute created with the key/value pair:
1109
+ #
1110
+ # e = REXML::Element.new
1111
+ # h = {'foo' => 'bar', 'baz' => 'bat'}
1112
+ # e.add_attributes(h)
1113
+ #
1114
+ # If argument +array+ is given,
1115
+ # each array member must be a 2-element array <tt>[name, value];
1116
+ # each name must be a string:
1117
+ #
1118
+ # e = REXML::Element.new
1119
+ # a = [['foo' => 'bar'], ['baz' => 'bat']]
1120
+ # e.add_attributes(a)
1121
+ #
1030
1122
def add_attributes hash
1031
1123
if hash . kind_of? Hash
1032
1124
hash . each_pair { |key , value | @attributes [ key ] = value }
@@ -1035,19 +1127,17 @@ def add_attributes hash
1035
1127
end
1036
1128
end
1037
1129
1038
- # Removes an attribute
1039
- # key::
1040
- # either an Attribute or a String. In either case, the
1041
- # attribute is found by matching the attribute name to the argument,
1042
- # and then removed. If no attribute is found, no action is taken.
1043
- # Returns::
1044
- # the attribute removed, or nil if this Element did not contain
1045
- # a matching attribute
1046
- # e = Element.new('E')
1047
- # e.add_attribute( 'name', 'Sean' ) #-> <E name='Sean'/>
1048
- # r = e.add_attribute( 'sur:name', 'Russell' ) #-> <E name='Sean' sur:name='Russell'/>
1049
- # e.delete_attribute( 'name' ) #-> <E sur:name='Russell'/>
1050
- # e.delete_attribute( r ) #-> <E/>
1130
+ # :call-seq:
1131
+ # delete_attribute(name) -> removed_attribute or nil
1132
+ #
1133
+ # Removes a named attribute if it exists;
1134
+ # returns the removed attribute if found, otherwise +nil+:
1135
+ #
1136
+ # e = REXML::Element.new('foo')
1137
+ # e.add_attribute('bar', 'baz')
1138
+ # e.delete_attribute('bar') # => <bar/>
1139
+ # e.delete_attribute('bar') # => nil
1140
+ #
1051
1141
def delete_attribute ( key )
1052
1142
attr = @attributes . get_attribute ( key )
1053
1143
attr . remove unless attr . nil?
@@ -1057,26 +1147,80 @@ def delete_attribute(key)
1057
1147
# Other Utilities #
1058
1148
#################################################
1059
1149
1060
- # Get an array of all CData children.
1061
- # IMMUTABLE
1150
+ # :call-seq:
1151
+ # cdatas -> array_of_cdata_children
1152
+ #
1153
+ # Returns a frozen array of the REXML::CData children of the element:
1154
+ #
1155
+ # xml_string = <<-EOT
1156
+ # <root>
1157
+ # <![CDATA[foo]]>
1158
+ # <![CDATA[bar]]>
1159
+ # </root>
1160
+ # EOT
1161
+ # d = REXML::Document.new(xml_string)
1162
+ # cds = d.root.cdatas # => ["foo", "bar"]
1163
+ # cds.frozen? # => true
1164
+ # cds.map {|cd| cd.class } # => [REXML::CData, REXML::CData]
1165
+ #
1062
1166
def cdatas
1063
1167
find_all { |child | child . kind_of? CData } . freeze
1064
1168
end
1065
1169
1066
- # Get an array of all Comment children.
1067
- # IMMUTABLE
1170
+ # :call-seq:
1171
+ # comments -> array_of_comment_children
1172
+ #
1173
+ # Returns a frozen array of the REXML::Comment children of the element:
1174
+ #
1175
+ # xml_string = <<-EOT
1176
+ # <root>
1177
+ # <!--foo-->
1178
+ # <!--bar-->
1179
+ # </root>
1180
+ # EOT
1181
+ # d = REXML::Document.new(xml_string)
1182
+ # cs = d.root.comments
1183
+ # cs.frozen? # => true
1184
+ # cs.map {|c| c.class } # => [REXML::Comment, REXML::Comment]
1185
+ # cs.map {|c| c.to_s } # => ["foo", "bar"]
1186
+ #
1068
1187
def comments
1069
1188
find_all { |child | child . kind_of? Comment } . freeze
1070
1189
end
1071
1190
1072
- # Get an array of all Instruction children.
1073
- # IMMUTABLE
1191
+ # :call-seq:
1192
+ # instructions -> array_of_instruction_children
1193
+ #
1194
+ # Returns a frozen array of the REXML::Instruction children of the element:
1195
+ #
1196
+ # xml_string = <<-EOT
1197
+ # <root>
1198
+ # <?target0 foo?>
1199
+ # <?target1 bar?>
1200
+ # </root>
1201
+ # EOT
1202
+ # d = REXML::Document.new(xml_string)
1203
+ # is = d.root.instructions
1204
+ # is.frozen? # => true
1205
+ # is.map {|i| i.class } # => [REXML::Instruction, REXML::Instruction]
1206
+ # is.map {|i| i.to_s } # => ["<?target0 foo?>", "<?target1 bar?>"]
1207
+ #
1074
1208
def instructions
1075
1209
find_all { |child | child . kind_of? Instruction } . freeze
1076
1210
end
1077
1211
1078
- # Get an array of all Text children.
1079
- # IMMUTABLE
1212
+ # :call-seq:
1213
+ # texts -> array_of_text_children
1214
+ #
1215
+ # Returns a frozen array of the REXML::Text children of the element:
1216
+ #
1217
+ # xml_string = '<root><a/>text<b/>more<c/></root>'
1218
+ # d = REXML::Document.new(xml_string)
1219
+ # ts = d.root.texts
1220
+ # ts.frozen? # => true
1221
+ # ts.map {|t| t.class } # => [REXML::Text, REXML::Text]
1222
+ # ts.map {|t| t.to_s } # => ["text", "more"]
1223
+ #
1080
1224
def texts
1081
1225
find_all { |child | child . kind_of? Text } . freeze
1082
1226
end
0 commit comments