Marcxella
A simple interface to MARC-XML, for when you just need to parse some MARC-XML quickly.
Pronounce it "marc-sélla".
Installation
Add this line to your application's Gemfile:
gem 'marcxella'
And then execute:
$ bundle
Or install it yourself as:
$ gem install marcxella
Usage
Documents
records (Marcxella::Record
) are the main objects you'll be dealing with. To get at the records, you'll probably create a document. This can be done from a filehandle:
> require "marcxella"
> file = File.open("spec/xml/1027474578.xml")
> marc = Marcxella::Document.new(file)
You can also create a document from a string of XML:
> xml = File.open("spec/xml/1027474578.xml").read
> marc = Marcxella::Document.new(xml)
Marxcella uses Nokogiri internally, so you can also just pass a Nokogiri document:
> doc = Nokogiri::XML(file)
> marc = Marcxella::Document.new(doc)
Once you have the document, you can get an array of the records:
> records = marc.records
If you want, you can create the records directly from Nokogiri nodes
> file = File.open("spec/xml/1027474578.xml")
> doc = Nokogiri::XML(file)
> records = doc.css('record').map{|r| Marcxella::Record.new(r)}
If the xml document contains collections, you can get the collections and then get the records from those.
> first_coll = marc.collections.first
> records = first_coll.records
If the document does contain collections, Marcxella::Document#records
will
simply ignore the collections and return an array of all the records from
all the collections.
Records and fields
Once you have a record, you can get the fields by tag:
> rec = marc.records.first
> f = rec.field("001")
The #field
method always returns an array, so even when you expect a single
field, you have to get it from the array. There is no distinction made between
repeating and non-repeating fields.
> control_number = rec.field("001").first
> title = rec.field("245").first
> subjects = rec.field("650")
Control fields and Data fields have different classes:
> control_number.class
=> Marcxella::ControlField
> title.class
=> Marcxella::DataField
All fields have tags and values:
> control_number.tag
=> "001"
> control_number.value
=> "1027474578"
> title.tag
=> "245"
> title.value
=> "Kindred /Octavia E. Butler."
#to_s
returns the customary representation of the field data:
> control_number.to_s
=> "001 1027474578"
> title.to_s
=> "245 10$aKindred /$cOctavia E. Butler."
> puts title
245 10$aKindred /$cOctavia E. Butler.
Data fields have subfields. You can get an array of all of them or select an array of subfields by code.
> title.subfields.count
=> 2
> title.subfield("a").first.to_s
=> "$aKindred /"
For compatibility, control fields have these methods, too, which always return empty arrays:
> control_number.subfields
=> []
> control_number.subfield("a")
=> []
Subfields have codes, values, and string representations:
> subfield = rec.titleStatement.subfield("a").first
> subfield.code
=> "a"
> subfield.value
=> "Kindred /"
> subfield.to_s
=> "$aKindred /"
You can get all instances of a subfield of a given tag. For instance, to get all the ISBN numbers:
> rec.subfield("020", "a").map{|s| s.value}
=> ["9781472214812", "1472214811"]
Convenience methods
There are several methods to make it easier to get single fields or categories
of fields. #mainEntry
will return whichever of the 1XX fields the record has
(as a DataField
, not an array):
> rec.mainEntry.to_s
=> "100 1\#$aButler, Octavia Estelle$d(1947-2006).$4aut"
#titleStatement
gets the 245 field (again, as a DataField
and not an array):
> rec.titleStatement.value
=> "Kindred /Octavia E. Butler."
There are also methods to get an array of each of the main categories of fields. Each of these returns an array of all the fields in the record of the given category:
> rec.controlFields # 00X
> rec.codes # 01X-09X
> rec.titles # 20X-24X
> rec.edition # 25X-28X
> rec.description # 3XX
> rec.series # 4XX
> rec.notes # 5XX
> rec.subjects # 6XX
> rec.addedEntries # 70X-75X
> rec.linking # 76X-78X
> rec.seriesAdded # 80X-83X
> rec.holdings # 841-88X
Some common numbers have convenience methods:
> record.lccn # 010$a, String or nil
> record.isbns # 020$a, Array of Strings, or []
> record.issns # 022$a, Array of Strings, or []
Leader
You can get the record leader:
> rec.leader
=> "00000cam a2200000Mi 4500"
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/seanredmond/marcxella. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Marcxella project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.