Class: BerkeleyLibrary::TIND::MARC::XMLReader

Inherits:
Object
  • Object
show all
Includes:
Util::Files, Enumerable, MARC::NokogiriReader
Defined in:
lib/berkeley_library/tind/marc/xml_reader.rb

Overview

A customized XML reader for reading MARC records from TIND search results.

Constant Summary collapse

COMMENT_TOTAL_RE =

Constant

/Search-Engine-Total-Number-Of-Results: ([0-9]+)/.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, freeze: false) ⇒ XMLReader

Reads MARC records from an XML datasource given either as an XML string, a file path, or as an IO object.

Parameters:

  • source (String, Pathname, IO)

    an XML string, the path to a file, or an IO to read from directly

  • freeze (Boolean) (defaults to: false)

    whether to freeze each record after reading



53
54
55
56
57
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 53

def initialize(source, freeze: false)
  @handle = ensure_io(source)
  @freeze = freeze
  init
end

Instance Attribute Details

#search_idObject (readonly)

Attributes



23
24
25
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 23

def search_id
  @search_id
end

Class Method Details

.read(source, freeze: false) ⇒ Object

Reads MARC records from an XML datasource given either as an XML string, a file path, or as an IO object.

Parameters:

  • source (String, Pathname, IO)

    an XML string, the path to a file, or an IO to read from directly

  • freeze (Boolean) (defaults to: false)

    whether to freeze each record after reading



65
66
67
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 65

def read(source, freeze: false)
  new(source, freeze: freeze)
end

Instance Method Details

#characters(string) ⇒ Object

See Also:

  • Nokogiri::XML::Sax::Document#characters


105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 105

def characters(string)
  return unless (name = @current_element_name)

  case name
  when 'search_id'
    @search_id = string
  when 'total'
    @total = string.to_i
  else
    super
  end
end

#comment(string) ⇒ Object

See Also:

  • Nokogiri::XML::Sax::Document#comment


119
120
121
122
123
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 119

def comment(string)
  return unless (md = COMMENT_TOTAL_RE.match(string))

  @total = md[1].to_i
end

#end_element_namespace(name, prefix = nil, uri = nil) ⇒ Object

See Also:

  • Nokogiri::XML::Sax::Document#end_element_namespace


98
99
100
101
102
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 98

def end_element_namespace(name, prefix = nil, uri = nil)
  super

  @current_element_name = nil
end

#records_yieldedInteger

Returns the number of records yielded.

Returns:

  • (Integer)

    the number of records yielded.



41
42
43
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 41

def records_yielded
  @records_yielded ||= 0
end

#start_element_namespace(name, attrs = [], prefix = nil, uri = nil, ns = []) ⇒ Object

rubocop:disable Metrics/ParameterLists

See Also:

  • Nokogiri::XML::Sax::Document#start_element_namespace


90
91
92
93
94
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 90

def start_element_namespace(name, attrs = [], prefix = nil, uri = nil, ns = [])
  super

  @current_element_name = name
end

#totalInteger?

Returns the total number of records, based on the <total/> tag returned by the TIND Search API, or the special comment Search-Engine-Total-Number-Of-Results returned by TIND Regular Search in XML format.

Note that the total is not guaranteed to be present, and if present, may not be present unless at least some records have been parsed.

Returns:

  • (Integer, nil)

    the total number of records, or nil if the total has not been read yet



34
35
36
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 34

def total
  @total&.to_i
end

#yield_recordObject

MARC::GenericPullParser overrides



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/berkeley_library/tind/marc/xml_reader.rb', line 73

def yield_record
  @record[:record].tap do |record|
    clean_cf_values(record)
    move_cf000_to_leader(record)
    record.freeze if @freeze
  end

  super
ensure
  increment_records_yielded!
end