module Soaspec::ResponseExtractor
Enables extracting a response according to type / path
Public Instance Methods
Convert XML or JSON response into a Hash
. Doesn't accept empty body @param [String] response Response as a String (either in XML or JSON) @return [Hash] Extracted Hash
from response
# File lib/soaspec/exchange_handlers/response_extractor.rb, line 9 def extract_hash(response) raise NoElementAtPath, "Empty Body. Can't assert on it" if response.body.empty? case Interpreter.response_type_for response when :xml then parse_xml(response.body.to_s) when :json converted = JSON.parse(response.body) return converted.transform_keys_to_symbols if converted.is_a? Hash return converted.map!(&:transform_keys_to_symbols) if converted.is_a? Array raise Soaspec::ResponseError, 'Incorrect Type produced ' + converted.class else raise Soaspec::ResponseError, "Neither XML nor JSON detected. It is #{type}. Don't know how to parse It is #{response.body}" end end
@param [Object] response Response object @return [Hash] Hash
representing response body
# File lib/soaspec/exchange_handlers/response_extractor.rb, line 27 def to_hash(response) case Interpreter.response_type_for(response) when :xml then IndifferentHash.new(parse_xml(response.body.to_s)) when :json IndifferentHash.new(JSON.parse(response.body.to_s)) else raise "Unable to interpret type of '#{response.body}'. Could be because of: #{Interpreter.diagnose_error}" end end
Private Instance Methods
Find element with name specified or pascal case equivalent @return [String] String to find paths with pascal converted or given path
# File lib/soaspec/exchange_handlers/response_extractor.rb, line 68 def add_pascal_path(json_path) return json_path unless pascal_keys? json_path.split(',').collect do |sub_path| "#{sub_path},#{convert_to_pascal_case(sub_path)}" end.join(',') end
Convert snakecase to PascalCase @return [String] PascalCase converted path
# File lib/soaspec/exchange_handlers/response_extractor.rb, line 60 def convert_to_pascal_case(key) return key if /[[:upper:]]/ =~ key[0] # If first character already capital, don't do conversion key.split('_').map(&:capitalize).join end
@param [String] xml XML to convert @return [Hash] Hash
representing XML
# File lib/soaspec/exchange_handlers/response_extractor.rb, line 41 def parse_xml(xml) parser = Nori.new(strip_namespaces: strip_namespaces?, convert_tags_to: ->(tag) { tag.snakecase.to_sym }) parser.parse(xml) end
@param [String] json_path Path set from Exchange
@return [String] JSON Path
# File lib/soaspec/exchange_handlers/response_extractor.rb, line 78 def prefix_json_path(json_path) return json_path if json_path[0] == '$' "$..#{json_path}" end
This enables shortcut xpaths to be used. If no '/' is given, one is appended to the start of the path If attribute value is set then this is also adjusted @return [String] New Xpath adjusted according to any add ons
# File lib/soaspec/exchange_handlers/response_extractor.rb, line 49 def prefix_xpath(xpath, attribute) xpath = "//*[@#{attribute}]" unless attribute.nil? if xpath[0] != '/' xpath = convert_to_pascal_case(xpath) if pascal_keys? xpath = '//' + xpath end xpath end