Skip to content

Commit e23a00b

Browse files
Enhanced RDoc for Element (#61)
1 parent e545aa3 commit e23a00b

File tree

1 file changed

+196
-52
lines changed

1 file changed

+196
-52
lines changed

lib/rexml/element.rb

Lines changed: 196 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -945,19 +945,45 @@ def xpath
945945
# Attributes #
946946
#################################################
947947

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
949980
#
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>:
953983
#
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
956986
#
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/>
961987
def [](name_or_index)
962988
case name_or_index
963989
when String
@@ -969,6 +995,36 @@ def [](name_or_index)
969995
end
970996
end
971997

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+
#
9721028
def attribute( name, namespace=nil )
9731029
prefix = nil
9741030
if namespaces.respond_to? :key
@@ -992,29 +1048,46 @@ def attribute( name, namespace=nil )
9921048

9931049
end
9941050

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+
#
9971061
def has_attributes?
9981062
return !@attributes.empty?
9991063
end
10001064

1065+
# :call-seq:
1066+
# add_attribute(name, value) -> value
1067+
# add_attribute(attribute) -> attribute
1068+
#
10011069
# Adds an attribute to this element, overwriting any existing attribute
10021070
# 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+
#
10181091
def add_attribute( key, value=nil )
10191092
if key.kind_of? Attribute
10201093
@attributes << key
@@ -1023,10 +1096,29 @@ def add_attribute( key, value=nil )
10231096
end
10241097
end
10251098

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+
#
10301122
def add_attributes hash
10311123
if hash.kind_of? Hash
10321124
hash.each_pair {|key, value| @attributes[key] = value }
@@ -1035,19 +1127,17 @@ def add_attributes hash
10351127
end
10361128
end
10371129

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+
#
10511141
def delete_attribute(key)
10521142
attr = @attributes.get_attribute(key)
10531143
attr.remove unless attr.nil?
@@ -1057,26 +1147,80 @@ def delete_attribute(key)
10571147
# Other Utilities #
10581148
#################################################
10591149

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+
#
10621166
def cdatas
10631167
find_all { |child| child.kind_of? CData }.freeze
10641168
end
10651169

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+
#
10681187
def comments
10691188
find_all { |child| child.kind_of? Comment }.freeze
10701189
end
10711190

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+
#
10741208
def instructions
10751209
find_all { |child| child.kind_of? Instruction }.freeze
10761210
end
10771211

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+
#
10801224
def texts
10811225
find_all { |child| child.kind_of? Text }.freeze
10821226
end

0 commit comments

Comments
 (0)