=head2 Original Message

On Thursday, May 12, 2005 9:13 AM, Jane Jacobs wrote:
>I've been working with a script to add an 020 field with the 13 digit
>ISBN, generating the 13 digit ISBN from the 10 digit ISBN.  This
>configuration works fine in DRA classic (making the UPC searchable as an
>ISBN).  So far so good.  The problem is that if someone had
>conscientiously added the UPC in 020 ALREADY (right now this doesn't
>happen often, but soon it might) you would end up with duplicate 020s
>for the 13 digit ISBN, hence my question.  How could you write your
>script to say "add this field unless it duplicates an existing field"?

Below is a very rough start of  what I might do to accomplish this (assuming
'UPC' was meant to mean 'EAN' or ISBN-13). The code has not really been
tested and needs some improvements, including proper ordering of the added
fields (the 13 and 10 should be added in matching pairs next to each other;
this version of the code simply adds the 020s before the first field after
020). The qualifier information is also not added after the 13-digit ISBNs.
A revised version of the code might gather the ISBNs on the first pass and
then loop through the 020 fields again to add the unique 13s preceding the
10-digit they match, using the qualifier on that 10, if any.

=head2 Original example

For:
020    $a0838935419 (alk. paper)
Append field:
020    $a9780838935415
Unless: 
020    $a9780838935415   already present in the record
>This could also be useful other places and I'm sure someone is already
>doing it.  It might be good to add to the documentation too.



=cut


#!perl

=head2 Duplicate ISBN-10 as ISBN-13

Adds 020 field for 13-digit version of ISBN based on 10-digit ISBN unless
the 13-digit version already exists.

=head2 TODO

 -Reorder 13 to precede corresponding 10.
 -Add qualifier from 10 to matching 13 if such info is present
 -Test code to make sure it works.

=cut

use strict;
use warnings;
use MARC::Batch;
use Business::ISBN qw(isbn_to_ean);

#change output path as necessary
my $output = '020test.txt';
open (OUT, ">$output") || die "Problem opening output file, $!";

#change input path as necessary
my $inputfile = 'file_of_records.mrc';

#initialize $batch as new MARC::Batch object
my $batch = MARC::Batch->new('USMARC', "$inputfile");

#use count for reporting number of records scanned
my $count = 0;

#### Start while loop through records in file #####
while (my $record = $batch->next()) {

    $count++;

    my %isbn10s = ();
    my %isbn13s = ();
    my @fields020 = $record->field('020');
    foreach my $field020 (@fields020) {
        #only want ISBNs in subfield 'a'
        my $isbnno = $field020->subfield('a') if $field020->subfield('a');

        #skip to next field if no 020a was found
        next unless $isbnno;
        
        #extract the actual ISBN number from 020a string
        $isbnno =~ s/^\D*(\d{9,12}[X\d])\b.*$/$1/;
        #add ISBN number to hash of ISBN10s for this record if it matches
normal ISBN-10 pattern 
        if ($isbnno =~ /(?:^\d{10}$)|(?:^\d{9}X$)/) {
            $isbn10s{$isbnno}++;
        } #if isbn-10
        
        #otherwise, if this is an ISBN-13, add to hash of ISBN13s
        elsif ($isbnno =~ /(?:^\d{13}$)/) {
            $isbn13s{$isbnno}++;
        } #elsif isbn-13
    } #foreach 020 field


    #insert new 020 after next closest tag
    my $after = '';
    foreach ($record->fields()) {
        #set after to the current field until the tag is greater than or
equal to 020
        #account for/skip non-numeric tags
        next unless ($_->tag() =~ /^[0-9][0-9][0-9]$/);
        $after = $_ unless ($_->tag() > 20);
        #stop once tag is greater than 020
        last if $_->tag() > 20;
    } #foreach field in record 


    #create a new 020 for each 10 as 13 unless the 13 exists already
    foreach my $isbn10 (keys %isbn10s) {
        my $new020 = MARC::Field->new('020', '', '', 'a' =>
isbn_to_ean($isbn10)) unless $isbn13s{isbn_to_ean($isbn10)};
        $record->insert_fields_after($after, $new020) if $new020;
        
    } #foreach 10-digit

    print OUT $record->as_usmarc();

} #while records






=head2

I hope this helps,

Bryan Baldus
[EMAIL PROTECTED]
[EMAIL PROTECTED]
http://home.inwave.com/eija
 
=cut

Reply via email to