Object
Easy API to maintain XML (especially configuration files).
Declare options that are valid for xml_in and xml_out.
Define some reasonable defaults.
Creates and intializes a new XmlSimple object.
defaults | Default values for options. |
# File lib/xmlsimple.rb, line 128 128: def initialize(defaults = nil) 129: unless defaults.nil? || defaults.instance_of?(Hash) 130: raise ArgumentError, "Options have to be a Hash." 131: end 132: @default_options = normalize_option_names(defaults, (KNOWN_OPTIONS['in'] + KNOWN_OPTIONS['out']).uniq) 133: @options = Hash.new 134: @_var_values = nil 135: end
Converts an XML document in the same way as the Perl module XML::Simple.
string | XML source. Could be one of the following:
|
options | Options to be used. |
# File lib/xmlsimple.rb, line 149 149: def xml_in(string = nil, options = nil) 150: handle_options('in', options) 151: 152: # If no XML string or filename was supplied look for scriptname.xml. 153: if string.nil? 154: string = File::basename($0).dup 155: string.sub!(/\.[^.]+$/, '') 156: string += '.xml' 157: 158: directory = File::dirname($0) 159: @options['searchpath'].unshift(directory) unless directory.nil? 160: end 161: 162: if string.instance_of?(String) 163: if string =~ /<.*?>/ 164: @doc = parse(string) 165: elsif string == '-' 166: @doc = parse($stdin.read) 167: else 168: filename = find_xml_file(string, @options['searchpath']) 169: 170: if @options.has_key?('cache') 171: @options['cache'].each { |scheme| 172: case(scheme) 173: when 'storable' 174: content = @@cache.restore_storable(filename) 175: when 'mem_share' 176: content = @@cache.restore_mem_share(filename) 177: when 'mem_copy' 178: content = @@cache.restore_mem_copy(filename) 179: else 180: raise ArgumentError, "Unsupported caching scheme: <#{scheme}>." 181: end 182: return content if content 183: } 184: end 185: 186: @doc = load_xml_file(filename) 187: end 188: elsif string.kind_of?(IO) || string.kind_of?(StringIO) || string.kind_of?(Zlib::GzipReader) 189: @doc = parse(string.read) 190: else 191: raise ArgumentError, "Could not parse object of type: <#{string.type}>." 192: end 193: 194: result = collapse(@doc.root) 195: result = @options['keeproot'] ? merge({}, @doc.root.name, result) : result 196: put_into_cache(result, filename) 197: result 198: end
Converts a data structure into an XML document.
ref | Reference to data structure to be converted into XML. |
options | Options to be used. |
# File lib/xmlsimple.rb, line 212 212: def xml_out(ref, options = nil) 213: handle_options('out', options) 214: if ref.instance_of?(Array) 215: ref = { @options['anonymoustag'] => ref } 216: end 217: 218: if @options['keeproot'] 219: keys = ref.keys 220: if keys.size == 1 221: ref = ref[keys[0]] 222: @options['rootname'] = keys[0] 223: end 224: elsif @options['rootname'] == '' 225: if ref.instance_of?(Hash) 226: refsave = ref 227: ref = {} 228: refsave.each { |key, value| 229: if !scalar(value) 230: ref[key] = value 231: else 232: ref[key] = [ value.to_s ] 233: end 234: } 235: end 236: end 237: 238: @ancestors = [] 239: xml = value_to_xml(ref, @options['rootname'], '') 240: @ancestors = nil 241: 242: if @options['xmldeclaration'] 243: xml = @options['xmldeclaration'] + "\n" + xml 244: end 245: 246: if @options.has_key?('outputfile') 247: if @options['outputfile'].kind_of?(IO) 248: return @options['outputfile'].write(xml) 249: else 250: File.open(@options['outputfile'], "w") { |file| file.write(xml) } 251: end 252: end 253: xml 254: end
Actually converts an XML document element into a data structure.
element | The document element to be collapsed. |
# File lib/xmlsimple.rb, line 461 461: def collapse(element) 462: result = @options['noattr'] ? {} : get_attributes(element) 463: 464: if @options['normalisespace'] == 2 465: result.each { |k, v| result[k] = normalise_space(v) } 466: end 467: 468: if element.has_elements? 469: element.each_element { |child| 470: value = collapse(child) 471: if empty(value) && (element.attributes.empty? || @options['noattr']) 472: next if @options.has_key?('suppressempty') && @options['suppressempty'] == true 473: end 474: result = merge(result, child.name, value) 475: } 476: if has_mixed_content?(element) 477: # normalisespace? 478: content = element.texts.map { |x| x.to_s } 479: content = content[0] if content.size == 1 480: result[@options['contentkey']] = content 481: end 482: elsif element.has_text? # i.e. it has only text. 483: return collapse_text_node(result, element) 484: end 485: 486: # Turn Arrays into Hashes if key fields present. 487: count = fold_arrays(result) 488: 489: # Disintermediate grouped tags. 490: if @options.has_key?('grouptags') 491: result.each { |key, value| 492: next unless (value.instance_of?(Hash) && (value.size == 1)) 493: child_key, child_value = value.to_a[0] 494: if @options['grouptags'][key] == child_key 495: result[key] = child_value 496: end 497: } 498: end 499: 500: # Fold Hashes containing a single anonymous Array up into just the Array. 501: if count == 1 502: anonymoustag = @options['anonymoustag'] 503: if result.has_key?(anonymoustag) && result[anonymoustag].instance_of?(Array) 504: return result[anonymoustag] 505: end 506: end 507: 508: if result.empty? && @options.has_key?('suppressempty') 509: return @options['suppressempty'] == '' ? '' : nil 510: end 511: 512: result 513: end
Tries to collapse a Hash even more ;-)
hash | Hash to be collapsed again. |
# File lib/xmlsimple.rb, line 624 624: def collapse_content(hash) 625: content_key = @options['contentkey'] 626: hash.each_value { |value| 627: return hash unless value.instance_of?(Hash) && value.size == 1 && value.has_key?(content_key) 628: hash.each_key { |key| hash[key] = hash[key][content_key] } 629: } 630: hash 631: end
Collapses a text node and merges it with an existing Hash, if possible. Thanks to Curtis Schofield for reporting a subtle bug.
hash | Hash to merge text node value with, if possible. |
element | Text node to be collapsed. |
# File lib/xmlsimple.rb, line 523 523: def collapse_text_node(hash, element) 524: value = node_to_text(element) 525: if empty(value) && !element.has_attributes? 526: return {} 527: end 528: 529: if element.has_attributes? && !@options['noattr'] 530: return merge(hash, @options['contentkey'], value) 531: else 532: if @options['forcecontent'] 533: return merge(hash, @options['contentkey'], value) 534: else 535: return value 536: end 537: end 538: end
Checks, if an object is nil, an empty String or an empty Hash. Thanks to Norbert Gawor for a bugfix.
value | Value to be checked for emptyness. |
# File lib/xmlsimple.rb, line 918 918: def empty(value) 919: case value 920: when Hash 921: return value.empty? 922: when String 923: return value !~ /\S/ 924: else 925: return value.nil? 926: end 927: end
Replaces XML markup characters by their external entities.
data | The string to be escaped. |
# File lib/xmlsimple.rb, line 900 900: def escape_value(data) 901: Text::normalize(data) 902: end
Searches in a list of paths for a certain file. Returns the full path to the file, if it could be found. Otherwise, an exception will be raised.
filename | Name of the file to search for. |
searchpath | List of paths to search in. |
# File lib/xmlsimple.rb, line 970 970: def find_xml_file(file, searchpath) 971: filename = File::basename(file) 972: 973: if filename != file 974: return file if File::file?(file) 975: else 976: searchpath.each { |path| 977: full_path = File::join(path, filename) 978: return full_path if File::file?(full_path) 979: } 980: end 981: 982: if searchpath.empty? 983: return file if File::file?(file) 984: raise ArgumentError, "File does not exist: #{file}." 985: end 986: raise ArgumentError, "Could not find <#{filename}> in <#{searchpath.join(':')}>" 987: end
Folds an Array to a Hash, if possible. Folding happens according to the content of keyattr, which has to be an array.
array | Array to be folded. |
# File lib/xmlsimple.rb, line 568 568: def fold_array(array) 569: hash = Hash.new 570: array.each { |x| 571: return array unless x.instance_of?(Hash) 572: key_matched = false 573: @options['keyattr'].each { |key| 574: if x.has_key?(key) 575: key_matched = true 576: value = x[key] 577: return array if value.instance_of?(Hash) || value.instance_of?(Array) 578: value = normalise_space(value) if @options['normalisespace'] == 1 579: x.delete(key) 580: hash[value] = x 581: break 582: end 583: } 584: return array unless key_matched 585: } 586: hash = collapse_content(hash) if @options['collapseagain'] 587: hash 588: end
Folds an Array to a Hash, if possible. Folding happens according to the content of keyattr, which has to be a Hash.
name | Name of the attribute to be folded upon. |
array | Array to be folded. |
# File lib/xmlsimple.rb, line 598 598: def fold_array_by_name(name, array) 599: return array unless @options['keyattr'].has_key?(name) 600: key, flag = @options['keyattr'][name] 601: 602: hash = Hash.new 603: array.each { |x| 604: if x.instance_of?(Hash) && x.has_key?(key) 605: value = x[key] 606: return array if value.instance_of?(Hash) || value.instance_of?(Array) 607: value = normalise_space(value) if @options['normalisespace'] == 1 608: hash[value] = x 609: hash[value]["-#{key}"] = hash[value][key] if flag == '-' 610: hash[value].delete(key) unless flag == '+' 611: else 612: $stderr.puts("Warning: <#{name}> element has no '#{key}' attribute.") 613: return array 614: end 615: } 616: hash = collapse_content(hash) if @options['collapseagain'] 617: hash 618: end
Folds all arrays in a Hash.
hash | Hash to be folded. |
# File lib/xmlsimple.rb, line 544 544: def fold_arrays(hash) 545: fold_amount = 0 546: keyattr = @options['keyattr'] 547: if (keyattr.instance_of?(Array) || keyattr.instance_of?(Hash)) 548: hash.each { |key, value| 549: if value.instance_of?(Array) 550: if keyattr.instance_of?(Array) 551: hash[key] = fold_array(value) 552: else 553: hash[key] = fold_array_by_name(key, value) 554: end 555: fold_amount += 1 556: end 557: } 558: end 559: fold_amount 560: end
Checks, if the ‘forcearray’ option has to be used for a certain key.
# File lib/xmlsimple.rb, line 689 689: def force_array?(key) 690: return false if key == @options['contentkey'] 691: return true if @options['forcearray'] == true 692: forcearray = @options['forcearray'] 693: if forcearray.instance_of?(Hash) 694: return true if forcearray.has_key?(key) 695: return false unless forcearray.has_key?('_regex') 696: forcearray['_regex'].each { |x| return true if key =~ x } 697: end 698: return false 699: end
Converts the attributes array of a document node into a Hash. Returns an empty Hash, if node has no attributes.
node | Document node to extract attributes from. |
# File lib/xmlsimple.rb, line 706 706: def get_attributes(node) 707: attributes = {} 708: if @options['attrprefix'] 709: node.attributes.each { |n,v| attributes["@" + n] = v } 710: else 711: node.attributes.each { |n,v| attributes[n] = v } 712: end 713: attributes 714: end
Called during variable substitution to get the value for the named variable.
# File lib/xmlsimple.rb, line 737 737: def get_var(name) 738: if @_var_values.has_key?(name) 739: return @_var_values[name] 740: else 741: return "${#{name}}" 742: end 743: end
Merges a set of options with the default options.
direction | ‘in’: If options should be handled for xml_in. ‘out’: If options should be handled for xml_out. |
options | Options to be merged with the default options. |
# File lib/xmlsimple.rb, line 319 319: def handle_options(direction, options) 320: @options = options || Hash.new 321: 322: raise ArgumentError, "Options must be a Hash!" unless @options.instance_of?(Hash) 323: 324: unless KNOWN_OPTIONS.has_key?(direction) 325: raise ArgumentError, "Unknown direction: <#{direction}>." 326: end 327: 328: known_options = KNOWN_OPTIONS[direction] 329: @options = normalize_option_names(@options, known_options) 330: 331: unless @default_options.nil? 332: known_options.each { |option| 333: unless @options.has_key?(option) 334: if @default_options.has_key?(option) 335: @options[option] = @default_options[option] 336: end 337: end 338: } 339: end 340: 341: unless @options.has_key?('noattr') 342: @options['noattr'] = false 343: end 344: 345: if @options.has_key?('rootname') 346: @options['rootname'] = '' if @options['rootname'].nil? 347: else 348: @options['rootname'] = DEF_ROOT_NAME 349: end 350: 351: if @options.has_key?('xmldeclaration') && @options['xmldeclaration'] == true 352: @options['xmldeclaration'] = DEF_XML_DECLARATION 353: end 354: 355: @options['keytosymbol'] = DEF_KEY_TO_SYMBOL unless @options.has_key?('keytosymbol') 356: 357: if @options.has_key?('contentkey') 358: if @options['contentkey'] =~ /^-(.*)$/ 359: @options['contentkey'] = $1 360: @options['collapseagain'] = true 361: end 362: else 363: @options['contentkey'] = DEF_CONTENT_KEY 364: end 365: 366: unless @options.has_key?('normalisespace') 367: @options['normalisespace'] = @options['normalizespace'] 368: end 369: @options['normalisespace'] = 0 if @options['normalisespace'].nil? 370: 371: if @options.has_key?('searchpath') 372: unless @options['searchpath'].instance_of?(Array) 373: @options['searchpath'] = [ @options['searchpath'] ] 374: end 375: else 376: @options['searchpath'] = [] 377: end 378: 379: if @options.has_key?('cache') && scalar(@options['cache']) 380: @options['cache'] = [ @options['cache'] ] 381: end 382: 383: @options['anonymoustag'] = DEF_ANONYMOUS_TAG unless @options.has_key?('anonymoustag') 384: 385: if !@options.has_key?('indent') || @options['indent'].nil? 386: @options['indent'] = DEF_INDENTATION 387: end 388: 389: @options['indent'] = '' if @options.has_key?('noindent') 390: 391: # Special cleanup for 'keyattr' which could be an array or 392: # a hash or left to default to array. 393: if @options.has_key?('keyattr') 394: if !scalar(@options['keyattr']) 395: # Convert keyattr => { elem => '+attr' } 396: # to keyattr => { elem => ['attr', '+'] } 397: if @options['keyattr'].instance_of?(Hash) 398: @options['keyattr'].each { |key, value| 399: if value =~ /^([-+])?(.*)$/ 400: @options['keyattr'][key] = [$2, $1 ? $1 : ''] 401: end 402: } 403: elsif !@options['keyattr'].instance_of?(Array) 404: raise ArgumentError, "'keyattr' must be String, Hash, or Array!" 405: end 406: else 407: @options['keyattr'] = [ @options['keyattr'] ] 408: end 409: else 410: @options['keyattr'] = DEF_KEY_ATTRIBUTES 411: end 412: 413: if @options.has_key?('forcearray') 414: if @options['forcearray'].instance_of?(Regexp) 415: @options['forcearray'] = [ @options['forcearray'] ] 416: end 417: 418: if @options['forcearray'].instance_of?(Array) 419: force_list = @options['forcearray'] 420: unless force_list.empty? 421: @options['forcearray'] = {} 422: force_list.each { |tag| 423: if tag.instance_of?(Regexp) 424: unless @options['forcearray']['_regex'].instance_of?(Array) 425: @options['forcearray']['_regex'] = [] 426: end 427: @options['forcearray']['_regex'] << tag 428: else 429: @options['forcearray'][tag] = true 430: end 431: } 432: else 433: @options['forcearray'] = false 434: end 435: else 436: @options['forcearray'] = @options['forcearray'] ? true : false 437: end 438: else 439: @options['forcearray'] = DEF_FORCE_ARRAY 440: end 441: 442: if @options.has_key?('grouptags') && !@options['grouptags'].instance_of?(Hash) 443: raise ArgumentError, "Illegal value for 'GroupTags' option - expected a Hash." 444: end 445: 446: if @options.has_key?('variables') && !@options['variables'].instance_of?(Hash) 447: raise ArgumentError, "Illegal value for 'Variables' option - expected a Hash." 448: end 449: 450: if @options.has_key?('variables') 451: @_var_values = @options['variables'] 452: elsif @options.has_key?('varattr') 453: @_var_values = {} 454: end 455: end
Determines, if a document element has mixed content.
element | Document element to be checked. |
# File lib/xmlsimple.rb, line 720 720: def has_mixed_content?(element) 721: if element.has_text? && element.has_elements? 722: return true if element.texts.join('') !~ /^\s*$/ 723: end 724: false 725: end
Attempts to unfold a hash of hashes into an array of hashes. Returns a reference to th array on success or the original hash, if unfolding is not possible.
parent | |
hashref | Reference to the hash to be unfolded. |
# File lib/xmlsimple.rb, line 881 881: def hash_to_array(parent, hashref) 882: arrayref = [] 883: hashref.each { |key, value| 884: return hashref unless value.instance_of?(Hash) 885: 886: if @options['keyattr'].instance_of?(Hash) 887: return hashref unless @options['keyattr'].has_key?(parent) 888: arrayref << { @options['keyattr'][parent][0] => key }.update(value) 889: else 890: arrayref << { @options['keyattr'][0] => key }.update(value) 891: end 892: } 893: arrayref 894: end
Loads and parses an XML configuration file.
filename | Name of the configuration file to be loaded. |
The following exceptions may be raised:
Errno::ENOENT | If the specified file does not exist. |
REXML::ParseException | If the specified file is not wellformed. |
# File lib/xmlsimple.rb, line 1000 1000: def load_xml_file(filename) 1001: parse(IO::read(filename)) 1002: end
Adds a new key/value pair to an existing Hash. If the key to be added does already exist and the existing value associated with key is not an Array, it will be converted into an Array. Then the new value is appended to that Array.
hash | Hash to add key/value pair to. |
key | Key to be added. |
value | Value to be associated with key. |
# File lib/xmlsimple.rb, line 644 644: def merge(hash, key, value) 645: if value.instance_of?(String) 646: value = normalise_space(value) if @options['normalisespace'] == 2 647: 648: # do variable substitutions 649: unless @_var_values.nil? || @_var_values.empty? 650: value.gsub!(/\$\{(\w+)\}/) { |x| get_var($1) } 651: end 652: 653: # look for variable definitions 654: if @options.has_key?('varattr') 655: varattr = @options['varattr'] 656: if hash.has_key?(varattr) 657: set_var(hash[varattr], value) 658: end 659: end 660: end 661: 662: #patch for converting keys to symbols 663: if @options.has_key?('keytosymbol') 664: if @options['keytosymbol'] == true 665: key = key.to_s.downcase.to_sym 666: end 667: end 668: 669: if hash.has_key?(key) 670: if hash[key].instance_of?(Array) 671: hash[key] << value 672: else 673: hash[key] = [ hash[key], value ] 674: end 675: elsif value.instance_of?(Array) # Handle anonymous arrays. 676: hash[key] = [ value ] 677: else 678: if force_array?(key) 679: hash[key] = [ value ] 680: else 681: hash[key] = value 682: end 683: end 684: hash 685: end
Converts a document node into a String. If the node could not be converted into a String for any reason, default will be returned.
node | Document node to be converted. |
default | Value to be returned, if node could not be converted. |
# File lib/xmlsimple.rb, line 937 937: def node_to_text(node, default = nil) 938: if node.instance_of?(REXML::Element) 939: node.texts.map { |t| t.value }.join('') 940: elsif node.instance_of?(REXML::Attribute) 941: node.value.nil? ? default : node.value.strip 942: elsif node.instance_of?(REXML::Text) 943: node.value.strip 944: else 945: default 946: end 947: end
Removes leading and trailing whitespace and sequences of whitespaces from a string.
text | String to be normalised. |
# File lib/xmlsimple.rb, line 909 909: def normalise_space(text) 910: text.strip.gsub(/\s\s+/, ' ') 911: end
Normalizes option names in a hash, i.e., turns all characters to lower case and removes all underscores. Additionally, this method checks, if an unknown option was used and raises an according exception.
options | Hash to be normalized. |
known_options | List of known options. |
# File lib/xmlsimple.rb, line 298 298: def normalize_option_names(options, known_options) 299: return nil if options.nil? 300: result = Hash.new 301: options.each { |key, value| 302: lkey = key.downcase 303: lkey.gsub!(/_/, '') 304: if !known_options.member?(lkey) 305: raise ArgumentError, "Unrecognised option: #{lkey}." 306: end 307: result[lkey] = value 308: } 309: result 310: end
Parses an XML string and returns the according document.
xml_string | XML string to be parsed. |
The following exception may be raised:
REXML::ParseException | If the specified file is not wellformed. |
# File lib/xmlsimple.rb, line 958 958: def parse(xml_string) 959: Document.new(xml_string) 960: end
Caches the data belonging to a certain file.
data | Data to be cached. |
filename | Name of file the data was read from. |
# File lib/xmlsimple.rb, line 1010 1010: def put_into_cache(data, filename) 1011: if @options.has_key?('cache') 1012: @options['cache'].each { |scheme| 1013: case(scheme) 1014: when 'storable' 1015: @@cache.save_storable(data, filename) 1016: when 'mem_share' 1017: @@cache.save_mem_share(data, filename) 1018: when 'mem_copy' 1019: @@cache.save_mem_copy(data, filename) 1020: else 1021: raise ArgumentError, "Unsupported caching scheme: <#{scheme}>." 1022: end 1023: } 1024: end 1025: end
Checks, if a certain value is a “scalar” value. Whatever that will be in Ruby … ;-)
value | Value to be checked. |
# File lib/xmlsimple.rb, line 868 868: def scalar(value) 869: return false if value.instance_of?(Hash) || value.instance_of?(Array) 870: return true 871: end
Called when a variable definition is encountered in the XML. A variable definition looks like
<element attrname="name">value</element>
where attrname matches the varattr setting.
# File lib/xmlsimple.rb, line 731 731: def set_var(name, value) 732: @_var_values[name] = value 733: end
Recurses through a data structure building up and returning an XML representation of that structure as a string.
ref | Reference to the data structure to be encoded. |
name | The XML tag name to be used for this item. |
indent | A string of spaces for use as the current indent level. |
# File lib/xmlsimple.rb, line 754 754: def value_to_xml(ref, name, indent) 755: named = !name.nil? && name != '' 756: nl = @options.has_key?('noindent') ? '' : "\n" 757: 758: if !scalar(ref) 759: if @ancestors.member?(ref) 760: raise ArgumentError, "Circular data structures not supported!" 761: end 762: @ancestors << ref 763: else 764: if named 765: return [indent, '<', name, '>', @options['noescape'] ? ref.to_s : escape_value(ref.to_s), '</', name, '>', nl].join('') 766: else 767: return ref.to_s + nl 768: end 769: end 770: 771: # Unfold hash to array if possible. 772: if ref.instance_of?(Hash) && !ref.empty? && !@options['keyattr'].empty? && indent != '' 773: ref = hash_to_array(name, ref) 774: end 775: 776: result = [] 777: if ref.instance_of?(Hash) 778: # Reintermediate grouped values if applicable. 779: if @options.has_key?('grouptags') 780: ref.each { |key, value| 781: if @options['grouptags'].has_key?(key) 782: ref[key] = { @options['grouptags'][key] => value } 783: end 784: } 785: end 786: 787: nested = [] 788: text_content = nil 789: if named 790: result << indent << '<' << name 791: end 792: 793: if !ref.empty? 794: ref.each { |key, value| 795: next if !key.nil? && key.to_s[0, 1] == '-' 796: if value.nil? 797: unless @options.has_key?('suppressempty') && @options['suppressempty'].nil? 798: raise ArgumentError, "Use of uninitialized value!" 799: end 800: value = {} 801: end 802: 803: # Check for the '@' attribute prefix to allow separation of attributes and elements 804: if @options['noattr'] || 805: (@options['attrprefix'] && !(key =~ /^@(.*)/)) || 806: !scalar(value) 807: nested << value_to_xml(value, key, indent + @options['indent']) 808: else 809: value = value.to_s 810: value = escape_value(value) unless @options['noescape'] 811: if key == @options['contentkey'] 812: text_content = value 813: else 814: result << ' ' << ($1||key) << '="' << value << '"' 815: end 816: end 817: } 818: else 819: text_content = '' 820: end 821: 822: if !nested.empty? || !text_content.nil? 823: if named 824: result << '>' 825: if !text_content.nil? 826: result << text_content 827: nested[0].sub!(/^\s+/, '') if !nested.empty? 828: else 829: result << nl 830: end 831: if !nested.empty? 832: result << nested << indent 833: end 834: result << '</' << name << '>' << nl 835: else 836: result << nested 837: end 838: else 839: result << ' />' << nl 840: end 841: elsif ref.instance_of?(Array) 842: ref.each { |value| 843: if scalar(value) 844: result << indent << '<' << name << '>' 845: result << (@options['noescape'] ? value.to_s : escape_value(value.to_s)) 846: result << '</' << name << '>' << nl 847: elsif value.instance_of?(Hash) 848: result << value_to_xml(value, name, indent) 849: else 850: result << indent << '<' << name << '>' << nl 851: result << value_to_xml(value, @options['anonymoustag'], indent + @options['indent']) 852: result << indent << '</' << name << '>' << nl 853: end 854: } 855: else 856: # Probably, this is obsolete. 857: raise ArgumentError, "Can't encode a value of type: #{ref.type}." 858: end 859: @ancestors.pop if !scalar(ref) 860: result.join('') 861: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.