Class: Rets::Parser::Compact

Inherits:
Object
  • Object
show all
Defined in:
lib/rets/parser/compact.rb

Constant Summary collapse

TAB =
/\t/
InvalidDelimiter =
Class.new(ArgumentError)

Class Method Summary collapse

Class Method Details

.get_count(xml) ⇒ Object



43
44
45
46
47
48
49
50
51
# File 'lib/rets/parser/compact.rb', line 43

def self.get_count(xml)
  doc = Nokogiri.parse(xml.to_s)
  if node = doc.at("//COUNT")
    return node.attr('Records').to_i
  elsif node = doc.at("//RETS-STATUS")
    # Handle <RETS-STATUS ReplyCode="20201" ReplyText="No matching records were found" />
    return 0 if node.attr('ReplyCode') == '20201'
  end
end

.parse_document(xml) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/rets/parser/compact.rb', line 8

def self.parse_document(xml)
  doc = Nokogiri.parse(xml.to_s)

  delimiter = doc.at("//DELIMITER")
  delimiter = delimiter ? Regexp.new(Regexp.escape(delimiter.attr(:value).to_i.chr)) : TAB

  if delimiter == // || delimiter == /,/
    raise InvalidDelimiter, "Empty or invalid delimiter found, unable to parse."
  end

  column_node  = doc.at("//COLUMNS")
  column_names = column_node.nil? ? [] : column_node.text.split(delimiter)

  rows = doc.xpath("//DATA")
  rows.map do |data|
    self.parse_row(column_names, data.text, delimiter)
  end
end

.parse_row(column_names, data, delimiter = TAB) ⇒ Object

Parses a single row of RETS-COMPACT data.

Delimiter must be a regexp because String#split behaves differently when given a string pattern. (It removes leading spaces).

Raises:

  • (ArgumentError)


32
33
34
35
36
37
38
39
40
41
# File 'lib/rets/parser/compact.rb', line 32

def self.parse_row(column_names, data, delimiter = TAB)
  raise ArgumentError, "Delimiter must be a regular expression" unless Regexp === delimiter

  data_values = data.split(delimiter).map { |x| CGI.unescapeHTML(x) }

  zipped_key_values = column_names.zip(data_values).map { |k, v| [k.freeze, v.to_s] }

  hash = Hash[*zipped_key_values.flatten]
  hash.reject { |key, value| key.empty? && value.to_s.empty? }
end