marc 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +3 -1
- data/Rakefile +2 -2
- data/lib/marc/controlfield.rb +5 -1
- data/lib/marc/datafield.rb +75 -2
- data/lib/marc/record.rb +126 -5
- data/test/random_tag_order.dat +1 -0
- data/test/random_tag_order.xml +72 -0
- data/test/random_tag_order2.dat +1 -0
- data/test/random_tag_order2.xml +148 -0
- data/test/tc_hash.rb +26 -0
- data/test/tc_record.rb +38 -1
- metadata +25 -5
data/README
CHANGED
@@ -44,7 +44,9 @@ and install the versioned gem:
|
|
44
44
|
AUTHORS
|
45
45
|
|
46
46
|
Kevin Clarke <ksclarke@gmail.com>
|
47
|
+
Bill Dueber <bill@dueber.com>
|
47
48
|
William Groppe <will.groppe@gmail.com>
|
49
|
+
Ross Singer <rossfsinger@gmail.com>
|
48
50
|
Ed Summers <ehs@pobox.com>
|
49
51
|
|
50
|
-
Please send bugs, requests and comments to
|
52
|
+
Please send bugs, requests and comments to Code4Lib Mailing list (https://listserv.nd.edu/cgi-bin/wa?A0=CODE4LIB).
|
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
RUBY_MARC_VERSION = '0.
|
1
|
+
RUBY_MARC_VERSION = '0.4.0'
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'rake'
|
@@ -30,7 +30,7 @@ spec = Gem::Specification.new do |s|
|
|
30
30
|
s.autorequire = 'marc'
|
31
31
|
s.has_rdoc = true
|
32
32
|
s.required_ruby_version = '>= 1.8.6'
|
33
|
-
s.authors = ["Kevin Clarke", "William Groppe", "Ross Singer", "Ed Summers"]
|
33
|
+
s.authors = ["Kevin Clarke", "Bill Dueber", "William Groppe", "Ross Singer", "Ed Summers"]
|
34
34
|
s.test_file = 'test/ts_marc.rb'
|
35
35
|
s.bindir = 'bin'
|
36
36
|
end
|
data/lib/marc/controlfield.rb
CHANGED
data/lib/marc/datafield.rb
CHANGED
@@ -3,6 +3,44 @@ require 'marc/record'
|
|
3
3
|
require 'marc/controlfield'
|
4
4
|
|
5
5
|
module MARC
|
6
|
+
|
7
|
+
class SubfieldMap < Array
|
8
|
+
attr_reader :codes
|
9
|
+
def initialize
|
10
|
+
@codes = HashWithChecksumAttribute.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def in_sync?
|
14
|
+
@codes.checksum == self.hash
|
15
|
+
end
|
16
|
+
|
17
|
+
def reindex
|
18
|
+
@codes.clear
|
19
|
+
self.each do |subfield|
|
20
|
+
@codes[subfield.code] ||= []
|
21
|
+
@codes[subfield.code] << self.index(subfield)
|
22
|
+
end
|
23
|
+
@codes.checksum = self.hash
|
24
|
+
end
|
25
|
+
def code_list
|
26
|
+
reindex unless in_sync?
|
27
|
+
@codes.keys
|
28
|
+
end
|
29
|
+
|
30
|
+
def each_by_code(codes)
|
31
|
+
reindex unless in_sync?
|
32
|
+
matched_codes = []
|
33
|
+
[*codes].each do |code|
|
34
|
+
next unless code && @codes[code]
|
35
|
+
@codes[code].each do |idx|
|
36
|
+
matched_codes << self[idx]
|
37
|
+
yield self[idx]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
matched_codes
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
6
44
|
|
7
45
|
# MARC records contain data fields, each of which has a tag,
|
8
46
|
# indicators and subfields. Tags for data fields must are all
|
@@ -34,7 +72,7 @@ module MARC
|
|
34
72
|
attr_accessor :indicator2
|
35
73
|
|
36
74
|
# A list of MARC::Subfield objects
|
37
|
-
attr_accessor :subfields
|
75
|
+
#attr_accessor :subfields
|
38
76
|
|
39
77
|
|
40
78
|
# Create a new field with tag, indicators and subfields.
|
@@ -64,7 +102,7 @@ module MARC
|
|
64
102
|
# screw us up later when we try to encode
|
65
103
|
@indicator1 = i1 == nil ? ' ' : i1
|
66
104
|
@indicator2 = i2 == nil ? ' ' : i2
|
67
|
-
@subfields =
|
105
|
+
@subfields = SubfieldMap.new
|
68
106
|
|
69
107
|
# must use MARC::ControlField for tags < 010 or
|
70
108
|
# those in MARC::ControlField#extra_control_fields
|
@@ -110,6 +148,15 @@ module MARC
|
|
110
148
|
return [@tag, @indicator1, @indicator2, @subfields.map {|sf| [sf.code, sf.value]} ]
|
111
149
|
end
|
112
150
|
|
151
|
+
# Turn the variable field and subfields into a hash for MARC-in-JSON
|
152
|
+
|
153
|
+
def to_hash
|
154
|
+
field_hash = {@tag=>{'ind1'=>@indicator1,'ind2'=>@indicator2,'subfields'=>[]}}
|
155
|
+
self.each do |subfield|
|
156
|
+
field_hash[@tag]['subfields'] << {subfield.code=>subfield.value}
|
157
|
+
end
|
158
|
+
field_hash
|
159
|
+
end
|
113
160
|
|
114
161
|
# Add a subfield (MARC::Subfield) to the field
|
115
162
|
# field.append(MARC::Subfield.new('a','Dave Thomas'))
|
@@ -118,6 +165,7 @@ module MARC
|
|
118
165
|
@subfields.push(subfield)
|
119
166
|
end
|
120
167
|
|
168
|
+
|
121
169
|
|
122
170
|
# You can iterate through the subfields in a Field:
|
123
171
|
# field.each {|s| print s}
|
@@ -128,6 +176,9 @@ module MARC
|
|
128
176
|
end
|
129
177
|
end
|
130
178
|
|
179
|
+
def each_by_code(filter)
|
180
|
+
@subfields.each_by_code(filter)
|
181
|
+
end
|
131
182
|
|
132
183
|
# You can lookup subfields with this shorthand. Note it
|
133
184
|
# will return a string and not a MARC::Subfield object.
|
@@ -138,7 +189,29 @@ module MARC
|
|
138
189
|
return subfield.value if subfield
|
139
190
|
return
|
140
191
|
end
|
192
|
+
|
193
|
+
def subfields(filter=nil)
|
194
|
+
return @subfields unless filter
|
195
|
+
@subfields.reindex unless subfields.in_sync?
|
196
|
+
subflds = []
|
197
|
+
if filter.is_a?(String) && @subfields.codes[filter]
|
198
|
+
@subfields.codes[filter].each do |idx|
|
199
|
+
subflds << @subfields[idx]
|
200
|
+
end
|
201
|
+
elsif filter.is_a?(Array) || filter.is_a?(Range)
|
202
|
+
filter.each do |code|
|
203
|
+
next unless @subfields.codes[code]
|
204
|
+
@subfields.codes[code].each do |idx|
|
205
|
+
subflds << @subfields[idx]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
subflds
|
210
|
+
end
|
141
211
|
|
212
|
+
def codes
|
213
|
+
@subfields.code_list
|
214
|
+
end
|
142
215
|
|
143
216
|
# Two fields are equal if their tag, indicators and
|
144
217
|
# subfields are all equal.
|
data/lib/marc/record.rb
CHANGED
@@ -1,7 +1,65 @@
|
|
1
1
|
require 'marc/controlfield'
|
2
2
|
require 'marc/datafield'
|
3
3
|
|
4
|
-
module MARC
|
4
|
+
module MARC
|
5
|
+
|
6
|
+
# Simply what the class name says.
|
7
|
+
# The checksum is used to see if the FieldMap's array has changed.
|
8
|
+
class HashWithChecksumAttribute < Hash
|
9
|
+
attr_accessor :checksum
|
10
|
+
end
|
11
|
+
|
12
|
+
# The FieldMap is an Array of DataFields and Controlfields.
|
13
|
+
# It also contains a HashWithChecksumAttribute with a Hash-based
|
14
|
+
# representation of the fields for faster lookups
|
15
|
+
class FieldMap < Array
|
16
|
+
attr_reader :tags
|
17
|
+
def initialize
|
18
|
+
@tags = HashWithChecksumAttribute.new
|
19
|
+
end
|
20
|
+
|
21
|
+
# Checks to see if the HashWithChecksumAttribute is in sync
|
22
|
+
# with the Array of fields
|
23
|
+
def in_sync?
|
24
|
+
@tags.checksum == self.hash
|
25
|
+
end
|
26
|
+
|
27
|
+
# Rebuild the HashWithChecksumAttribute with the current
|
28
|
+
# values of the fields Array
|
29
|
+
def reindex
|
30
|
+
@tags.clear
|
31
|
+
self.each do |field|
|
32
|
+
@tags[field.tag] ||= []
|
33
|
+
@tags[field.tag] << self.index(field)
|
34
|
+
end
|
35
|
+
@tags.checksum = self.hash
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns an array of all of the tags that appear in the record (not in the order they appear, however).
|
39
|
+
def tag_list
|
40
|
+
reindex unless in_sync?
|
41
|
+
@tags.keys
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns an array of fields, in the order they appear, according to their tag.
|
45
|
+
# The tags argument can be a string (e.g. '245'), an array (['100','700','800'])
|
46
|
+
# or a range (('600'..'699')).
|
47
|
+
def each_by_tag(tags)
|
48
|
+
reindex unless in_sync?
|
49
|
+
matched_tags = []
|
50
|
+
[*tags].each do |tag|
|
51
|
+
next unless tag && @tags[tag]
|
52
|
+
@tags[tag].each do |idx|
|
53
|
+
matched_tags[idx] = self[idx]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
matched_tags.compact!
|
57
|
+
matched_tags.each do |tag|
|
58
|
+
yield tag
|
59
|
+
end
|
60
|
+
matched_tags
|
61
|
+
end
|
62
|
+
end
|
5
63
|
|
6
64
|
# A class that represents an individual MARC record. Every record
|
7
65
|
# is made up of a collection of MARC::DataField objects.
|
@@ -22,13 +80,13 @@ module MARC
|
|
22
80
|
include Enumerable
|
23
81
|
|
24
82
|
# the record fields
|
25
|
-
|
83
|
+
#attr_reader :fields
|
26
84
|
|
27
85
|
# the record leader
|
28
86
|
attr_accessor :leader
|
29
87
|
|
30
88
|
def initialize
|
31
|
-
@fields =
|
89
|
+
@fields = FieldMap.new
|
32
90
|
# leader is 24 bytes
|
33
91
|
@leader = ' ' * 24
|
34
92
|
# leader defaults:
|
@@ -51,7 +109,7 @@ module MARC
|
|
51
109
|
end
|
52
110
|
|
53
111
|
# each() is here to support iterating and searching since MARC::Record
|
54
|
-
# mixes in
|
112
|
+
# mixes in Enumerable
|
55
113
|
#
|
56
114
|
# iterating through the fields in a record:
|
57
115
|
# record.each { |f| print f }
|
@@ -67,6 +125,12 @@ module MARC
|
|
67
125
|
yield field
|
68
126
|
end
|
69
127
|
end
|
128
|
+
|
129
|
+
# A more convenient way to iterate over each field with a given tag.
|
130
|
+
# The filter argument can be a string, array or range.
|
131
|
+
def each_by_tag(filter)
|
132
|
+
@fields.each_by_tag(filter) {|tag| yield tag }
|
133
|
+
end
|
70
134
|
|
71
135
|
# You can lookup fields using this shorthand:
|
72
136
|
# title = record['245']
|
@@ -74,6 +138,31 @@ module MARC
|
|
74
138
|
def [](tag)
|
75
139
|
return self.find {|f| f.tag == tag}
|
76
140
|
end
|
141
|
+
|
142
|
+
# Provides a backwards compatible means to access the FieldMap.
|
143
|
+
# No argument returns the FieldMap array in entirety. Providing
|
144
|
+
# a string, array or range of tags will return an array of fields
|
145
|
+
# in the order they appear in the record.
|
146
|
+
def fields(filter=nil)
|
147
|
+
return @fields.to_a unless filter
|
148
|
+
@fields.reindex unless @fields.in_sync?
|
149
|
+
flds = []
|
150
|
+
if filter.is_a?(String) && @fields.tags[filter]
|
151
|
+
@fields.tags[filter].each do |idx|
|
152
|
+
flds << @fields[idx]
|
153
|
+
end
|
154
|
+
elsif filter.is_a?(Array) || filter.is_a?(Range)
|
155
|
+
@fields.each_by_tag(filter) do |tag|
|
156
|
+
flds << tag
|
157
|
+
end
|
158
|
+
end
|
159
|
+
flds
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns an array of all of the tags that appear in the record (not necessarily in the order they appear).
|
163
|
+
def tags
|
164
|
+
return @fields.tag_list
|
165
|
+
end
|
77
166
|
|
78
167
|
# Factory method for creating a MARC::Record from MARC21 in
|
79
168
|
# transmission format.
|
@@ -130,7 +219,7 @@ module MARC
|
|
130
219
|
'fields' => self.map {|f| f.to_marchash}
|
131
220
|
}
|
132
221
|
end #to_hash
|
133
|
-
|
222
|
+
|
134
223
|
# Factory method for creating a new MARC::Record from
|
135
224
|
# a marchash object
|
136
225
|
#
|
@@ -150,6 +239,38 @@ module MARC
|
|
150
239
|
end
|
151
240
|
|
152
241
|
|
242
|
+
|
243
|
+
# Returns a (roundtrippable) hash representation for MARC-in-JSON
|
244
|
+
def to_hash
|
245
|
+
record_hash = {'leader'=>@leader, 'fields'=>[]}
|
246
|
+
@fields.each do |field|
|
247
|
+
record_hash['fields'] << field.to_hash
|
248
|
+
end
|
249
|
+
record_hash
|
250
|
+
end
|
251
|
+
|
252
|
+
def self.new_from_hash(h)
|
253
|
+
r = self.new
|
254
|
+
r.leader = h['leader']
|
255
|
+
if h['fields']
|
256
|
+
h['fields'].each do |position|
|
257
|
+
position.each_pair do |tag, field|
|
258
|
+
if field.is_a?(Hash)
|
259
|
+
f = MARC::DataField.new(tag, field['ind1'], field['ind2'])
|
260
|
+
field['subfields'].each do | pos |
|
261
|
+
pos.each_pair do |code, value|
|
262
|
+
f.append MARC::Subfield.new(code, value)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
r << f
|
266
|
+
else
|
267
|
+
r << MARC::ControlField.new(tag, field)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
return r
|
273
|
+
end
|
153
274
|
# Returns a string version of the record, suitable for printing
|
154
275
|
|
155
276
|
def to_s
|
@@ -0,0 +1 @@
|
|
1
|
+
01199njm a22002657a 4500001000800000005001700008007001400025008004100039035002100080906004500101010001700146028002100163040001300184050002000197245004100217260004300258300005700301511008200358505037800440500001800818650002100836700002800857953000900885991003900894567743719930615144807.4sdubmmennmplu930430s1966 nyuuun eng 9(DLC) 93710188 a7bcbccorignewd5encipf19gy-genmusic a 93710188 00aC2L 41bColumbia aDLCcDLC00aColumbia C2L 4100aBlonde on blondeh[sound recording]. a[New York, N.Y.] :bColumbia,c[1966?] a2 sound discs :banalog, 33 1/3 rpm, mono. ;c12 in.0 aWritten and performed by Bob Dylan, vocals, harmonica ; with other musicians.0 aRainy day women #12 & 35 -- Pledging my time -- Visions of Johanna -- One of us must know (Sooner or later) -- I want you -- Memphis blues again -- Leopard-skin pill-box hat -- Just like a woman -- Most likely you go your way and I'll go mine -- Temporary like Achilles -- Absolutely sweet Marie -- 4th time around -- Obviously 5 believers -- Sad eyed lady of the lowlands. aBrief record. 0aFolk-rock music.1 aDylan, Bob,d1941-4prf aTA28 bc-RecSoundhColumbia C2L 41wMUSIC
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><record xmlns="http://www.loc.gov/MARC21/slim" xmlns:cinclude="http://apache.org/cocoon/include/1.0" xmlns:zs="http://www.loc.gov/zing/srw/">
|
2
|
+
<leader>01199njm a22002657a 4500</leader>
|
3
|
+
<controlfield tag="001">5677437</controlfield>
|
4
|
+
<controlfield tag="005">19930615144807.4</controlfield>
|
5
|
+
<controlfield tag="007">sdubmmennmplu</controlfield>
|
6
|
+
<controlfield tag="008">930430s1966 nyuuun eng </controlfield>
|
7
|
+
<datafield tag="035" ind1=" " ind2=" ">
|
8
|
+
<subfield code="9">(DLC) 93710188</subfield>
|
9
|
+
</datafield>
|
10
|
+
<datafield tag="906" ind1=" " ind2=" ">
|
11
|
+
<subfield code="a">7</subfield>
|
12
|
+
<subfield code="b">cbc</subfield>
|
13
|
+
<subfield code="c">orignew</subfield>
|
14
|
+
<subfield code="d">5</subfield>
|
15
|
+
<subfield code="e">ncip</subfield>
|
16
|
+
<subfield code="f">19</subfield>
|
17
|
+
<subfield code="g">y-genmusic</subfield>
|
18
|
+
</datafield>
|
19
|
+
<datafield tag="010" ind1=" " ind2=" ">
|
20
|
+
<subfield code="a"> 93710188 </subfield>
|
21
|
+
</datafield>
|
22
|
+
<datafield tag="028" ind1="0" ind2="0">
|
23
|
+
<subfield code="a">C2L 41</subfield>
|
24
|
+
<subfield code="b">Columbia</subfield>
|
25
|
+
</datafield>
|
26
|
+
<datafield tag="040" ind1=" " ind2=" ">
|
27
|
+
<subfield code="a">DLC</subfield>
|
28
|
+
<subfield code="c">DLC</subfield>
|
29
|
+
</datafield>
|
30
|
+
<datafield tag="050" ind1="0" ind2="0">
|
31
|
+
<subfield code="a">Columbia C2L 41</subfield>
|
32
|
+
</datafield>
|
33
|
+
<datafield tag="245" ind1="0" ind2="0">
|
34
|
+
<subfield code="a">Blonde on blonde</subfield>
|
35
|
+
<subfield code="h">[sound recording].</subfield>
|
36
|
+
</datafield>
|
37
|
+
<datafield tag="260" ind1=" " ind2=" ">
|
38
|
+
<subfield code="a">[New York, N.Y.] :</subfield>
|
39
|
+
<subfield code="b">Columbia,</subfield>
|
40
|
+
<subfield code="c">[1966?]</subfield>
|
41
|
+
</datafield>
|
42
|
+
<datafield tag="300" ind1=" " ind2=" ">
|
43
|
+
<subfield code="a">2 sound discs :</subfield>
|
44
|
+
<subfield code="b">analog, 33 1/3 rpm, mono. ;</subfield>
|
45
|
+
<subfield code="c">12 in.</subfield>
|
46
|
+
</datafield>
|
47
|
+
<datafield tag="511" ind1="0" ind2=" ">
|
48
|
+
<subfield code="a">Written and performed by Bob Dylan, vocals, harmonica ; with other musicians.</subfield>
|
49
|
+
</datafield>
|
50
|
+
<datafield tag="505" ind1="0" ind2=" ">
|
51
|
+
<subfield code="a">Rainy day women #12 & 35 -- Pledging my time -- Visions of Johanna -- One of us must know (Sooner or later) -- I want you -- Memphis blues again -- Leopard-skin pill-box hat -- Just like a woman -- Most likely you go your way and I'll go mine -- Temporary like Achilles -- Absolutely sweet Marie -- 4th time around -- Obviously 5 believers -- Sad eyed lady of the lowlands.</subfield>
|
52
|
+
</datafield>
|
53
|
+
<datafield tag="500" ind1=" " ind2=" ">
|
54
|
+
<subfield code="a">Brief record.</subfield>
|
55
|
+
</datafield>
|
56
|
+
<datafield tag="650" ind1=" " ind2="0">
|
57
|
+
<subfield code="a">Folk-rock music.</subfield>
|
58
|
+
</datafield>
|
59
|
+
<datafield tag="700" ind1="1" ind2=" ">
|
60
|
+
<subfield code="a">Dylan, Bob,</subfield>
|
61
|
+
<subfield code="d">1941-</subfield>
|
62
|
+
<subfield code="4">prf</subfield>
|
63
|
+
</datafield>
|
64
|
+
<datafield tag="953" ind1=" " ind2=" ">
|
65
|
+
<subfield code="a">TA28</subfield>
|
66
|
+
</datafield>
|
67
|
+
<datafield tag="991" ind1=" " ind2=" ">
|
68
|
+
<subfield code="b">c-RecSound</subfield>
|
69
|
+
<subfield code="h">Columbia C2L 41</subfield>
|
70
|
+
<subfield code="w">MUSIC</subfield>
|
71
|
+
</datafield>
|
72
|
+
</record>
|
@@ -0,0 +1 @@
|
|
1
|
+
02500cjm a22004571a 45000010009000000050017000090070015000260080041000410350023000820400018001050280021001230410013001440350023001570240017001800280027001970100017002240420013002410500014002541000023002682450086002912460027003772600037004043000060004413060011005014400017005125000093005295000055006225110024006775180055007015000231007565000213009875000018012005000045012185050572012636500018018359060045018539250038018989520012019369550066019489850028020141337876820070513203356.0sd fsngnnmmned031021p20032002ohubln ez eng d a(DLC) 2003577486 aNTGcNTGdDLC02aCD-83567bTelarc0 denggeng a(OCoLC)ocm526272551 a08940835672802aCD-83567bTelarc Blues a 2003577486 alcderive00aSDA 807181 aDylan, Bob,d1941-10aBlues on Blonde on blondeh[sound recording] /c[all songs written by Bob Dylan].3 aBlonde on blonde blues aCleveland, OH :bTelarc,cp2003. a1 sound disc (67 min.) :bdigital, stereo. ;c4 3/4 in. a010717 0aTelarc blues a"Contemporary blues" interpretations of previously released songs; written by Bob Dylan. aStatement of responsibility from container insert.0 aVarious performers. aRecorded July 2002 at the Studio, Portland, Maine. a"Nearly thirty years after the debut of Bob Dylan's 'Blonde on blonde', Telarc assembles some of the finest artists on the contemporary blues scene to salute the monumental blues/folk/rock recording"--Container exterior sheet. a"Fully 27 years after the debut of 'Blonde on blonde', Telarc gathered an assembly of contemporary blues artists to pay tribute to Dylan's masterpiece from his controversial electric period"--All Music Guide. aCompact disc. aComposer and program notes in container.00tRainy day women # 12 & 35r(Brian Stoltz) --tMost likely you go your way and I'll go miner(Sue Foley) --tLeopard-skin pill-box hatr(Walter Trout) --tVisions of Johannar(Anders Osborne) --tPledging my timer(Duke Robillard) --tJust like a womanr(Eric Bibb) --tStuck inside of Mobile with the Memphis blues againr(Joe Louis Walker) --tObviously 5 believersr(Sean Costello) --tOne of us must know (sooner or later)r(Clarence Bucaro) --tTemporary like Achillesr(Deborah Coleman) --tI want your(Cyril Neville) --tAbsolutely sweet Marier(C.J. Chenier). 0aBlues (Music) a7bcbcccopycatd3encipf20gy-genmusic0 aacquireb2 copiesxpolicy default amuzerec avn22 2003-10-28 to MBRS/RSevn17 2004-02-25 copy 2 to MBRS/RS cOCLCesrreplace 2004-01
|
@@ -0,0 +1,148 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><record xmlns="http://www.loc.gov/MARC21/slim" xmlns:cinclude="http://apache.org/cocoon/include/1.0" xmlns:zs="http://www.loc.gov/zing/srw/">
|
2
|
+
<leader>02500cjm a22004571a 4500</leader>
|
3
|
+
<controlfield tag="001">13378768</controlfield>
|
4
|
+
<controlfield tag="005">20070513203356.0</controlfield>
|
5
|
+
<controlfield tag="007">sd fsngnnmmned</controlfield>
|
6
|
+
<controlfield tag="008">031021p20032002ohubln ez eng d</controlfield>
|
7
|
+
<datafield tag="035" ind1=" " ind2=" ">
|
8
|
+
<subfield code="a">(DLC) 2003577486</subfield>
|
9
|
+
</datafield>
|
10
|
+
<datafield tag="040" ind1=" " ind2=" ">
|
11
|
+
<subfield code="a">NTG</subfield>
|
12
|
+
<subfield code="c">NTG</subfield>
|
13
|
+
<subfield code="d">DLC</subfield>
|
14
|
+
</datafield>
|
15
|
+
<datafield tag="028" ind1="0" ind2="2">
|
16
|
+
<subfield code="a">CD-83567</subfield>
|
17
|
+
<subfield code="b">Telarc</subfield>
|
18
|
+
</datafield>
|
19
|
+
<datafield tag="041" ind1="0" ind2=" ">
|
20
|
+
<subfield code="d">eng</subfield>
|
21
|
+
<subfield code="g">eng</subfield>
|
22
|
+
</datafield>
|
23
|
+
<datafield tag="035" ind1=" " ind2=" ">
|
24
|
+
<subfield code="a">(OCoLC)ocm52627255</subfield>
|
25
|
+
</datafield>
|
26
|
+
<datafield tag="024" ind1="1" ind2=" ">
|
27
|
+
<subfield code="a">089408356728</subfield>
|
28
|
+
</datafield>
|
29
|
+
<datafield tag="028" ind1="0" ind2="2">
|
30
|
+
<subfield code="a">CD-83567</subfield>
|
31
|
+
<subfield code="b">Telarc Blues</subfield>
|
32
|
+
</datafield>
|
33
|
+
<datafield tag="010" ind1=" " ind2=" ">
|
34
|
+
<subfield code="a"> 2003577486</subfield>
|
35
|
+
</datafield>
|
36
|
+
<datafield tag="042" ind1=" " ind2=" ">
|
37
|
+
<subfield code="a">lcderive</subfield>
|
38
|
+
</datafield>
|
39
|
+
<datafield tag="050" ind1="0" ind2="0">
|
40
|
+
<subfield code="a">SDA 80718</subfield>
|
41
|
+
</datafield>
|
42
|
+
<datafield tag="100" ind1="1" ind2=" ">
|
43
|
+
<subfield code="a">Dylan, Bob,</subfield>
|
44
|
+
<subfield code="d">1941-</subfield>
|
45
|
+
</datafield>
|
46
|
+
<datafield tag="245" ind1="1" ind2="0">
|
47
|
+
<subfield code="a">Blues on Blonde on blonde</subfield>
|
48
|
+
<subfield code="h">[sound recording] /</subfield>
|
49
|
+
<subfield code="c">[all songs written by Bob Dylan].</subfield>
|
50
|
+
</datafield>
|
51
|
+
<datafield tag="246" ind1="3" ind2=" ">
|
52
|
+
<subfield code="a">Blonde on blonde blues</subfield>
|
53
|
+
</datafield>
|
54
|
+
<datafield tag="260" ind1=" " ind2=" ">
|
55
|
+
<subfield code="a">Cleveland, OH :</subfield>
|
56
|
+
<subfield code="b">Telarc,</subfield>
|
57
|
+
<subfield code="c">p2003.</subfield>
|
58
|
+
</datafield>
|
59
|
+
<datafield tag="300" ind1=" " ind2=" ">
|
60
|
+
<subfield code="a">1 sound disc (67 min.) :</subfield>
|
61
|
+
<subfield code="b">digital, stereo. ;</subfield>
|
62
|
+
<subfield code="c">4 3/4 in.</subfield>
|
63
|
+
</datafield>
|
64
|
+
<datafield tag="306" ind1=" " ind2=" ">
|
65
|
+
<subfield code="a">010717</subfield>
|
66
|
+
</datafield>
|
67
|
+
<datafield tag="440" ind1=" " ind2="0">
|
68
|
+
<subfield code="a">Telarc blues</subfield>
|
69
|
+
</datafield>
|
70
|
+
<datafield tag="500" ind1=" " ind2=" ">
|
71
|
+
<subfield code="a">"Contemporary blues" interpretations of previously released songs; written by Bob Dylan.</subfield>
|
72
|
+
</datafield>
|
73
|
+
<datafield tag="500" ind1=" " ind2=" ">
|
74
|
+
<subfield code="a">Statement of responsibility from container insert.</subfield>
|
75
|
+
</datafield>
|
76
|
+
<datafield tag="511" ind1="0" ind2=" ">
|
77
|
+
<subfield code="a">Various performers.</subfield>
|
78
|
+
</datafield>
|
79
|
+
<datafield tag="518" ind1=" " ind2=" ">
|
80
|
+
<subfield code="a">Recorded July 2002 at the Studio, Portland, Maine.</subfield>
|
81
|
+
</datafield>
|
82
|
+
<datafield tag="500" ind1=" " ind2=" ">
|
83
|
+
<subfield code="a">"Nearly thirty years after the debut of Bob Dylan's 'Blonde on blonde', Telarc assembles some of the finest artists on the contemporary blues scene to salute the monumental blues/folk/rock recording"--Container exterior sheet.</subfield>
|
84
|
+
</datafield>
|
85
|
+
<datafield tag="500" ind1=" " ind2=" ">
|
86
|
+
<subfield code="a">"Fully 27 years after the debut of 'Blonde on blonde', Telarc gathered an assembly of contemporary blues artists to pay tribute to Dylan's masterpiece from his controversial electric period"--All Music Guide.</subfield>
|
87
|
+
</datafield>
|
88
|
+
<datafield tag="500" ind1=" " ind2=" ">
|
89
|
+
<subfield code="a">Compact disc.</subfield>
|
90
|
+
</datafield>
|
91
|
+
<datafield tag="500" ind1=" " ind2=" ">
|
92
|
+
<subfield code="a">Composer and program notes in container.</subfield>
|
93
|
+
</datafield>
|
94
|
+
<datafield tag="505" ind1="0" ind2="0">
|
95
|
+
<subfield code="t">Rainy day women # 12 & 35</subfield>
|
96
|
+
<subfield code="r">(Brian Stoltz) --</subfield>
|
97
|
+
<subfield code="t">Most likely you go your way and I'll go mine</subfield>
|
98
|
+
<subfield code="r">(Sue Foley) --</subfield>
|
99
|
+
<subfield code="t">Leopard-skin pill-box hat</subfield>
|
100
|
+
<subfield code="r">(Walter Trout) --</subfield>
|
101
|
+
<subfield code="t">Visions of Johanna</subfield>
|
102
|
+
<subfield code="r">(Anders Osborne) --</subfield>
|
103
|
+
<subfield code="t">Pledging my time</subfield>
|
104
|
+
<subfield code="r">(Duke Robillard) --</subfield>
|
105
|
+
<subfield code="t">Just like a woman</subfield>
|
106
|
+
<subfield code="r">(Eric Bibb) --</subfield>
|
107
|
+
<subfield code="t">Stuck inside of Mobile with the Memphis blues again</subfield>
|
108
|
+
<subfield code="r">(Joe Louis Walker) --</subfield>
|
109
|
+
<subfield code="t">Obviously 5 believers</subfield>
|
110
|
+
<subfield code="r">(Sean Costello) --</subfield>
|
111
|
+
<subfield code="t">One of us must know (sooner or later)</subfield>
|
112
|
+
<subfield code="r">(Clarence Bucaro) --</subfield>
|
113
|
+
<subfield code="t">Temporary like Achilles</subfield>
|
114
|
+
<subfield code="r">(Deborah Coleman) --</subfield>
|
115
|
+
<subfield code="t">I want you</subfield>
|
116
|
+
<subfield code="r">(Cyril Neville) --</subfield>
|
117
|
+
<subfield code="t">Absolutely sweet Marie</subfield>
|
118
|
+
<subfield code="r">(C.J. Chenier).</subfield>
|
119
|
+
</datafield>
|
120
|
+
<datafield tag="650" ind1=" " ind2="0">
|
121
|
+
<subfield code="a">Blues (Music)</subfield>
|
122
|
+
</datafield>
|
123
|
+
<datafield tag="906" ind1=" " ind2=" ">
|
124
|
+
<subfield code="a">7</subfield>
|
125
|
+
<subfield code="b">cbc</subfield>
|
126
|
+
<subfield code="c">copycat</subfield>
|
127
|
+
<subfield code="d">3</subfield>
|
128
|
+
<subfield code="e">ncip</subfield>
|
129
|
+
<subfield code="f">20</subfield>
|
130
|
+
<subfield code="g">y-genmusic</subfield>
|
131
|
+
</datafield>
|
132
|
+
<datafield tag="925" ind1="0" ind2=" ">
|
133
|
+
<subfield code="a">acquire</subfield>
|
134
|
+
<subfield code="b">2 copies</subfield>
|
135
|
+
<subfield code="x">policy default</subfield>
|
136
|
+
</datafield>
|
137
|
+
<datafield tag="952" ind1=" " ind2=" ">
|
138
|
+
<subfield code="a">muzerec</subfield>
|
139
|
+
</datafield>
|
140
|
+
<datafield tag="955" ind1=" " ind2=" ">
|
141
|
+
<subfield code="a">vn22 2003-10-28 to MBRS/RS</subfield>
|
142
|
+
<subfield code="e">vn17 2004-02-25 copy 2 to MBRS/RS</subfield>
|
143
|
+
</datafield>
|
144
|
+
<datafield tag="985" ind1=" " ind2=" ">
|
145
|
+
<subfield code="c">OCLC</subfield>
|
146
|
+
<subfield code="e">srreplace 2004-01</subfield>
|
147
|
+
</datafield>
|
148
|
+
</record>
|
data/test/tc_hash.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'marc'
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
class TestHash < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_to_hash
|
8
|
+
raw = IO.read('test/one.dat')
|
9
|
+
r = MARC::Record.new_from_marc(raw)
|
10
|
+
h = r.to_hash
|
11
|
+
assert_kind_of(Hash, h)
|
12
|
+
assert_equal(r.leader, h['leader'])
|
13
|
+
assert_equal(r.fields.length, h['fields'].length)
|
14
|
+
assert_equal(r.fields.first.tag, h['fields'].first.keys.first)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_roundtrip
|
18
|
+
reader = MARC::Reader.new('test/batch.dat')
|
19
|
+
reader.each do |r|
|
20
|
+
x = MARC::Record.new_from_hash(r.to_hash)
|
21
|
+
assert_equal(r,x)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
end
|
data/test/tc_record.rb
CHANGED
@@ -72,6 +72,43 @@ class TestRecord < Test::Unit::TestCase
|
|
72
72
|
r.append(MARC::DataField.new('245', '0', '4', ['The Pragmatic Programmer']))
|
73
73
|
return r
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
|
+
def test_field_index
|
77
|
+
raw = IO.read('test/random_tag_order.dat')
|
78
|
+
r = MARC::Record.new_from_marc(raw)
|
79
|
+
assert_kind_of(Array, r.fields)
|
80
|
+
assert_kind_of(Array, r.tags)
|
81
|
+
assert_equal(['001','005','007','008','010','028','035','040','050','245','260','300','500','505','511','650','700','906','953','991'], r.tags.sort)
|
82
|
+
assert_kind_of(Array, r.fields('035'))
|
83
|
+
raw2 = IO.read('test/random_tag_order2.dat')
|
84
|
+
r2 = MARC::Record.new_from_marc(raw2)
|
85
|
+
assert_equal(6, r2.fields('500').length)
|
86
|
+
# Test passing an array to Record#fields
|
87
|
+
assert_equal(3, r.fields(['500','505', '510', '511']).length)
|
88
|
+
# Test passing a Range to Record#fields
|
89
|
+
assert_equal(9, r.fields(('001'..'099')).length)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_field_index_order
|
93
|
+
raw = IO.read('test/random_tag_order.dat')
|
94
|
+
r = MARC::Record.new_from_marc(raw)
|
95
|
+
notes = ['500','505','511']
|
96
|
+
r.fields(('500'..'599')).each do |f|
|
97
|
+
assert_equal(notes.pop, f.tag)
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
raw2 = IO.read('test/random_tag_order2.dat')
|
102
|
+
r2 = MARC::Record.new_from_marc(raw2)
|
103
|
+
|
104
|
+
fields = ['050','042','010','028','024','035','041','028','040','035','008','007','005','001']
|
105
|
+
r2.each_by_tag(('001'..'099')) do |f|
|
106
|
+
assert_equal(fields.pop, f.tag)
|
107
|
+
end
|
108
|
+
|
109
|
+
five_hundreds = r2.fields('500')
|
110
|
+
assert_equal(five_hundreds.first['a'], '"Contemporary blues" interpretations of previously released songs; written by Bob Dylan.')
|
111
|
+
assert_equal(five_hundreds.last['a'], 'Composer and program notes in container.')
|
112
|
+
end
|
76
113
|
|
77
114
|
end
|
metadata
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Kevin Clarke
|
14
|
+
- Bill Dueber
|
8
15
|
- William Groppe
|
9
16
|
- Ross Singer
|
10
17
|
- Ed Summers
|
@@ -12,7 +19,7 @@ autorequire: marc
|
|
12
19
|
bindir: bin
|
13
20
|
cert_chain: []
|
14
21
|
|
15
|
-
date:
|
22
|
+
date: 2010-09-21 00:00:00 -04:00
|
16
23
|
default_executable:
|
17
24
|
dependencies: []
|
18
25
|
|
@@ -45,9 +52,14 @@ files:
|
|
45
52
|
- test/non-numeric.xml
|
46
53
|
- test/one.dat
|
47
54
|
- test/one.xml
|
55
|
+
- test/random_tag_order.dat
|
56
|
+
- test/random_tag_order.xml
|
57
|
+
- test/random_tag_order2.dat
|
58
|
+
- test/random_tag_order2.xml
|
48
59
|
- test/tc_controlfield.rb
|
49
60
|
- test/tc_datafield.rb
|
50
61
|
- test/tc_dublincore.rb
|
62
|
+
- test/tc_hash.rb
|
51
63
|
- test/tc_marchash.rb
|
52
64
|
- test/tc_parsers.rb
|
53
65
|
- test/tc_reader.rb
|
@@ -70,21 +82,29 @@ rdoc_options: []
|
|
70
82
|
require_paths:
|
71
83
|
- lib
|
72
84
|
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
73
86
|
requirements:
|
74
87
|
- - ">="
|
75
88
|
- !ruby/object:Gem::Version
|
89
|
+
hash: 59
|
90
|
+
segments:
|
91
|
+
- 1
|
92
|
+
- 8
|
93
|
+
- 6
|
76
94
|
version: 1.8.6
|
77
|
-
version:
|
78
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
79
97
|
requirements:
|
80
98
|
- - ">="
|
81
99
|
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
101
|
+
segments:
|
102
|
+
- 0
|
82
103
|
version: "0"
|
83
|
-
version:
|
84
104
|
requirements: []
|
85
105
|
|
86
106
|
rubyforge_project:
|
87
|
-
rubygems_version: 1.3.
|
107
|
+
rubygems_version: 1.3.7
|
88
108
|
signing_key:
|
89
109
|
specification_version: 3
|
90
110
|
summary: A ruby library for working with Machine Readable Cataloging
|