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').firstRetrieving 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.
For developers
Generated tests
The tests for this gem include a set generated from the MARCSpec-Test-Suite
project, which is provided as a Git submodule
under spec/suite.
The tests themselves are in spec/suite/generated. It's not necessary to fetch the submodule in order
to run these tests, but it is necessary if you need to regenerate them. To fetch the submodule, from the project root, run:
git submodule init
git submodule updateTo regenerate the tests, run rake spec:generate.