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