Class: Rets::Parser::Compact

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

Constant Summary collapse

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

Class Method Summary collapse

Class Method Details

.get_count(xml) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'lib/rets/parser/compact.rb', line 50

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(columns, 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)


38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rets/parser/compact.rb', line 38

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

  column_names = columns.split(delimiter)
  data_values = data.split(delimiter, INCLUDE_NULL_FIELDS)

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

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

.parse_document(xml) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/rets/parser/compact.rb', line 10

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")
  if column_node.nil?
    columns = ''
  else
    columns = column_node.text
  end
  rows    = doc.xpath("//DATA")

  rows.map do |data|
    self.parse(columns, data.text, delimiter)
  end
end