1MARC::Doc::Tutorial(3)User Contributed Perl DocumentationMARC::Doc::Tutorial(3)
2
3
4
6 MARC::Doc::Tutorial - A documentation-only module for new users of
7 MARC::Record
8
10 perldoc MARC::Doc::Tutorial
11
13 What is MARC?
14
15 The MAchine Readable Cataloging format was designed by the Library of
16 Congress in the late 1960s in order to allow libraries to convert their
17 card catalogs into a digital format. The advantages of having computer‐
18 ized card catalogs were soon realized, and now MARC is being used by
19 all sorts of libraries around the world to provide computerized access
20 to their collections. MARC data in transmission format is optimized
21 for processing by computers, so it's not very readable for the normal
22 human. For more about the MARC format, visit the Library of Congress at
23 http://www.loc.gov/marc/
24
25 What is this Tutorial?
26
27 The document you are reading is a beginners guide to using Perl to pro‐
28 cessing MARC data, written in the 'cookbook' style. Inside, you will
29 find recipes on how to read, write, update and convert MARC data using
30 the MARC::Record CPAN package. As with any cookbook, you should feel
31 free to dip in at any section and use the recipe you find interesting.
32 If you are new to Perl, you may want to read from the beginning.
33
34 The document you are reading is distributed with the MARC::Record pack‐
35 age, however in case you are reading it somewhere else, you can find
36 the latest version at CPAN: http://www.cpan.org/modules/by-mod‐
37 ule/MARC/. You'll notice that some sections aren't filled in yet, which
38 is a result of this document being a work in progress. If you have
39 ideas for new sections please make a suggestion to perl4lib:
40 http://www.rice.edu/perl4lib/.
41
42 History of MARC on CPAN
43
44 In 1999, a group of developers began working on MARC.pm to provide a
45 Perl module for working with MARC data. MARC.pm was quite successful
46 since it grew to include many new options that were requested by the
47 Perl/library community. However, in adding these features the module
48 swiftly outgrew its own clothes, and maintenance and addition of new
49 features became extremely difficult. In addition, as libraries began
50 using MARC.pm to process large MARC data files (>1000 records) they
51 noticed that memory consumption would skyrocket. Memory consumption
52 became an issue for large batches of records because MARC.pm's object
53 model was based on the 'batch' rather than the record... so each record
54 in the file would often be read into memory. There were ways of getting
55 around this, but they were not obvious. Some effort was made to recon‐
56 cile the two approaches (batch and record), but with limited success.
57
58 In mid 2001, Andy Lester released MARC::Record and MARC::Field which
59 provided a much simpler and maintainable package for processing MARC
60 data with Perl. As its name suggests, MARC::Record treats an individ‐
61 ual MARC record as the primary Perl object, rather than having the
62 object represent a given set of records. Instead of forking the two
63 projects, the developers agreed to encourage use of the MARC::Record
64 framework, and to work on enhancing MARC::Record rather than extending
65 MARC.pm further. Soon afterwards, MARC::Batch was added, which allows
66 you to read in a large data file without having to worry about memory
67 consumption.
68
69 In Dec., 2004, the MARC::Lint module, an extension to check the valid‐
70 ity of MARC records, was removed from the MARC::Record distribution, to
71 become a separately distributed package. This tutorial contains exam‐
72 ples for using MARC::Lint.
73
74 Brief Overview of MARC Classes
75
76 The MARC::Record package is made up of several separate packages. This
77 can be somewhat confusing to people new to Perl, or Object Oriented
78 Programming. However this framework allows easy extension, and is built
79 to support new input/output formats as their need arises. For a good
80 introduction to using the object oriented features of Perl, see the
81 perlboot documentation that came with your version of Perl.
82
83 Here are the packages that get installed with MARC::Record:
84
85 MARC::Batch
86 A convenience class for accessing MARC data contained in an exter‐
87 nal file.
88
89 MARC::Field
90 An object for representing the indicators and subfields of a single
91 MARC field.
92
93 MARC::Record
94 This primary class represents a MARC record, being a container for
95 multiple MARC::Field objects.
96
97 MARC::Doc::Tutorial
98 This document!
99
100 MARC::File
101 A superclass for representing files of MARC data.
102
103 MARC::File::MicroLIF
104 A subclass of MARC::File for working with data encoded in the
105 MicroLIF format.
106
107 MARC::File::USMARC
108 A subclass of MARC::File for working with data encoded in the
109 USMARC format.
110
111 Help Wanted!
112
113 It's already been mentioned but it's worth mentioning again:
114 MARC::Doc::Tutorial is a work in progress, and you are encouraged to
115 submit any suggestions for additional recipes via the perl4lib mailing
116 list at http://www.rice.edu/perl4lib. Also, the development group is
117 always looking for additional developers with good ideas; if you are
118 interested you can sign up at SourceForge: http://source‐
119 forge.net/projects/marcpm/.
120
122 Reading a record from a file
123
124 Let's say you have a USMARC record in 'file.dat' and you'd like to read
125 in the record and print out its title.
126
127 1 ## Example R1
128 2
129 3 ## create a MARC::Batch object.
130 4 use MARC::Batch;
131 5 my $batch = MARC::Batch('USMARC', 'file.dat');
132 6
133 7 ## get a MARC record from the MARC::Batch object.
134 8 ## the $record will be a MARC::Record object.
135 9 my $record = $batch->next();
136 10
137 11 ## print the title contained in the record.
138 12 print $record->title(),"\n";
139
140 Using the distribution's 't/camel.usmarc', your result should be:
141
142 ActivePerl with ASP and ADO / Tobias Martinsson.
143
144 Iterating through a batch file
145
146 Now imagine that 'file.dat' actually contains multiple records and we
147 want to print the title for each of them. Our program doesn't have to
148 change very much at all: we just need to add a loop around our call to
149 "next()".
150
151 1 ## Example R2
152 2
153 3 ## create a MARC::Batch object.
154 4 use MARC::Batch;
155 5 my $batch = MARC::Batch->new('USMARC','file.dat');
156 6
157 7 while (my $record = $batch->next()) {
158 8
159 9 ## print the title contained in the record.
160 10 print $record->title(),"\n";
161 11
162 12 }
163
164 The call to the "next()" method at line 7 returns the next record from
165 the file. "next()" returns "undef" when there are no more records left
166 in the file, which causes the "while" loop to end. This is a useful
167 idiom for reading in all the records in a file. Your results with
168 'camel.usmarc' should be:
169
170 ActivePerl with ASP and ADO / Tobias Martinsson.
171 Programming the Perl DBI / Alligator Descartes and Tim Bunce.
172 .
173 .
174 .
175 Cross-platform Perl / Eric F. Johnson.
176
177 Checking for errors
178
179 It is a good idea to get in the habit of checking for errors. MARC/Perl
180 has been designed to help you do this. Calls to "next()" when iterating
181 through a batch file will return "undef" when there are no more records
182 to return... AND when an error was encountered (see the next recipe to
183 subvert this). You probably want to make sure that you didn't abruptly
184 stop reading a batch file because of an error.
185
186 1 ## Example R3
187 2
188 3 ## create a MARC::Batch object.
189 4 use MARC::Batch;
190 5 my $batch = MARC::Batch->new('USMARC','file.dat');
191 6
192 7 ## get a marc record from the MARC::Batch object.
193 8 ## $record will be a MARC::Record object.
194 9 while ( my $record = $batch->next() ) {
195 10 print $record->title(),"\n";
196 11 }
197 12
198 13 ## make sure there weren't any problems.
199 14 if ( my @warnings = $batch->warnings() ) {
200 15 print "\nWarnings were detected!\n", @warnings;
201 16 }
202
203 The call to "warnings()" at line 14 will retrieve any warning messages
204 and store them in @warnings. This allows you to detect when "next()"
205 has aborted prematurely (before the end of the file has been reached).
206 When a warning is detected, an explanation is sent to "STDERR". By
207 introducing an error into 'camel.usmarc', we'll receive the following
208 output to "STDOUT":
209
210 Warnings were detected!
211 Invalid indicators "a0" forced to blanks in record 1 for tag 245
212
213 Recovering from errors
214
215 You may want to keep reading a batch file even after an error has been
216 encountered. If so, you will want to turn strict mode off using the
217 "strict_off()" method. You can also prevent warnings from being printed
218 to "STDERR" using the "warnings_off()" method. By default, strict is on
219 as a safety precaution to prevent you from using corrupt MARC data.
220 Once off, you can turn both strict and warnings back on again with the
221 "strict_on()" and "warnings_on()" methods.
222
223 1 ## Example R4
224 2
225 3 use MARC::Batch;
226 4 my $batch = MARC::Batch->new('USMARC', 'file.dat');
227 5 $batch->strict_off();
228 6
229 7 while ( my $record = $batch->next() ) {
230 8 print $record->title(),"\n";
231 9 }
232 10
233 11 ## make sure there weren't any problems.
234 12 if ( my @warnings = $batch->warnings() ) {
235 13 print "\nWarnings were detected!\n", @warnings;
236 14 }
237
238 Introducing a second error to the 'camel.usmarc' file gives the follow‐
239 ing:
240
241 ActivePerl with ASP and ADO / Tobias Martinsson.
242 Programming the Perl DBI / Alligator Descartes and Tim Bunce.
243 .
244 .
245 .
246 Cross-platform Perl / Eric F. Johnson.
247
248 Warnings were detected!
249 Invalid indicators "a0" forced to blanks in record 1 for tag 245
250 Invalid indicators "a0" forced to blanks in record 5 for tag 245
251
252 Looking at a field
253
254 Our previous examples use MARC::Record's "title()" method to easily
255 access the 245 field, but you will probably want programs that access
256 lots of other MARC fields. MARC::Record's "field()" method gives you
257 complete access to the data found in any MARC field. The "field()"
258 method returns a MARC::Field object which can be used to access the
259 data, indicators, and even the individual subfields. Our next example
260 shows how this is done.
261
262 1 ## Example R5
263 2
264 3 ## open a file.
265 4 use MARC::Batch;
266 5 my $batch = MARC::Batch->new('USMARC','file.dat');
267 6
268 7 ## read a record.
269 8 my $record = $batch->next();
270 9
271 10 ## get the 100 field as a MARC::Field object.
272 11 my $field = $record->field('100');
273 12 print "The 100 field contains: ",$field->as_string(),"\n";
274 13 print "The 1st indicator is ",$field->indicator(1),"\n";
275 14 print "The 2nd indicator is ",$field->indicator(2),"\n";
276 15 print "Subfield d contains: ",$field->subfield('d'),"\n";
277
278 Which results in something like:
279
280 The 100 field contains: Martinsson, Tobias, 1976-
281 The 1st indicator is 1
282 The 2nd indicator is
283 Subfield d contains: 1976-
284
285 As before, use a "while" loop to iterate through all the records in a
286 batch.
287
288 Looking at repeatable fields
289
290 So how do you retrieve data from repeatable fields? The "field()"
291 method can help you with this as well. In our previous example's line
292 11, the "field()" method was used in a scalar context, since the result
293 was being assigned to the variable $field. However in a list context,
294 "field()" will return all the fields in the record of that particular
295 type. For example:
296
297 1 ## Example R6
298 2
299 3 use MARC::Batch;
300 4 my $batch = MARC::Batch->new('USMARC','file.dat');
301 5 my $record = $batch->next();
302 6
303 7 ## get all the 650 fields (list context).
304 8 my @fields = $record->field('650');
305 9
306 10 ## examine each 650 field and print it out.
307 11 foreach my $field (@fields) {
308 12 print $field->as_string(),"\n";
309 13 }
310
311 Which prints out the following for the first record of
312 't/camel.usmarc':
313
314 Active server pages.
315 ActiveX.
316
317 Looking at a set of related fields
318
319 "field()" also allows you to retrieve similar fields using '.' as a
320 wildcard.
321
322 1 ## Example R7
323 2
324 3 use MARC::Batch;
325 4 my $batch = MARC::Batch->new('USMARC','file.dat');
326 5 my $record = $batch->next();
327 6
328 7 # retrieve all title fields in one shot.
329 8 foreach my $field ($record->field('2..')) {
330 9 print $field->tag(),' contains ',$field->as_string(),"\n";
331 10 }
332
333 Notice the shorthand in line 8 which compacts lines 7-13 of our previ‐
334 ous example. Instead of storing the fields in an array, the "field()"
335 still returns a list in the "for" loop. Line 9 uses the "tag()" method
336 which returns the tag number for a particular MARC field, which is use‐
337 ful when you aren't certain what tag you are currently dealing with.
338 Sample output from this recipe:
339
340 245 contains ActivePerl with ASP and ADO / Tobias Martinsson.
341 260 contains New York : John Wiley & Sons, 2000.
342
343 You can also return all tags for a specific record by using '...' in
344 "field" (though, see the next recipe).
345
346 Looking at all the fields in a record
347
348 The last example in this section illustrates how to retrieve all the
349 fields in a record using the "fields()" method. This method is similar
350 to passing '...' as a wildcard (see our previous recipe for alternative
351 access).
352
353 1 ## Example R8
354 2
355 3 use MARC::Batch;
356 4 my $file = MARC::Batch->new('USMARC','file.dat');
357 5 my $record = $batch->next();
358 6
359 7 ## get all of the fields using the fields() method.
360 8 my @fields = $record->fields();
361 9
362 10 ## print out the tag, the indicators and the field contents.
363 11 foreach my $field (@fields) {
364 12 print
365 13 $field->tag(), " ",
366 14 defined $field->indicator(1) ? $field->indicator(1) : "",
367 15 defined $field->indicator(2) ? $field->indicator(2) : "",
368 16 " ", $field->as_string, " \n";
369 17 }
370
371 The above code would print the following for the first record of
372 't/camel.usmarc':
373
374 001 fol05731351
375 003 IMchF
376 .
377 .
378 .
379 300 xxi, 289 p. : ill. ; 23 cm. + 1 computer laser disc (4 3/4 in.)
380 500 "Wiley Computer Publishing."
381 650 0 Perl (Computer program language)
382 630 00 Active server pages.
383 630 00 ActiveX.
384
386 The examples in the Section 1 covered how to read in existing USMARC
387 data in a file. Section 2 will show you how to create a MARC record
388 from scratch. The techniques in this section would allow you to write
389 programs which create MARC records that could then be loaded into an
390 online catalog, or sent to a third party.
391
392 Creating a record
393
394 To create a new MARC record, you'll need to first create a MARC::Record
395 object, add a leader (though MARC::Record can create leaders automati‐
396 cally if you don't specifically define one), and then create and add
397 MARC::Field objects to your MARC::Record object. For example:
398
399 1 ## Example C1
400 2
401 3 ## create a MARC::Record object.
402 4 use MARC::Record;
403 5 my $record = MARC::Record->new();
404 6
405 7 ## add the leader to the record. optional.
406 8 $record->leader('00903pam 2200265 a 4500');
407 9
408 10 ## create an author field.
409 11 my $author = MARC::Field->new(
410 12 '100',1,'',
411 13 a => 'Logan, Robert K.',
412 14 d => '1939-'
413 15 );
414 16 $record->append_fields($author);
415 17
416 18 ## create a title field.
417 19 my $title = MARC::Field->new(
418 20 '245','1','4',
419 21 a => 'The alphabet effect /',
420 22 c => 'Robert K. Logan.'
421 23 );
422 24 $record->append_fields($title);
423
424 The key to creating records from scratch is to use "append_fields()",
425 which adds a field to the end of the record. Since each field gets
426 added at the end, it's up to you to order the fields the way you want.
427 "insert_fields_before()" and "insert_fields_after()" are similar meth‐
428 ods that allow you to define where the field gets added. These methods
429 are covered in more detail below.
430
432 Sections 1 and 2 showed how to read and create USMARC data. Once you
433 know how to read and create, it becomes important to know how to write
434 the USMARC data to disk in order to save your work. In these examples,
435 we will create a new record and save it to a file called 'record.dat'.
436
437 Writing records to a file
438
439 1 ## Example W1
440 2
441 3 ## create a MARC::Record object.
442 4 use MARC::Record;
443 5 my $record = MARC::Record->new();
444 6
445 7 ## add the leader to the record. optional.
446 8 $record->leader('00903pam 2200265 a 4500');
447 9
448 10 ## create an author field.
449 11 my $author = MARC::Field->new(
450 12 '100',1,'',
451 13 a => 'Logan, Robert K.',
452 14 d => '1939-'
453 15 );
454 16
455 17 ## create a title field.
456 18 my $title = MARC::Field->new(
457 19 '245','1','4',
458 20 a => 'The alphabet effect /',
459 21 c => 'Robert K. Logan.'
460 22 );
461 23
462 24 $record->append_fields($author, $title);
463 25
464 26 ## open a filehandle to write to 'record.dat'.
465 27 open(OUTPUT, '> record.dat') or die $!;
466 28 print OUTPUT $record->as_usmarc();
467 29 close(OUTPUT);
468
469 The "as_usmarc()" method call at line 28 returns a scalar value which
470 is the raw USMARC data for $record. The raw data is then promptly
471 printed to the "OUTPUT" file handle. If you want to output multiple
472 records to a file, simply repeat the process at line 28 for the addi‐
473 tional records. Also of note is the "append_fields" method: unlike
474 recipe C1 which called the method once for each field added, this
475 recipe demonstrates that "append_fields" can accept multiple arguments.
476
477 Note to the curious: the "as_usmarc()" method is actually an alias to
478 the MARC::File::USMARC "encode()" method. Having separate "encode()"
479 methods is a design feature of the MARC class hierarchy, since it
480 allows extensions to be built that translate MARC::Record objects into
481 different data formats.
482
483 Debugging with "as_formatted()"
484
485 Since raw USMARC data isn't very easy for humans to read, it is often
486 useful to be able to see the contents of your MARC::Record object rep‐
487 resented in a 'pretty' way for debugging purposes. If you have a
488 MARC::Record object you'd like to pretty-print, use the "as_format‐
489 ted()" method.
490
491 1 ## Example W2
492 2
493 3 ## create a MARC::Record object.
494 4 use MARC::Record;
495 5 my $record = MARC::Record->new();
496 6
497 7 $record->leader('00903pam 2200265 a 4500');
498 8
499 9 $record->append_fields(
500 10 MARC::Field->new('100','1','', a=>'Logan, Robert K.', d=>'1939-'),
501 11 MARC::Field->new('245','1','4', a=>'The alphabet effect /', c=>'Robert K. Logan.')
502 12 );
503 13
504 14 ## pretty print the record.
505 15 print $record->as_formatted(), "\n";
506
507 This code will pretty print the contents of the newly created record:
508
509 LDR 00903pam 2200265 a 4500
510 100 1 _aLogan, Robert K.
511 _d1939-
512 245 14 _aThe alphabet effect /
513 _cRobert K. Logan.
514
515 Notice on lines 9-12 how you can add a list of new fields by creating
516 MARC::Field objects within a call to "append_fields()". This is yet
517 another shorthand method to those shown in recipes C1 and W1. For more
518 pretty-printing capabilities, try "marcdump()" in our next recipe.
519
520 Debugging with marcdump()
521
522 If you have written USMARC data to a file (as in recipe W2) and you
523 would like to verify that the data is stored correctly you can use the
524 "marcdump" command line utility that was installed with the
525 MARC::Record package:
526
527 % marcdump record.dat
528 record.dat
529 LDR 00122pam 2200049 a 4500
530 100 1 _aLogan, Robert K.
531 _d1939-
532 245 14 _aThe alphabet effect /
533 _cRobert K. Logan.
534
535 Recs Errs Filename
536 ----- ----- --------
537 1 0 record.dat
538
539 As you can see, this command results in the record being pretty printed
540 to your screen ("STDOUT") similarly to the "as_formatted" method from
541 recipe W2. It is useful for verifying your USMARC data after it has
542 been stored on disk. More details about debugging are found later in
543 VALIDATING.
544
546 Now that you know how to read, write and create MARC data, you have the
547 tools you need to update or edit exiting MARC data. Updating MARC data
548 is a common task for library catalogers. Sometimes there are huge
549 amounts of records that need to be touched up... and while the touch
550 ups are very detail oriented, they are also highly repetitive. Luckily,
551 computers are tireless, and not very prone to error (assuming the pro‐
552 grammer isn't).
553
554 When libraries receive large batches of MARC records for electronic
555 text collections such as NetLibrary, Making of America, or microfiche
556 sets like Early American Imprints, the records are often loaded into an
557 online system and then the system is used to update the records. Unfor‐
558 tunately, not all these systems are created equal, and catalogers have
559 to spend a great deal of time touching up each individual record. An
560 alternative would be to process the records prior to import and then,
561 once in the system, the records would not need editing. This scenario
562 would save a great deal of time for the cataloger who would be liber‐
563 ated to spend their time doing original cataloging... which computers
564 are notably bad at!
565
566 Adding a field
567
568 Imagine a batch of records in 'file.dat' that you'd like to add local
569 notes (590) to, then saving your changes:
570
571 1 ## Example U1
572 2
573 3 ## create our MARC::Batch object.
574 4 use MARC::Batch;
575 5 my $batch = MARC::Batch->new('USMARC','file.dat');
576 6
577 7 ## open a file handle to write to.
578 8 open(OUT,'>new.dat') or die $!;
579 9
580 10 ## read each record, modify, then print.
581 11 while ( my $record = $batch->next() ) {
582 12
583 13 ## add a 590 field.
584 14 $record->append_fields(
585 15 MARC::Field->new('590','','',a=>'Access provided by Enron.')
586 16 );
587 17
588 18 print OUT $record->as_usmarc();
589 19
590 20 }
591 21
592 22 close(OUT);
593
594 Preserving field order
595
596 As its name suggests, "append_fields()" will add the 590 field in
597 recipe U1 to the end of the record. If you want to preserve a particu‐
598 lar order, you can use the "insert_fields_before()" and
599 "insert_fields_after()" methods. In order to use these, you need to
600 locate the field you want to insert before or after. Here is an exam‐
601 ple ("insert_fields_after()" works similarly):
602
603 1 ## Example U2
604 2
605 3 use MARC::Batch;
606 4 my $batch = MARC::Batch->new('USMARC','file.dat');
607 5 open(OUT,'>new.dat') or die $!;
608 6
609 7 ## read in each record.
610 8 while ( my $record = $batch->next() ) {
611 9
612 10 ## find the tag after 590.
613 11 my $before;
614 12 foreach ($record->fields()) {
615 13 $before = $_;
616 14 last if $_->tag() > 590;
617 15 }
618 16
619 17 ## create the 590 field.
620 18 my $new = MARC::Field->new('590','','',a=>'Access provided by Enron.');
621 19
622 20 ## insert our 590 field after the $before.
623 21 $record->insert_fields_before($before,$new);
624 22
625 23 ## and print out the new record.
626 24 print OUT $record->as_usmarc();
627 25
628 26 }
629
630 Deleting a field
631
632 You can also delete fields that you don't want. But you will probably
633 want to check that the field contains what you expect before deleting
634 it. Let's say Enron has gone out of business and the 590 field needs to
635 be deleted:
636
637 1 ## Example U3
638 2
639 3 use MARC::Batch;
640 4 my $batch = MARC::Batch->new('USMARC','new.dat');
641 5 open(OUT,'>newer.dat') or die $1;
642 6
643 7 while ( my $record = $batch->next() ) {
644 8
645 9 ## get the 590 record.
646 10 my $field = $record->field('590');
647 11
648 12 ## if there is a 590 AND it has the word "Enron"...
649 13 if ($field and $field->as_string() =~ /Enron/i) {
650 14
651 15 ## delete it!
652 16 $record->delete_field($field);
653 17
654 18 }
655 19
656 20 ## output possibly modified record.
657 21 print OUT $record->as_usmarc();
658 22
659 23 }
660
661 The 590 field is retrieved on line 10, but notice how we check that we
662 actually received a valid $field, and that it then contains the word
663 'Enron' before we delete it. You need to pass "delete_field()" a
664 MARC::Field object that can be retrieved with the "field()" method.
665
666 Changing existing fields
667
668 Perhaps rather than adding or deleting a field, you need to modify an
669 existing field. This is achieved in several steps: first, read in the
670 MARC record you want to update, and then the field you're interested
671 in. From there, call the field's "update" or "replace_with" methods to
672 modify its contents, and then resave the record. Below is an example of
673 updating existing 590 field's containing the word 'Enron' to indicate
674 that access is now provided through Arthur Andersen:
675
676 1 ## Example U4
677 2
678 3 use MARC::Batch;
679 4 my $batch = MARC::Batch->new('USMARC','new.dat');
680 5 open(OUT,'>newer.dat') or die $1;
681 6
682 7 while ( my $record = $batch->next() ) {
683 8
684 9 ## look for a 590 containing "Enron"...
685 10 my $field = $record->field('590');
686 11 if ($field and $field->as_string =~ /Enron/i) {
687 12
688 13 ## create a new 590 field.
689 14 my $new_field = MARC::Field->new(
690 15 '590','','', a => 'Access provided by Arthur Andersen.' );
691 16
692 17 ## replace existing with our new one.
693 18 $field->replace_with($new_field);
694 19
695 20 }
696 21
697 22 ## output possibly modified record.
698 23 print OUT $record->as_usmarc();
699 24
700 25 }
701
702 In this example, we used MARC::Field's method "replace_with()" to
703 replace an existing field in the record with a new field that we cre‐
704 ated. To use "replace_with()", you need to retrieve the field you want
705 to replace from a MARC::Record object (line 10), create a new field to
706 replace the existing one with (lines 13-15), and then call the existing
707 field's "replace_with()" method passing the new field as an argument
708 (lines 18). You must pass "replace_with()" a valid MARC::Field object.
709
710 Updating subfields and indicators
711
712 If you'd rather not replace an existing field with a new one, you can
713 also edit the contents of the field itself using the "update()" method.
714 Let's say you've got a batch of records and want to make sure that the
715 2nd indicator for the 245 field is properly set for titles that begin
716 with 'The' (where the indicator should be '4').
717
718 1 ## Example U5
719 2
720 3 use MARC::Batch;
721 4 my $batch = MARC::Batch->new('USMARC','file.dat');
722 5 open(OUT,'>new.dat') or die $!;
723 6
724 7 while (my $record = $batch->next()) {
725 8
726 9 ## retrieve the 245 record.
727 10 my $field_245 = $record->field('245');
728 11
729 12 ## if we got 245 and it starts with 'The'...
730 13 if ($field_245 and $field_245->as_string() =~ /^The /) {
731 14
732 15 ## if the 2nd indicator isn't 4, update
733 16 if ($field_245->indicator(2) != 4) {
734 17 $field_245->update( ind2 => 4 );
735 18 }
736 19
737 20 }
738 21
739 22 print OUT $record->as_usmarc();
740 23
741 24 }
742
743 In a similar fashion, you can update individual or multiple subfields:
744
745 $field_245->update( a => 'History of the World :', b => 'part 1' );
746
747 But beware, you can only update the first occurrence of a subfield
748 using "update()". If you need to do more finer grained updates, you are
749 advised to build a new field and replace the existing field with
750 "replace_with()".
751
752 Changing a record's leader
753
754 The above procedure works for fields, but editing the leader requires
755 that you use the "leader()" method. When called with no arguments,
756 "leader()" will return the current leader, and when you pass a scalar
757 value as an argument, the leader will be set to this value. This exam‐
758 ple shows how you might want to update position 6 of a records leader
759 to reflect a computer file.
760
761 1 ## Example U6
762 2
763 3 use MARC::Batch;
764 4 my $batch = MARC::Batch->new('USMARC','file.dat');
765 5 open(OUT,'>new.dat') or die $!;
766 6 my $record = $batch->next();
767 7
768 8 ## get the current leader.
769 9 my $leader = $record->leader();
770 10
771 11 ## replace position 6 with 'm'
772 12 substr($leader,6,1) = 'm';
773 13
774 14 ## update the leader
775 15 $record->leader($leader);
776 16
777 17 ## save the record to a file
778 18 print OUT $record->as_usmarc();
779
780 Modifying fields without indicators
781
782 MARC::Record and MARC::Field are smart and know that you don't have
783 field indicators with tags less than 010. Here's an example of updat‐
784 ing/adding an 005 field to indicate a new transaction time. For a lit‐
785 tle pizzazz, we use Perl's "localtime()" to generate the data we need
786 for this field.
787
788 1 ## Example U7
789 2
790 3 use MARC::Batch;
791 4 my $batch = MARC::Batch->new('USMARC','file.dat');
792 5 open(OUT,'>new.dat') or die $!;
793 6
794 7 while (my $record = $batch->next() ) {
795 8
796 9 ## see if there is a 005 field.
797 10 my $field_005 = $record->field('005');
798 11
799 12 ## delete it if we find one.
800 13 $record->delete_field($field_005) if $field_005;
801 14
802 15 ## figure out the contents of our new 005 field.
803 16 my ($sec,$min,$hour,$mday,$mon,$year) = localtime();
804 17 $year += 1900; $mon += 1; # catering to offsets.
805 18 my $datetime = sprintf("%4d%02d%02d%02d%02d%02d.0",
806 19 $year,$mon,$mday,$hour,$min,$sec);
807 20
808 21 ## create a new 005 field using our new datetime.
809 22 $record->append_fields( MARC::Field->new('005',$datetime) );
810 23
811 24 ## save record to a file.
812 25 print OUT $record->as_usmarc();
813 26
814 27 }
815
816 Reordering subfields
817
818 You may find yourself in the situation where you would like to program‐
819 matically reorder, and possibly modify, subfields in a particular
820 field. For example, imagine that you have a batch of records that have
821 856 fields which contain subfields z, u, and possibly 3... in any
822 order! Now imagine that you'd like to standardize the subfield z, and
823 reorder them so that subfield 3 precedes subfield z, which precedes
824 subfield u. This is tricky but can be done in the following manner:
825 read in a record, extract the existing 856 field, build a new 856 field
826 based on the existing one, replace the existing field with your newly
827 created version.
828
829 1 ## Example U8
830 2
831 3 use MARC::Batch;
832 4 my $batch = MARC::Batch->new('USMARC','856.dat');
833 5 open(OUT,'>856_new.dat') or die $!;
834 6
835 7 while (my $record = $batch->next()) {
836 8
837 9 my $existing = $record->field('856');
838 10
839 11 ## make sure 856 exists.
840 12 if ($existing) {
841 13
842 14 ## our ordered subfields.
843 15 my @subfields = ();
844 16
845 17 ## if we have a subfield 3, add it.
846 18 if (defined($existing->subfield('3'))) {
847 19 push(@subfields,'3',$existing->subfield('3'));
848 20 }
849 21
850 22 ## now add subfields z and u.
851 23 push(@subfields,'z','Access restricted',
852 24 'u',$existing->subfield('u'));
853 25
854 26 ## create a new 856.
855 27 my $new = MARC::Field->new(
856 28 856', $existing->indicator(1),
857 29 $existing->indicator(2), @subfields
858 30 );
859 31
860 32 ## replace the existing subfield.
861 33 $existing->replace_with($new);
862 34
863 35 }
864 36
865 37 ## write out the record
866 38 print OUT $record->as_usmarc();
867 39
868 40 }
869
870 Updating subject subfield x to subfield v
871
872 As a somewhat more complicated example, you may find yourself wanting
873 to update the last subfield x in a 650 field to be a subfield v
874 instead. With the MARC::Field "subfields()" and "replace_with()" meth‐
875 ods along with some fancy footwork this can be done relatively easily.
876
877 1 ## Example U9
878 2
879 3 use MARC::Batch;
880 4
881 5 my $file = shift;
882 6
883 7 my $batch = MARC::Batch->new('USMARC', $file);
884 8 while ( my $record = $batch->next() ) {
885 9
886 10 # go through all 6XX fields in the record.
887 11 foreach my $subject ( $record->field( '6..' ) ) {
888 12
889 13 # extract subfields as an array of array refs.
890 14 my @subfields = $subject->subfields();
891 15
892 16 # setup an array to store our new field.
893 17 my @newSubfields = ();
894 18
895 19 # a flag to indicate that we found an subfield x.
896 20 my $foundX = 0;
897 21
898 22 # use pop() to read the subfields backwards.
899 23 while ( my $subfield = pop( @subfields ) ) {
900 24
901 25 # for convenience, pull out the subfield
902 26 # code and data from the array ref.
903 27 my ($code,$data) = @$subfield;
904 28
905 29 # if the subfield code is 'x' and
906 30 # we haven't already found one...
907 31 if ( $code eq 'x' and ! $foundX ) {
908 32
909 33 # change to a v.
910 34 $code = 'v';
911 35
912 36 # set flag so we know not to
913 37 # translate any more subfield x.
914 38 $foundX = 1;
915 39
916 40 }
917 41
918 42 # add our (potentially changed) subfield
919 43 # data to our new subfield data array.
920 44 unshift( @newSubfields, $code, $data );
921 45
922 46 }
923 47
924 48 # if we did find a subfield x, then create a new field using our
925 49 # new subfield data, and replace the old one with the new one.
926 50 if ( $foundX ) {
927 51 my $newSubject = MARC::Field->new(
928 52 $subject->tag(),
929 53 $subject->indicator(1),
930 54 $subject->indicator(2),
931 55 @newSubfields
932 56 );
933 57 $subject->replace_with( $newSubject );
934 58 }
935 59
936 60 }
937 61
938 62 # output the potentially changed record as MARC.
939 63 print $record->as_usmarc();
940 64
941 65 }
942
944 MARC::Lint, available on CPAN and in cvs on SourceForge, has some extra
945 goodies to allow you to validate records. MARC::Lint provides an exten‐
946 sive battery of tests, and it also provides a framework for adding
947 more.
948
949 Using MARC::Lint
950
951 Here is an example of using MARC::Lint to generate a list of errors
952 present in a batch of records in a file named 'file.dat':
953
954 1 ## Example V1
955 2
956 3 use MARC::Batch;
957 4 use MARC::Lint;
958 5
959 6 my $batch = MARC::Batch->new('USMARC','file.dat');
960 7 my $linter = MARC::Lint->new();
961 8 my $counter = 0;
962 9
963 10 while (my $record = $batch->next() ) {
964 11
965 12 $counter++;
966 13
967 14 ## feed the record to our linter object.
968 15 $linter->check_record($record);
969 16
970 17 ## get the warnings...
971 18 my @warnings = $linter->warnings();
972 19
973 20 ## output any warnings.
974 21 if (@warnings) {
975 22
976 23 print "RECORD $counter\n";
977 24 print join("\n",@warnings),"\n";
978 25
979 26 }
980 27
981 28 }
982
983 MARC::Lint is quite thorough, and will check the following when vali‐
984 dating: presence of a 245 field, repeatability of fields and subfields,
985 valid use of subfield within particular fields, presence of indicators
986 and their values. All checks are based on MARC21 bibliographic format.
987
988 Customizing MARC::Lint
989
990 MARC::Lint makes no claim to check everything that might be wrong with
991 a MARC record. In practice, individual libraries may have their own
992 idea about what is valid or invalid. For example, a library may mandate
993 that all MARC records with an 856 field should have a subfield z that
994 reads "Connect to this resource".
995
996 MARC::Lint does provide a framework for adding rules. It can be done
997 using the object oriented programming technique of inheritance. In
998 short, you can create your own subclass of MARC::Lint, and then use it
999 to validate your records. Here's an example:
1000
1001 1 ## Example V2
1002 2
1003 3 ## first, create our own subclass of MARC::Lint.
1004 4 ## should be saved in a file called MyLint.pm.
1005 5
1006 6 package MyLint;
1007 7 use base qw(MARC::Lint);
1008 8
1009 9 ## add a method to check that the 856
1010 10 ## fields contain a correct subfield z.
1011 11 sub check_856 {
1012 12
1013 13 ## your method is passed the MARC::Lint
1014 14 ## and MARC::Field objects for the record.
1015 15 my ($self,$field) = @_;
1016 16
1017 17 if ($field->subfield('z') ne 'Connect to this resource') {
1018 18
1019 19 ## add a warning to our lint object.
1020 20 $self->warn("856 subfield z must read 'Connect to this resource'.");
1021 21
1022 22 }
1023 23
1024 24 }
1025
1026 Then create a separate program that uses your subclass to validate your
1027 MARC records. You'll need to make sure your program is able to find
1028 your module (in this case, MyLint.pm)... this can be achieved by
1029 putting both MyLint.pm and the following program in the same directory:
1030
1031 1 ## Example V3
1032 2
1033 3 use MARC::Batch;
1034 4 use MyLint;
1035 5
1036 6 my $linter = MyLint->new();
1037 7 my $batch = MARC::Batch->new('USMARC','file.marc');
1038 8 my $counter = 0;
1039 9
1040 10 while (my $record = $batch->next()) {
1041 11
1042 12 $counter++;
1043 13
1044 14 ## check the record
1045 15 $linter->check_record($record);
1046 16
1047 17 ## get the warnings, and print them out
1048 18 my @warnings = $linter->warnings();
1049 19 if (@warnings) {
1050 20 print "RECORD $counter\n";
1051 21 print join("\n",@warnings),"\n";
1052 22 }
1053 23
1054 24 }
1055
1056 Notice how the call to "check_record()" at line 15 automatically calls
1057 the "check_record" in MARC::Lint. The property of inheritance is what
1058 makes this happen. $linter is an instance of the MyLint class, and
1059 MyLint inherits from the MARC::Lint class, which allows $linter to
1060 inherit all the functionality of a normal MARC::Lint object plus the
1061 new functionality found in the "check_856" method.
1062
1063 Notice also that we don't have to call "check_856()" directly. The call
1064 to "check_record()" automatically looks for any "check_XXX" methods
1065 that it can call to verify the record. Pretty neat stuff. If you've
1066 added validation checks that you think could be of use to the general
1067 public, please share them on the perl4lib mailing list, or become a
1068 developer and add them to the source!
1069
1071 Brian Eno fans might catch this reference to his autobiography which
1072 was comprised of a years worth of diary entries plus extra topics at
1073 the end, and was entitled "A Year With Swollen Appendices". The follow‐
1074 ing section is a grab bag group of appendices. Many of them are not
1075 filled in yet; this is because they are just ideas... so perhaps the
1076 appendices aren't that swollen yet. Feel free to suggest new ones, or
1077 to fill these in.
1078
1079 Comparing Collections
1080
1081 Authority Records
1082
1083 URLs
1084
1085 ISBN/ISSNs
1086
1087 Call numbers
1088
1089 Subject headings
1090
1091 Suppose you have a batch of MARC records and you want to extract all
1092 the subject headings, generating a report of how many times each sub‐
1093 ject heading appeared in the batch:
1094
1095 1 use MARC::File::USMARC;
1096 2 use constant MAX => 20;
1097 3
1098 4 my %counts;
1099 5
1100 6 my $filename = shift or die "Must specify filename\n";
1101 7 my $file = MARC::File::USMARC->in( $filename );
1102 8
1103 9 while ( my $marc = $file->next() ) {
1104 10 for my $field ( $marc->field("6..") ) {
1105 11 my $heading = $field->subfield('a');
1106 12
1107 13 # trailing whitespace / punctuation.
1108 14 $heading =~ s/[.,]?\s*$//;
1109 15
1110 16 # Now count it.
1111 17 ++$counts{$heading};
1112 18 }
1113 19 }
1114 20 $file->close();
1115 21
1116 22 # Sort the list of headings based on the count of each.
1117 23 my @headings = reverse sort { $counts{$a} <=> $counts{$b} } keys %counts;
1118 24
1119 25 # Take the top N hits...
1120 26 @headings = @headings[0..MAX-1];
1121 27
1122 28 # And print out the results.
1123 29 for my $heading ( @headings ) {
1124 30 printf( "%5d %s\n", $counts{$heading}, $heading );
1125 31 }
1126
1127 Which will generate results like this:
1128
1129 600 United States
1130 140 World War, 1939-1945
1131 78 Great Britain
1132 63 Afro-Americans
1133 61 Indians of North America
1134 58 American poetry
1135 55 France
1136 53 West (U.S.)
1137 53 Science fiction
1138 53 American literature
1139 50 Shakespeare, William
1140 48 Soviet Union
1141 46 Mystery and detective stories
1142 45 Presidents
1143 43 China
1144 40 Frontier and pioneer life
1145 38 English poetry
1146 37 Authors, American
1147 37 English language
1148 35 Japan
1149
1150 HTML
1151
1152 XML
1153
1154 MARCMaker
1155
1156 MARC::File::MARCMaker, available on CPAN and in cvs on SourceForge, is
1157 a subclass of MARC::File for working with MARC 21 data encoded in the
1158 format used by the Library of Congress MARCMaker and MARCBreaker pro‐
1159 grams (<http://www.loc.gov/marc/makrbrkr.html>) and MarcEdit ().
1160
1161 An example of a brief record in this format:
1162
1163 =LDR 00314nam 22001215a 4500
1164 =001 ctr00000123\
1165 =003 XX-XxUND
1166 =005 20000613133448.0
1167 =008 051029s2005\\\\xxua\\\\\\\\\\001\0\eng\\
1168 =040 \\$aXX-XxUND$cXX-XxUND
1169 =245 00$aSample of MARCMaker record.
1170 =260 \\$a[United States] :$b[S.n.],$c2005.
1171 =300 \\$a1 p. ;$c28 cm.
1172
1173 The following example converts an ISO2709 format record into MARCMaker
1174 format.
1175
1176 1 ## Example Maker1
1177 2
1178 3 use MARC::Batch;
1179 4 use MARC::File::MARCMaker;
1180 5
1181 6 #mrc indicates ISO2709 format
1182 7 my $mrc_in = 'in.mrc';
1183 8 #mrk indicates MARCMaker format
1184 9 my $mrk_out = 'out.mrk';
1185 10
1186 11 #initialize $batch_mrc as new MARC::Batch object
1187 12 my $batch_mrc = MARC::Batch->new('USMARC', $mrc_in);
1188 13
1189 14 #open mrk (MARCMaker) format output file
1190 15 open (OUTMRK, ">$mrk_out") ⎪⎪ die "Cannot open $mrk_out, $!";
1191 16
1192 17 my $rec_count = 0;
1193 18 while (my $record = $batch_mrc->next()) {
1194 19 $rec_count++;
1195 20
1196 21 print OUTMRK MARC::File::MARCMaker->encode($record);
1197 22
1198 23 } # while
1199 24
1200 25 print "$rec_count records processed\n";
1201
1202 The following example shows conversion from MARCMaker format to ISO2709
1203 format.
1204
1205 1 ## Example Maker2
1206 2
1207 3 use MARC::Batch;
1208 4 use MARC::File::MARCMaker;
1209 5
1210 6 #mrk indicates MARCMaker format
1211 7 my $mrk_in = 'in.mrk';
1212 8 #mrc indicates ISO2709 format
1213 9 my $mrc_out = 'out.mrc';
1214 10
1215 11 #initialize $batch_mrk as new MARC::Batch object
1216 12 my $batch_mrk = MARC::Batch->new( 'MARCMaker', $mrk_in);
1217 13
1218 14 #open mrc (ISO2709) format output file
1219 15 open (OUTMRC, ">$mrc_out") ⎪⎪ die "Cannot open $mrc_out, $!";
1220 16
1221 17 my $rec_count = 0;
1222 18 while (my $record = $batch_mrk->next()) {
1223 19 $rec_count++;
1224 20
1225 21 print OUTMRC $record->as_usmarc();
1226 22
1227 23 } # while
1228 24
1229 25 print "$rec_count records processed\n";
1230
1231 Excel
1232
1233 Z39.50
1234
1235 Chris Biemesderfer was kind enough to contribute a short example of how
1236 to use MARC::Record in tandem with Net::Z3950. Net::Z3950 is a CPAN
1237 module which provides an easy to use interface to the Z39.50 protocol
1238 so that you can write programs that retrieve records from bibliographic
1239 database around the world.
1240
1241 Chris' program is a command line utility which you run like so:
1242
1243 ./zm.pl 0596000278
1244
1245 where 0596000278 is an ISBN (for the 3rd edition of the Camel inciden‐
1246 tally). The program will query the Library of Congress Z39.50 server
1247 for the ISBN, and dump out the retrieved MARC record on the screen. The
1248 program is designed to lookup multiple ISBNs if you separate them with
1249 a space. This is just an example showing what is possible.
1250
1251 1 #!/usr/bin/perl -w
1252 2
1253 3 # GET-MARC-ISBN -- Get MARC records by ISBN from a Z39.50 server
1254 4
1255 5 use strict;
1256 6 use Carp;
1257 7 use Net::Z3950;
1258 8 use MARC::Record;
1259 9
1260 10 exit if ($#ARGV < 0);
1261 11
1262 12 # We handle multiple ISBNs in the same query by assembling a
1263 13 # (potentially very large) search string with Prefix Query Notation
1264 14 # that ORs the ISBN-bearing attributes.
1265 15 #
1266 16 # For purposes of automation, we want to request batches of many MARC
1267 17 # records. I am not a Z39.50 weenie, though, and I don't know
1268 18 # offhand if there is a limit on how big a PQN query can be...
1269 19
1270 20 my $zq = "\@attr 1=7 ". pop();
1271 21 while (@ARGV) { $zq = '@or @attr 1=7 '. pop() ." $zq" }
1272 22
1273 23 ## HERE IS THE CODE FOR Z3950 REC RETRIEVAL
1274 24 # Set up connection management structures, connect
1275 25 # to the server, and submit the Z39.50 query.
1276 26
1277 27 my $mgr = Net::Z3950::Manager->new( databaseName => 'voyager' );
1278 28 $mgr->option( elementSetName => "f" );
1279 29 $mgr->option( preferredRecordSyntax => Net::Z3950::RecordSyntax::USMARC );
1280 30
1281 31 my $conn = $mgr->connect('z3950.loc.gov', '7090');
1282 32 croak "Unable to connect to server" if !defined($conn);
1283 33
1284 34 my $rs = $conn->search($zq);
1285 35
1286 36 my $numrec = $rs->size();
1287 37 print STDERR "$numrec record(s) found\n";
1288 38
1289 39 for (my $ii = 1; $ii <= $numrec; $ii++) {
1290 40
1291 41 # Extract MARC records from Z3950
1292 42 # result set, and load MARC::Record.
1293 43 my $zrec = $rs->record($ii);
1294 44 my $mrec = MARC::Record->new_from_usmarc($zrec->rawdata());
1295 45 print $mrec->as_formatted, "\n\n";
1296 46
1297 47 }
1298
1299 Databases
1300
1301 Here's a script that will do a Z39.50 query (using Chris Biemesderfer's
1302 zm.pl as a model), get a MARC record back, and store it as a binary
1303 blob in a MySQL table of this structure:
1304
1305 +---------------+---------------+------+-----+---------+----------------+
1306 ⎪ Field ⎪ Type ⎪ Null ⎪ Key ⎪ Default ⎪ Extra ⎪
1307 +---------------+---------------+------+-----+---------+----------------+
1308 ⎪ TitleID ⎪ int(7) ⎪ ⎪ PRI ⎪ NULL ⎪ auto_increment ⎪
1309 ⎪ RecLastMod ⎪ timestamp(14) ⎪ YES ⎪ ⎪ NULL ⎪ ⎪
1310 ⎪ ISSN ⎪ text ⎪ YES ⎪ ⎪ NULL ⎪ ⎪
1311 ⎪ RawMARCRecord ⎪ blob ⎪ YES ⎪ ⎪ NULL ⎪ ⎪
1312 +---------------+---------------+------+-----+---------+----------------+
1313
1314 1 #!/usr/bin/perl -w
1315 2
1316 3 # Script that reads in a file of ISSNs, queries a Z39.50 server,
1317 4 # and stores resulting records in a database. Limitations: Only
1318 5 # stores 1 records per ISSN.
1319 6 # Last updated 2004-09-08 Mark Jordan, mjordan@sfu.ca
1320 7
1321 8 use strict;
1322 9 use Carp;
1323 10 use Net::Z3950;
1324 11 use MARC::Record;
1325 12 use DBI;
1326 13
1327 14 # DB connection settings
1328 15 my $host = "somehost";
1329 16 my $user = "someuser";
1330 17 my $password = "somepass";
1331 18 my $database = "somedb";
1332 19
1333 20 # Input file (one ISSS/line)
1334 21 my $InputFile = $ARGV[0];
1335 22
1336 23 # Prepare list of ISSNs to search
1337 24 my @ISSNs;
1338 25 open (INPUT, "< $InputFile") or die "Can't find input file\n";
1339 26 while (<INPUT>) { chomp $_; push (@ISSNs, $_); }
1340 27 close INPUT;
1341 28
1342 29
1343 30 # Set up connection management structures, connect to the server,
1344 31 # and submit the Z39.50 query.
1345 32 my $mgr = Net::Z3950::Manager->new( databaseName => 'voyager' );
1346 33 $mgr->option( elementSetName => "f" );
1347 34 $mgr->option( preferredRecordSyntax => Net::Z3950::RecordSyntax::USMARC );
1348 35 my $conn = $mgr->connect('z3950.loc.gov', '7090');
1349 36 croak "Unable to connect to server" if !defined($conn);
1350 37
1351 38
1352 39 my $handle = DBI->connect("DBI:mysql:$database:$host","$user","$password")
1353 40 or die $DBI::errstr;
1354 41
1355 42 foreach my $ISSN (@ISSNs) {
1356 43 my $zq = "\@attr 1=8 ". $ISSN;
1357 44 my $rs = $conn->search($zq);
1358 45 my $numrec = $rs->size();
1359 46 if ($numrec == 0) {
1360 47 print "Record for ISSN $ISSN not found, moving to next ISSN...\n";
1361 48 next;
1362 49 } else {
1363 50 # Extract MARC record from the result set, and invoke MARC::Record
1364 51 my $zrec = $rs->record(1);
1365 52 my $mrec = MARC::Record->new_from_usmarc($zrec->rawdata());
1366 53 my $rawdata = $zrec->rawdata();
1367 54 $rawdata = $handle->quote ($rawdata);
1368 55 # Add to db
1369 56 my $SQL = "insert into Titles values (NULL,NULL,'$ISSN',$rawdata)";
1370 57 my $cursor = $handle->prepare($SQL);
1371 58 $cursor->execute;
1372 59 print "Record for ISSN $ISSN added to database...\n";
1373 60 $cursor->finish;
1374 61 }
1375 62 }
1376 63 $handle->disconnect;
1377 64
1378 65 __END__
1379
1380 If you want to pull records out of the same database and do something
1381 with them, here's a template script:
1382
1383 1 #!/usr/bin/perl -w
1384 2
1385 3 # Script that gets MARC records (in blobs) from a database.
1386 4 # Last updated 2004-09-08 Mark Jordan, mjordan@sfu.ca
1387 5
1388 6 use strict;
1389 7 use MARC::Record;
1390 8 use DBI;
1391 9
1392 10 # DB connection settings
1393 11 my $mysql_host = "somehost";
1394 12 my $mysql_user = "someuser";
1395 13 my $mysql_password = "somepass*";
1396 14 my $mysql_database = "somedb";
1397 15
1398 16
1399 17 my $handle = DBI->connect("DBI:mysql:$mysql_database:$mysql_host",
1400 18 "$mysql_user","$mysql_password") or die $DBI::errstr;
1401 19
1402 20 my $SQL = "select * from Titles";
1403 21 my $cursor = $handle->prepare($SQL);
1404 22 $cursor->execute;
1405 23
1406 24 while (my @Records = $cursor->fetchrow_array) {
1407 25 my $RawMARC = $Records[3];
1408 26 my $mrec = MARC::Record->new_from_usmarc($RawMARC);
1409 27 # Print out the title
1410 28 print $mrec->title , "\n";
1411 29 }
1412 30
1413 31 $cursor->finish;
1414 32 $handle->disconnect;
1415 33
1416 34 __END__
1417
1418 Procite/Endnote
1419
1421 Many thanks to all the contributors who have made this document possi‐
1422 ble.
1423
1424 · Bryan Baldus <eijabb@cpan.org>
1425
1426 · Chris Biemesderfer <chris@seagoat.com>
1427
1428 · Morbus Iff <morbus@disobey.com>
1429
1430 · Mark Jordan <mjordan@sfu.ca>
1431
1432 · Andy Lester <andy@petdance.com>
1433
1434 · Christopher Morgan <morgan@acm.org>
1435
1436 · Shashi Pinheiro <SPinheiro@utsa.edu>
1437
1438 · Jackie Shieh <jshieh@umich.edu>
1439
1440 · Ed Summers <ehs@pobox.com>
1441
1442
1443
1444perl v5.8.8 2005-04-27 MARC::Doc::Tutorial(3)