require 'rets4r/client/transaction' require 'rets4r/client/parsers/compact' require 'rexml/document' module RETS4R class Client class ResponseParser def parse_key_value(xml) parse_common(xml) do |doc| parsed = nil first_child = doc.get_elements('/RETS/RETS-RESPONSE')[0] ? doc.get_elements('/RETS/RETS-RESPONSE')[0] : doc.get_elements('/RETS')[0] unless first_child.nil? parsed = {} first_child.text.each do |line| (key, value) = line.strip.split('=') key.strip! if key value.strip! if value parsed[key] = value end else raise 'Response was not a proper RETS XML doc!' end if parsed.nil? raise "Response was not valid key/value format" else parsed end end end def parse_results(xml, format) parse_common(xml) do |doc| parser = get_parser_by_name(format) parser.parse_results(doc) end end def parse_count(xml) parse_common(xml) do |doc| doc.get_elements('/RETS/COUNT')[0].attributes['Records'] end end def parse_metadata(xml, format) parse_common(xml) do |doc| return REXML::Document.new(xml) end end def parse_object_response(xml) parse_common(xml) do |doc| # XXX end end private def parse_common(xml, &block) if xml == '' raise RETSException, 'No transaction body was returned!' end doc = REXML::Document.new(xml) root = doc.root if root.nil? || root.name != 'RETS' raise "Response had invalid root node. Document was: #{doc.inspect}" end transaction = Transaction.new transaction.reply_code = root.attributes['ReplyCode'] transaction.reply_text = root.attributes['ReplyText'] transaction.maxrows = (doc.get_elements('/RETS/MAXROWS').length > 0) # XXX: If it turns out we need to parse the response of errors, then this will # need to change. if transaction.reply_code.to_i > 0 && transaction.reply_code.to_i != 20201 exception_type = Client::EXCEPTION_TYPES[transaction.reply_code.to_i] || RETSTransactionException raise exception_type, "#{transaction.reply_code} - #{transaction.reply_text}" end transaction.response = yield doc return transaction end def get_parser_by_name(name) case name when 'COMPACT', 'COMPACT-DECODED' type = RETS4R::Client::CompactDataParser else raise "Invalid format #{name}" end type.new end end end end