问题
I am writing a perl script that will zip up a group of files from a given parent folder and create a *.epub file. The process works ok, and I am able to open the epub in adobe digital editions, but I get an epubchecker error:
Required MTA-INF/container.xml resource is missing
When I zip up the files manually (I'm on a winxp machine) there are no problems, but the perl created file throws the error. Here is the relevant code:
#-------------------------------------------------------------------------------
# name : createEpub
# purpose : create an epub from a given parent folder
# args : [0] parent folder [1] name of new zip file [2] log object
# example : &createEpub( $zipLoc, 'newzip', $log);
# notes : it is assumed that mimetype, meta-inf and oebs are all child folders
# of the given parent folder
# author: : jw 2/4/13
#-------------------------------------------------------------------------------
sub createEpub(){
my ($parentFolder, $zipName, $log) = @_;
my $newZipLoc;
$parentFolder =~ s#\\#/#g;
my $newZip = Archive::Zip->new();
# add mimetype first with no compression
my $mimetype = "$parentFolder/mimetype";
my $mimetypeMember = $newZip->addFile( $mimetype, 'mimetype');
$mimetypeMember->desiredCompressionMethod( COMPRESSION_STORED );
## add web-inf
my $metaINF = $parentFolder . '/META-INF';
&addFilesToZip( $metaINF, $parentFolder, $newZip, $log);
## add OEBPS
my $oebps = $parentFolder . '/OEBPS';
&addFilesToZip( $oebps, $parentFolder, $newZip, $log );
# maybe break this out in its own func...ok for current epub script purposes
$newZipLoc = $1 if $parentFolder =~ m/(.*)\//;
$newZipLoc = $newZipLoc . '/' . $zipName;
if( $newZipLoc !~ m/\.zip/){
$newZipLoc = $newZipLoc . '.epub';
}
$log->info("writing new zip file to $newZipLoc");
$newZip->writeToFileNamed( $newZipLoc );
## not sure if this is the write thing to do...returning actual file name, not zip extract object
return $newZipLoc;
}
sub addFilesToZip(){
my ($file, $origParent, $zip, $log) = @_;
if( -d $file ){
my @children = grep{ $_ !~ m/mimetype/} glob("$file/*") or warn "can't add $file to zip! $!\n";
foreach my $child( @children ){
&addFilesToZip( $child, $origParent, $zip, $log);
}
} elsif (-f $file){
my $memPath = $file; $memPath =~ s/\Q$origParent\E//;
$log->info("adding member $memPath");
my $newMember = $zip->addFile( $file, $memPath );
}
}
when I open the resulting epub file in winzip, the container.xml is definitely there, I also made sure the mimetype is first with no compression. Here's an excerpt from the log:
-------------------------------------------------------------------------
creating zip file from recently unzipped files
-------------------------------------------------------------------------
[ok]: adding member /META-INF/container.xml
[ok]: adding member /META-INF/stylesheet.css.kindle
[ok]: adding member /META-INF/toc.ncx.kindle
[ok]: adding member /OEBPS/content.opf
[ok]: adding member /OEBPS/coverpage.html
In the googling I've seen there is a slight alteration people make in their linux shell commands, but I didn't see anything related to archive::zip or win.
thanks, bp
回答1:
From your logging it looks like you are creating entries in the zip file with absolute paths.
[ok]: adding member /META-INF/container.xml
I believe epub files need to be relative paths - try removing the leading "/" from the path that is going to be written to the zip file. Something like ths (untested)
} elsif (-f $file){
my $memPath = $file; $memPath =~ s/\Q$origParent\E//;
# remove leading "/"
$memPath =~ s#^/+##;
$log->info("adding member $memPath");
my $newMember = $zip->addFile( $file, $memPath );
}
来源:https://stackoverflow.com/questions/14698579/creating-epub-with-perl-archivezip-epubchecker-error