欢迎回到 Nooks & Crannies!在我休假一个月结婚后,我一直在挖掘一些有趣的内容,用于即将到来的专栏。本月,我将看看一些开源代码库,开发人员可以使用它们来处理 MARC 格式的记录。
MARC 新手的一些背景知识
MARC 代表机器可读编目记录。这是一种格式,最初于 20 世纪 60 年代为美国国会图书馆开发,目的是促进图书馆之间书目记录的交换。到 20 世纪 70 年代中期,它已成为国际标准,在世界各地使用。
MARC 格式有几种变体。MARC21 是 20 世纪 90 年代 USMARC 和 CANMARC(当时美国和加拿大的变体)以及其他国家/地区自身格式的合并。在欧洲大部分地区,UNIMARC 是最常见的变体。所有这些记录的格式都相同,结构包括标签(用于包含信息)、目录(用于告知记录中包含哪些标签以及它们的位置)。
每个标签在每种格式中都有特定的含义。例如,在 MARC21 书目格式中,245 标签包含有关作品标题的信息。其他信息,包括出版商、作者、实体书的大小、出版日期和主题,都包含在其他标签中。
记录的格式,如果您只是将其打印出来,会有点难以阅读。它最初是为串行交换而设计的,通过 9 磁道磁带,这种介质在 20 世纪 90 年代我职业生涯的早期仍在使用。记录的前五个字节是数字,告诉您记录的长度(以字节为单位)——包括这五个字节。聪明的现代书呆子会立即意识到这种结构的局限性:记录不能是 100,000 字节长。之后是标签目录,告诉您要查找哪些标签,以及每个标签从哪个字节开始。之后是标签数据,之后的一个字节是下一个记录的第一个字节。领导者/目录/标签结构在 ISO-2709 中通用定义;MARC21 或 UNIMARC 是定义标签含义的格式。
是的,按照现代标准,这是一个设计糟糕的格式。是的,它迫切需要更新,但这完全是另一篇文章的主题。在本文中,我将向您展示三个代码库,您可以使用它们来操作 MARC 记录,而无需了解所有关于神秘标签目录的细节。
Java:MARC4J
MARC4J 允许创建迭代器来读取输入流(例如文件),并对在流中找到的 MARC21 或 UNIMARC 记录执行操作。当然,也有记录写入工具,以及用于详细检查记录的迭代器。这是一个快速示例,它将读取记录文件,如果字段 245 子字段 a 中作品的标题以字母 J 开头,则将其写入另一个文件
import org.marc4j.MarcReader;
import org.marc4j.MarcStreamReader;
import org.marc4j.MarcStreamWriter;
import org.marc4j.marc.Record;
import org.marc4j.marc.DataField;
import org.marc4j.marc.Subfield;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class JMarcExample {
public static void main(String args[]) throws Exception {
InputStream in = new FileInputStream("inputfile.mrc");
OutputStream out = new FileOutputStream("outputfile.mrc");
MarcReader reader = new MarcStreamReader(in);
MarcWriter writer = new MARCStreamWriter(out);
while (reader.hasNext()) {
Record record = reader.next();
datafield = (DataField) record.getVariableField("245");
list subfields = datafield.getSubfields();
i = subfields.iterator();
while (i.hasNext()) {
Subfield subfield = (Subfield) i.next();
char code = subfield.getCode();
if ( code == 'a' ) {
String data = subfield.getData();
if ( data.startsWith("J") ) {
writer.write(record);
}
}
}
}
}
}
MARC4J 还包括 Unicode 和 MARCXML 变体(其中 MARC 记录以 XML 呈现)的处理程序,标签结构对于人眼来说更容易阅读,但正如您可以想象的那样,它更冗长。MARC4J 与 245 标签实际可能意味着什么无关,因此,从这个意义上说,它应该能够读取和写入任何 ISO-2709 格式的记录。
MARC4J 在 LGPL V2.1 许可下获得许可,并且可在 GitHub 上获得。
C#:CSharp_MARC
CSharp_MARC 具有丰富的工具集,用于导入和导出 MARC21 和 MARCXML 记录,包括记录验证和搜索替换工具,允许批量编辑记录。它还内置了一些报告工具,用于报告版权年份或分类。它非常轻量级,每分钟最多可处理 28,000 条记录。
这是一个示例程序,用于读取 MARC21 记录文件,并按记录出现的顺序打印每个记录的 100 标签子字段 a 中的作者姓名
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MARC;
using System.IO;
namespace CSharp_Show_Authors
{
class Program
{
static void Main(string[] args)
{
string rawMarc = File.ReadAllText("inputfile.mrc");
FileMARC marcRecords = new FileMARC(rawMarc);
foreach (Record record in marcRecords)
{
Field authorField = record["100"];
if (authorfield.IsDataField())
{
DataField authorDataField = (Datafield)authorField;
Subfield authorName = authorDataField['a'];
Console.WriteLine(authorName.Data);
}
else if (authorField.IsControlField())
{
//unreachable
Console.WriteLine("Something awful has happened. The author field should never be a control field!");
}
}
}
}
}
与 MARC4J 一样,CSharp_MARC 读取器和写入器工具实际上并不关心每个标签在书目记录中实际意味着什么,因此应该可用于 UNIMARC 或其他 MARC 变体。但是,内置的验证工具似乎仅限于 MARC21 和 MARCXML。CSharp_MARC 在 GPL V3.0 许可下获得许可,并且可在 GitHub 上获得。
Perl 5:MARC::Record
您不会真的认为我会让这篇文章在没有 Perl 的情况下通过吧?MARC::Record,与这里的其他工具一样,具有处理您可能需要的任何 ISO-2709 格式记录读取或写入需求的机制。它有一个内置的漂亮打印机,它可以处理字段插入或删除到记录中,并将在输出时正确更新标签目录。它不像 C# 库那样功能丰富,但可以处理大多数基本的记录操作需求。多年来,我在自己的工作中一直使用这个库。(免责声明:MARC::Record 由我的好朋友和同事 Galen Charlton 维护。)
这是一个示例脚本,用于读取 MARC21 记录文件,并写出一个管道分隔的作者(100 子字段 a)和标题(245 子字段 a)文件
use strict;
use warnings;
use MARC::File::USMARC;
use MARC::Record;
use MARC::Batch;
use MARC::Charset;
my $in_fh = IO::File->new("inputfile.mrc");
my $batch = MARC::Batch->new('USMARC',$in_fh);
$batch->warnings_off();
$batch->strict_off();
my $iggy = MARC::Charset::ignore_errors(1);
my $setting = MARC::Charset::assume_encoding('marc8');
open my $out_fh,">:utf8","outputfile.psv";
RECORD:
while () {
my $this_record = $batch->next();
last RECORD unless ($this_record);
my $author = $this_record->field('100')->subfield('a');
my $title = $this_record->field('245')->subfield('a');
print $out_fh "$author|$title\n";
}
close $in_fh;
close $out_fh;
MARC::Record 在 CPAN 上可用,并在 Perl 许可下可用。到目前为止,还没有人为 Perl 6 编写 MARC 处理程序;我现在可以听到六个同事对我大喊“自告奋勇!”...
我做了一些开源搜索
我在 GitHub 上进行了一些挖掘,并很快找到了 Python、JavaScript、Ruby、Node.js 和 Scala 中的库。我没有测试它们中的任何一个,所以它们可能不完整或部分,但对于您想要编码的任何语言,您很可能可以找到一个可以为您工作的模块。
1 条评论