Class: ONIX::Reader

Inherits:
Object
  • Object
show all
Defined in:
lib/onix/reader.rb

Overview

This is the primary class for reading data from an ONIX file, and there’s really not much to it

Each file should contain a single header, and 1 or more products:

reader = ONIX::Reader.new("somefile.xml")

puts reader.header.inspect

reader.each do |product|
  puts product.inspect
end

The header will be returned as an ONIX::Header object, and the product will be an ONIX::Product.

The ONIX::Product class can be a bit of a hassle to work with, as data can be nested in it fairly deeply. To wrap all the products returned by the reader in a shim that provides simple accessor access to common attributes, pass the shim class as a second argument

reader = ONIX::Reader.new("somefile.xml", ONIX::APAProduct)

puts reader.header.inspect

reader.each do |product|
  puts product.inspect
end

APAProduct stands for Australian Publishers Association and provides simple access to the ONIX attributes that are commonly used in the Australian market.

As well as accessing the file header, there are handful of other read only attributes that might be useful

reader = ONIX::Reader.new("somefile.xml", ONIX::APAProduct)

puts reader.version
puts reader.xml_lang
puts reader.xml_version
puts reader.encoding

The version attribute is particuarly useful. There are multiple revisions of the ONIX spec, and you may need to handle the file differently based on what version it is.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input, product_klass = ::ONIX::Product) ⇒ Reader

Create a new ONIX::Reader object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/onix/reader.rb', line 59

def initialize(input, product_klass = ::ONIX::Product)
  if input.kind_of? String
    @reader = LibXML::XML::Reader.file(input)
  elsif input.kind_of?(IO)
    @reader = LibXML::XML::Reader.io(input)
  else
    throw "Unable to read from path or file"
  end

  @product_klass = product_klass

  # create a sized queue to store each product read from the file
  # We use a separate thread to read products from the source file.
  # This queue is a thread-safe way to transfer products from that
  # thread back into the main one.
  @queue = SizedQueue.new(100)

  # launch a reader thread
  Thread.abort_on_exception = true
  Thread.new { read_input }

  # don't return from the constructor until the reading thread
  # has spun up and put at least one item into the queue. If
  # it finds no Products in the file, it queues a nil, so we
  # shouldn't get stuck here indefinitely
  while @queue.size == 0
    sleep 0.05
  end
end

Instance Attribute Details

#encodingObject (readonly)

Returns the value of attribute encoding.



55
56
57
# File 'lib/onix/reader.rb', line 55

def encoding
  @encoding
end

#headerObject (readonly)

Returns the value of attribute header.



55
56
57
# File 'lib/onix/reader.rb', line 55

def header
  @header
end

#versionObject (readonly)

Returns the value of attribute version.



55
56
57
# File 'lib/onix/reader.rb', line 55

def version
  @version
end

#xml_langObject (readonly)

Returns the value of attribute xml_lang.



55
56
57
# File 'lib/onix/reader.rb', line 55

def xml_lang
  @xml_lang
end

#xml_versionObject (readonly)

Returns the value of attribute xml_version.



55
56
57
# File 'lib/onix/reader.rb', line 55

def xml_version
  @xml_version
end

Instance Method Details

#each(&block) ⇒ Object

Iterate over all the products in an ONIX file



91
92
93
94
95
96
97
# File 'lib/onix/reader.rb', line 91

def each(&block)
  obj = @queue.pop
  while !obj.nil?
    yield obj
    obj = @queue.pop
  end
end