From: Justin Zipperle Date: 2010-12-18T06:05:34+09:00 Subject: Re: soap4r orders multi-element sequences incorrectly? Hi James- I ended up writing a workaround that (so far) fixes the issue in my project, though someone may be able to implement this more cleanly. I put this in a separate file in my project rather than mangle the soap4r source: module SOAP module Mapping class LiteralRegistry def multielement_sequence_size(obj, definition) num_arrays = 0 use_arrays = 0 mes_size = 0 definition.each do |e| num_arrays += 1 if e.respond_to?('as_array?') and e.as_array? if e.respond_to?('varname') and Mapping.get_attribute(obj, e.varname).class == Array use_arrays += 1 if Mapping.get_attribute(obj, e.varname).length > 1 mes_size = Mapping.get_attribute(obj, e.varname).length end end if definition.class == SchemaSequenceDefinition and definition.size > 1 and num_arrays == definition.size and use_arrays == definition.size mes_size else 0 end end def stubobj2soap_elements(obj, ele, definition, is_choice = false) added = false case definition when SchemaSequenceDefinition, SchemaEmptyDefinition # check for multi-element sequence mes_size = multielement_sequence_size(obj, definition) if mes_size > 0 # maintain order of multi-element sequences added = true (0...mes_size).each do |idx| definition.each do |e| ele.add(definedobj2soap(Mapping.get_attribute(obj, e.varname)[idx], e)) end end else definition.each do |eledef| ele_added = stubobj2soap_elements(obj, ele, eledef, is_choice) added = true if ele_added end end when SchemaChoiceDefinition definition.each do |eledef| added = stubobj2soap_elements(obj, ele, eledef, true) break if added end else added = true if definition.as_any? any = Mapping.get_attributes_for_any(obj) SOAPElement.from_objs(any).each do |child| ele.add(child) end elsif obj.respond_to?(:each) and definition.as_array? obj.each do |item| ele.add(definedobj2soap(item, definition)) end else child = Mapping.get_attribute(obj, definition.varname) if child.nil? and (is_choice or definition.minoccurs == 0) added = false else if child.respond_to?(:each) and definition.as_array? if child.empty? added = false else child.each do |item| ele.add(definedobj2soap(item, definition)) end end else ele.add(definedobj2soap(child, definition)) end end end end added end end end end YMMV -Justin -- Posted via http://www.ruby-forum.com/.