我正在使用MARC::Lint
整理一些MARC记录,但是现在和它们我都出现了错误(大约占文件的1%):
utf8 "\xCA" does not map to Unicode at /usr/lib/x86_64-linux-gnu/perl/5.26/Encode.pm line 212.
问题是我尝试了不同的方法,但是在文件中找不到"\xCA"
...
我的脚本是:
#!perl -w
use MARC::File::USMARC;
use MARC::Lint;
use utf8;
use open OUT => ':utf8';
my $lint = new MARC::Lint;
my $filename = shift;
my $file = MARC::File::USMARC->in( $filename );
while ( my $marc = $file->next() ) {
$lint->check_record( $marc );
# Print the errors that were found
print join( "\n", $lint->warnings ), "\n";
} # while
,可以在这里下载文件:http://eroux.fr/I14376.mrc
“ \ xCA”是否隐藏在某个地方?还是这是MARC :: Lint中的错误?
答案 0 :(得分:3)
该问题与MARC :: Lint无关。删除棉绒检查,您仍然会收到错误消息。
问题是数据文件不正确。
文件包含信息在文件中所在位置的“目录”。以下是您提供的文件的目录的可读格式:
tagno|offset|len # Offsets are from the start of the data portion.
001|00000|0017 # Length include the single-byte field terminator.
006|00017|0019 # Offset and lengths are in bytes.
007|00036|0015
008|00051|0041
035|00092|0021
035|00113|0021
040|00134|0018
050|00152|0022
066|00174|0009
245|00183|0101
246|00284|0135
264|00419|0086
300|00505|0034
336|00539|0026
337|00565|0026
338|00591|0036
546|00627|0016
500|00643|0112
505|00755|9999 <--
506|29349|0051
520|29400|0087
533|29487|0115
542|29602|0070
588|29672|0070
653|29742|0013
710|29755|0038
720|29793|0130
776|29923|0066
856|29989|0061
880|30050|0181
880|30231|0262
请注意带有标签505 9999
的字段的长度。这是支持的最大值(因为长度存储为四个十进制数字)。不足之处在于该字段的值远远大于9,999字节;它实际上是28,594个字节。
发生的事情是该模块提取了9,999个字节,而不是28,594个字节。这恰好将UTF-8序列切成两半。 (特定序列为CA BA
,即ʼ
的编码。)随后,当模块尝试解码该文本时,将引发错误。 (CA
之后必须是另一个字节才有效。)
您正在生成这些记录吗?如果是这样,则需要确保没有字段需要超过9,999个字节。
仍然,模块应该更好地处理此问题。它可以读取直到找到场结束标记,而不是在没有期望的场结束标记时才使用长度,并且/或者可以以非致命的方式处理解码错误。它已经有了报告这些问题的机制($marc->warnings
)。
实际上,如果它没有消失(例如,剪切是否恰好发生在字符之间而不是字符中间),$marc->warnings
会返回以下消息:
field does not end in end of field character in tag 505 in record 1