MARC::Spec
A implementation of the MARCspec query language for Ruby and ruby-marc.
Usage
Add ruby-marc-spec to your Gemfile or gemspec, or just install it:
- Gemfile:
gem 'ruby-marc-spec'
- gemspec
spec.add_dependency 'ruby-marc-spec'
- from the command line:
gem install ruby-marc-spec
Then, in your code:
require 'marc/spec'
The entry point for MARC::Spec is the MARC::Spec#find method, which takes a string
MARCspec query and a MARC::Record object.
MARC::Spec.find('245$a', marc_record)
# => [#<MARC::Subfield:0x00007ffa1686e3f0 @code="a", @value="Arithmetic /">]
Note that for simplicity's sake MARC::Spec#find always returns an array, even for
queries that can only return a single-element result, e.g.
MARC::Spec.find('LDR', marc_record)
# => ["01142cam 2200301 a 4500"]
Examples
All examples below are based on the record sandburg.xml
from the Library of Congress MARCXML documentation.
marc_record = MARC::XMLReader.new('sandburg.xml').first
Retrieving the leader
MARC::Spec.find('LDR', marc_record)
# => ["01142cam 2200301 a 4500"]
Retrieving control fields
Find all fields whose tag begins with 00:
MARC::Spec.find('00.', marc_record)
# => [
# #<MARC::ControlField:0x00007ff9f706ac40 @tag="001", @value=" 92005291 ">,
# #<MARC::ControlField:0x00007ff9f70686c0 @tag="003", @value="DLC">,
# #<MARC::ControlField:0x00007ff9f7062450 @tag="005", @value="19930521155141.9">,
# #<MARC::ControlField:0x00007ff9f70600d8 @tag="008", @value="920219s1993 caua j 000 0 eng ">
# ]
Retrieving substrings of a control field value:
Find the first six characters (characters 0 through 6) of the 008 field:
MARC::Spec.find('008/0-5', marc_record)
# => ["920219"]
Retrieving data fields
Find the first two 650 fields (fields 0 and 1):
MARC::Spec.find('650[0-1]', marc_record)
# => [#<MARC::DataField:0x00007ffa1799a5c0
# @indicator1=" ",
# @indicator2="0",
# @subfields=[#<MARC::Subfield:0x00007ffa17999878 @code="a", @value="Arithmetic">, #<MARC::Subfield:0x00007ffa179984a0 @code="x", @value="Juvenile poetry.">],
# @tag="650">,
# #<MARC::DataField:0x00007ffa17992618
# @indicator1=" ",
# @indicator2="0",
# @subfields=[#<MARC::Subfield:0x00007ffa179918d0 @code="a", @value="Children's poetry, American.">],
# @tag="650">]
Retrieving subfields
Find subfield a of all 650 fields:
MARC::Spec.find('650$a', marc_record)
# =>
# [#<MARC::Subfield:0x00007ffa17999878 @code="a", @value="Arithmetic">,
# #<MARC::Subfield:0x00007ffa179918d0 @code="a", @value="Children's poetry, American.">,
# #<MARC::Subfield:0x00007ffa1798acb0 @code="a", @value="Arithmetic">,
# #<MARC::Subfield:0x00007ffa17982cb8 @code="a", @value="American poetry.">,
# #<MARC::Subfield:0x00007ffa17980120 @code="a", @value="Visual perception.">]
Retrieving subfield values
Find the first six characters (characters 0 through 5) of subfield a
of the fifth (zero-indexed) 650 field:
MARC::Spec.find('650[4]$a/0-5', marc_record)
# => ["Visual"]
Limiting results based on conditions:
Find all 650 fields having a value of 0 for the second indicator:
MARC::Spec.find('650{^2=\0}', marc_record)
# =>
# [#<MARC::DataField:0x00007ffa1799a5c0
# @indicator1=" ",
# @indicator2="0",
# @subfields=[#<MARC::Subfield:0x00007ffa17999878 @code="a", @value="Arithmetic">, #<MARC::Subfield:0x00007ffa179984a0 @code="x", @value="Juvenile poetry.">],
# @tag="650">,
# #<MARC::DataField:0x00007ffa17992618
# @indicator1=" ",
# @indicator2="0",
# @subfields=[#<MARC::Subfield:0x00007ffa179918d0 @code="a", @value="Children's poetry, American.">],
# @tag="650">]
Find subfield a of each 650 field that also has a subfield x:
MARC::Spec.find('650$a{$x}', marc_record)
# => [#<MARC::Subfield:0x00007ffa17999878 @code="a", @value="Arithmetic">, #<MARC::Subfield:0x00007ffa1798acb0 @code="a", @value="Arithmetic">]
Note that this 650$a{$x} could also be written 650$a{?$x}; the ? ("exists") operator
is implicit if no other operator is specified.
Find the first seven characters of 260$b, but only if the corresponding $a contains
the string San Diego and there is at least one 050$b containing as a substring characters
7 through 10 of the 008 field:
MARC::Spec.find('260$b/0-7{$a~\San\sDiego}{050$b~008/7-10}', marc_record)
# => ["Harcourt"]
For further examples, see the MARCSpec documentation.