Lines 1-27
Link Here
|
1 |
#!/usr/bin/perl |
1 |
#!/usr/bin/perl |
2 |
|
2 |
|
3 |
# Copyright Biblibre 2008 |
3 |
# Copyright Biblibre 2008 |
|
|
4 |
# Copyright The National Library of Finland 2015 |
4 |
# |
5 |
# |
5 |
# This file is part of Koha. |
6 |
# This file is part of Koha. |
6 |
# |
7 |
# |
7 |
# Koha is free software; you can redistribute it and/or modify it under the |
8 |
# Koha is free software; you can redistribute it and/or modify it |
8 |
# terms of the GNU General Public License as published by the Free Software |
9 |
# under the terms of the GNU General Public License as published by |
9 |
# Foundation; either version 2 of the License, or (at your option) any later |
10 |
# the Free Software Foundation; either version 3 of the License, or |
10 |
# version. |
11 |
# (at your option) any later version. |
11 |
# |
12 |
# |
12 |
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY |
13 |
# Koha is distributed in the hope that it will be useful, but |
13 |
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR |
14 |
# WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
15 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
16 |
# GNU General Public License for more details. |
15 |
# |
17 |
# |
16 |
# You should have received a copy of the GNU General Public License along |
18 |
# You should have received a copy of the GNU General Public License |
17 |
# with Koha; if not, write to the Free Software Foundation, Inc., |
19 |
# along with Koha; if not, see <http://www.gnu.org/licenses>. |
18 |
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|
|
19 |
|
20 |
|
20 |
|
21 |
|
21 |
use strict; |
22 |
use strict; |
22 |
use warnings; |
23 |
use warnings; |
23 |
|
24 |
|
24 |
use CGI qw/:standard -oldstyle_urls/; |
25 |
use CGI qw( :standard -oldstyle_urls -utf8 ); |
25 |
use vars qw( $GZIP ); |
26 |
use vars qw( $GZIP ); |
26 |
use C4::Context; |
27 |
use C4::Context; |
27 |
|
28 |
|
Lines 59-64
else {
Link Here
|
59 |
} |
60 |
} |
60 |
|
61 |
|
61 |
binmode STDOUT, ':encoding(UTF-8)'; |
62 |
binmode STDOUT, ':encoding(UTF-8)'; |
|
|
63 |
# OAI-PMH handles dates in UTC, so do that on the database level to avoid the |
64 |
# need for any conversions |
65 |
C4::Context->dbh->prepare("SET time_zone='+00:00'")->execute(); |
62 |
my $repository = C4::OAI::Repository->new(); |
66 |
my $repository = C4::OAI::Repository->new(); |
63 |
|
67 |
|
64 |
# __END__ Main Prog |
68 |
# __END__ Main Prog |
Lines 71-77
my $repository = C4::OAI::Repository->new();
Link Here
|
71 |
# - from |
75 |
# - from |
72 |
# - until |
76 |
# - until |
73 |
# - offset |
77 |
# - offset |
74 |
# |
78 |
# |
75 |
package C4::OAI::ResumptionToken; |
79 |
package C4::OAI::ResumptionToken; |
76 |
|
80 |
|
77 |
use strict; |
81 |
use strict; |
Lines 86-94
sub new {
Link Here
|
86 |
|
90 |
|
87 |
my $self = $class->SUPER::new(%args); |
91 |
my $self = $class->SUPER::new(%args); |
88 |
|
92 |
|
89 |
my ($metadata_prefix, $offset, $from, $until, $set); |
93 |
my ($metadata_prefix, $offset, $from, $until, $set, $stage); |
90 |
if ( $args{ resumptionToken } ) { |
94 |
if ( $args{ resumptionToken } ) { |
91 |
($metadata_prefix, $offset, $from, $until, $set) |
95 |
($metadata_prefix, $offset, $from, $until, $set, $stage) |
92 |
= split( '/', $args{resumptionToken} ); |
96 |
= split( '/', $args{resumptionToken} ); |
93 |
} |
97 |
} |
94 |
else { |
98 |
else { |
Lines 101-106
sub new {
Link Here
|
101 |
} |
105 |
} |
102 |
$offset = $args{ offset } || 0; |
106 |
$offset = $args{ offset } || 0; |
103 |
$set = $args{set}; |
107 |
$set = $args{set}; |
|
|
108 |
$stage = (defined $args{stage}) ? $args{stage} : 0; |
104 |
} |
109 |
} |
105 |
|
110 |
|
106 |
$self->{ metadata_prefix } = $metadata_prefix; |
111 |
$self->{ metadata_prefix } = $metadata_prefix; |
Lines 108-116
sub new {
Link Here
|
108 |
$self->{ from } = $from; |
113 |
$self->{ from } = $from; |
109 |
$self->{ until } = $until; |
114 |
$self->{ until } = $until; |
110 |
$self->{ set } = $set; |
115 |
$self->{ set } = $set; |
|
|
116 |
$self->{ stage } = $stage; |
111 |
|
117 |
|
112 |
$self->resumptionToken( |
118 |
$self->resumptionToken( |
113 |
join( '/', $metadata_prefix, $offset, $from, $until, $set ) ); |
119 |
join( '/', $metadata_prefix, $offset, $from, $until, $set, $stage ) ); |
114 |
$self->cursor( $offset ); |
120 |
$self->cursor( $offset ); |
115 |
|
121 |
|
116 |
return $self; |
122 |
return $self; |
Lines 138-146
sub new {
Link Here
|
138 |
repositoryName => C4::Context->preference("LibraryName"), |
144 |
repositoryName => C4::Context->preference("LibraryName"), |
139 |
adminEmail => C4::Context->preference("KohaAdminEmailAddress"), |
145 |
adminEmail => C4::Context->preference("KohaAdminEmailAddress"), |
140 |
MaxCount => C4::Context->preference("OAI-PMH:MaxCount"), |
146 |
MaxCount => C4::Context->preference("OAI-PMH:MaxCount"), |
141 |
granularity => 'YYYY-MM-DD', |
147 |
granularity => 'YYYY-MM-DDThh:mm:ssZ', |
142 |
earliestDatestamp => '0001-01-01', |
148 |
earliestDatestamp => '0001-01-01T00:00:00Z', |
143 |
deletedRecord => 'no', |
149 |
deletedRecord => 'persistent', |
144 |
); |
150 |
); |
145 |
|
151 |
|
146 |
# FIXME - alas, the description element is not so simple; to validate |
152 |
# FIXME - alas, the description element is not so simple; to validate |
Lines 187-192
sub new {
Link Here
|
187 |
metadataNamespace => 'http://www.openarchives.org/OAI/2.0/oai_dc/' |
193 |
metadataNamespace => 'http://www.openarchives.org/OAI/2.0/oai_dc/' |
188 |
) ); |
194 |
) ); |
189 |
$self->metadataFormat( HTTP::OAI::MetadataFormat->new( |
195 |
$self->metadataFormat( HTTP::OAI::MetadataFormat->new( |
|
|
196 |
metadataPrefix => 'marc21', |
197 |
schema => 'http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim.xsd', |
198 |
metadataNamespace => 'http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim' |
199 |
) ); |
200 |
$self->metadataFormat( HTTP::OAI::MetadataFormat->new( |
190 |
metadataPrefix => 'marcxml', |
201 |
metadataPrefix => 'marcxml', |
191 |
schema => 'http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim.xsd', |
202 |
schema => 'http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim.xsd', |
192 |
metadataNamespace => 'http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim' |
203 |
metadataNamespace => 'http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim' |
Lines 210-216
use HTTP::OAI::Metadata::OAI_DC;
Link Here
|
210 |
use base ("HTTP::OAI::Record"); |
221 |
use base ("HTTP::OAI::Record"); |
211 |
|
222 |
|
212 |
sub new { |
223 |
sub new { |
213 |
my ($class, $repository, $marcxml, $timestamp, $setSpecs, %args) = @_; |
224 |
my ($class, $repository, $marcxml, $timestamp, $setSpecs, $deleted, %args) = @_; |
214 |
|
225 |
|
215 |
my $self = $class->SUPER::new(%args); |
226 |
my $self = $class->SUPER::new(%args); |
216 |
|
227 |
|
Lines 218-239
sub new {
Link Here
|
218 |
$self->header( new HTTP::OAI::Header( |
229 |
$self->header( new HTTP::OAI::Header( |
219 |
identifier => $args{identifier}, |
230 |
identifier => $args{identifier}, |
220 |
datestamp => $timestamp, |
231 |
datestamp => $timestamp, |
|
|
232 |
status => $deleted ? 'deleted' : undef |
221 |
) ); |
233 |
) ); |
222 |
|
234 |
|
223 |
foreach my $setSpec (@$setSpecs) { |
235 |
foreach my $setSpec (@$setSpecs) { |
224 |
$self->header->setSpec($setSpec); |
236 |
$self->header->setSpec($setSpec); |
225 |
} |
237 |
} |
226 |
|
238 |
|
227 |
my $parser = XML::LibXML->new(); |
239 |
if (!$deleted) { |
228 |
my $record_dom = $parser->parse_string( $marcxml ); |
240 |
my $parser = XML::LibXML->new(); |
229 |
my $format = $args{metadataPrefix}; |
241 |
my $record_dom = $parser->parse_string( $marcxml ); |
230 |
if ( $format ne 'marcxml' ) { |
242 |
my $format = $args{metadataPrefix}; |
231 |
my %args = ( |
243 |
if ( $format ne 'marcxml' && $format ne 'marc21' ) { |
232 |
OPACBaseURL => "'" . C4::Context->preference('OPACBaseURL') . "'" |
244 |
my %args = ( |
233 |
); |
245 |
OPACBaseURL => "'" . C4::Context->preference('OPACBaseURL') . "'" |
234 |
$record_dom = $repository->stylesheet($format)->transform($record_dom, %args); |
246 |
); |
|
|
247 |
$record_dom = $repository->stylesheet($format)->transform($record_dom, %args); |
248 |
} |
249 |
$self->metadata( HTTP::OAI::Metadata->new( dom => $record_dom ) ); |
235 |
} |
250 |
} |
236 |
$self->metadata( HTTP::OAI::Metadata->new( dom => $record_dom ) ); |
|
|
237 |
|
251 |
|
238 |
return $self; |
252 |
return $self; |
239 |
} |
253 |
} |
Lines 314-353
sub new {
Link Here
|
314 |
if(defined $token->{'set'}) { |
328 |
if(defined $token->{'set'}) { |
315 |
$set = GetOAISetBySpec($token->{'set'}); |
329 |
$set = GetOAISetBySpec($token->{'set'}); |
316 |
} |
330 |
} |
317 |
my $sql = " |
331 |
my $max = $repository->{'koha_max_count'}; |
318 |
SELECT biblioitems.biblionumber, biblioitems.timestamp |
332 |
my $offset = $token->{'offset'}; |
319 |
FROM biblioitems |
333 |
|
320 |
"; |
334 |
my $count = 0; |
321 |
$sql .= " JOIN oai_sets_biblios ON biblioitems.biblionumber = oai_sets_biblios.biblionumber " if defined $set; |
335 |
# Since creating a union of normal and deleted record tables would be a heavy |
322 |
$sql .= " WHERE DATE(timestamp) >= ? AND DATE(timestamp) <= ? "; |
336 |
# operation, build results in two stages: first deleted records, then normal records |
323 |
$sql .= " AND oai_sets_biblios.set_id = ? " if defined $set; |
337 |
MAINLOOP: |
324 |
$sql .= " |
338 |
for ( my $stage = $token->{'stage'}; $stage < 2; $stage++ ) { |
325 |
LIMIT $repository->{'koha_max_count'} |
339 |
my $sql = C4::OAI::Utils->build_list_sql($stage == 0, $set, $max, $offset); |
326 |
OFFSET $token->{'offset'} |
340 |
my $sth = $dbh->prepare( $sql ) || die('Query preparation failed: ' . $dbh->errstr); |
327 |
"; |
341 |
my @bind_params = (C4::OAI::Utils->fix_date($token->{'from'}, 0), C4::OAI::Utils->fix_date($token->{'until'}, 1)); |
328 |
my $sth = $dbh->prepare( $sql ); |
342 |
push @bind_params, $set->{'id'} if defined $set; |
329 |
my @bind_params = ($token->{'from'}, $token->{'until'}); |
343 |
$sth->execute( @bind_params ) || die('Query failed: ' . $dbh->errstr); |
330 |
push @bind_params, $set->{'id'} if defined $set; |
344 |
|
331 |
$sth->execute( @bind_params ); |
345 |
while ( my ($biblionumber, $timestamp) = $sth->fetchrow ) { |
332 |
|
346 |
$count++; |
333 |
my $pos = $token->{offset}; |
347 |
if ( $count > $max ) { |
334 |
while ( my ($biblionumber, $timestamp) = $sth->fetchrow ) { |
348 |
$self->resumptionToken( |
335 |
$timestamp =~ s/ /T/, $timestamp .= 'Z'; |
349 |
new C4::OAI::ResumptionToken( |
336 |
$self->identifier( new HTTP::OAI::Header( |
350 |
metadataPrefix => $token->{metadata_prefix}, |
337 |
identifier => $repository->{ koha_identifier} . ':' . $biblionumber, |
351 |
from => $token->{from}, |
338 |
datestamp => $timestamp, |
352 |
until => $token->{until}, |
339 |
) ); |
353 |
offset => $offset + $max, |
340 |
$pos++; |
354 |
set => $token->{set}, |
|
|
355 |
stage => $stage |
356 |
) |
357 |
); |
358 |
last MAINLOOP; |
359 |
} |
360 |
$timestamp =~ s/ /T/, $timestamp .= 'Z'; |
361 |
my $header = new HTTP::OAI::Header( |
362 |
identifier => $repository->{ koha_identifier} . ':' . $biblionumber, |
363 |
datestamp => $timestamp, |
364 |
); |
365 |
if ($stage == 0) { |
366 |
$header->status( 'deleted' ); |
367 |
} |
368 |
$self->identifier( $header ); |
369 |
} |
370 |
# Reset offset for next stage |
371 |
$offset = 0; |
341 |
} |
372 |
} |
342 |
$self->resumptionToken( |
|
|
343 |
new C4::OAI::ResumptionToken( |
344 |
metadataPrefix => $token->{metadata_prefix}, |
345 |
from => $token->{from}, |
346 |
until => $token->{until}, |
347 |
offset => $pos, |
348 |
set => $token->{set} |
349 |
) |
350 |
) if ($pos > $token->{offset}); |
351 |
|
373 |
|
352 |
return $self; |
374 |
return $self; |
353 |
} |
375 |
} |
Lines 467-518
sub new {
Link Here
|
467 |
if(defined $token->{'set'}) { |
489 |
if(defined $token->{'set'}) { |
468 |
$set = GetOAISetBySpec($token->{'set'}); |
490 |
$set = GetOAISetBySpec($token->{'set'}); |
469 |
} |
491 |
} |
470 |
my $sql = " |
492 |
my $offset = $token->{'offset'}; |
471 |
SELECT biblioitems.biblionumber, biblioitems.marcxml, biblioitems.timestamp |
493 |
my $max = $repository->{'koha_max_count'}; |
472 |
FROM biblioitems |
494 |
my $query = ' |
473 |
"; |
495 |
SELECT biblioitems.marcxml |
474 |
$sql .= " JOIN oai_sets_biblios ON biblioitems.biblionumber = oai_sets_biblios.biblionumber " if defined $set; |
496 |
FROM biblioitems |
475 |
$sql .= " WHERE DATE(timestamp) >= ? AND DATE(timestamp) <= ? "; |
497 |
WHERE biblionumber = ? |
476 |
$sql .= " AND oai_sets_biblios.set_id = ? " if defined $set; |
498 |
'; |
477 |
$sql .= " |
499 |
my $marc_sth = $dbh->prepare($query) || die('Query preparation failed: ' . $dbh->errstr); |
478 |
LIMIT $repository->{'koha_max_count'} |
500 |
|
479 |
OFFSET $token->{'offset'} |
501 |
my $count = 0; |
480 |
"; |
502 |
# Since creating a union of normal and deleted record tables would be a heavy |
481 |
|
503 |
# operation, build results in two stages: first deleted records, then normal records |
482 |
my $sth = $dbh->prepare( $sql ); |
504 |
MAINLOOP: |
483 |
my @bind_params = ($token->{'from'}, $token->{'until'}); |
505 |
for ( my $stage = $token->{'stage'}; $stage < 2; $stage++ ) { |
484 |
push @bind_params, $set->{'id'} if defined $set; |
506 |
my $sql = C4::OAI::Utils->build_list_sql($stage == 0, $set, $max, $offset); |
485 |
$sth->execute( @bind_params ); |
507 |
my $sth = $dbh->prepare( $sql ) || die('Query preparation failed: ' . $dbh->errstr); |
486 |
|
508 |
my @bind_params = (C4::OAI::Utils->fix_date($token->{'from'}, 0), C4::OAI::Utils->fix_date($token->{'until'}, 1)); |
487 |
my $pos = $token->{offset}; |
509 |
push @bind_params, $set->{'id'} if defined $set; |
488 |
while ( my ($biblionumber, $marcxml, $timestamp) = $sth->fetchrow ) { |
510 |
$sth->execute( @bind_params ) || die('Query failed: ' . $dbh->errstr); |
489 |
my $oai_sets = GetOAISetsBiblio($biblionumber); |
511 |
|
490 |
my @setSpecs; |
512 |
while ( my ($biblionumber, $timestamp) = $sth->fetchrow ) { |
491 |
foreach (@$oai_sets) { |
513 |
$count++; |
492 |
push @setSpecs, $_->{spec}; |
514 |
if ( $count > $max ) { |
|
|
515 |
$self->resumptionToken( |
516 |
new C4::OAI::ResumptionToken( |
517 |
metadataPrefix => $token->{metadata_prefix}, |
518 |
from => $token->{from}, |
519 |
until => $token->{until}, |
520 |
offset => $offset + $max, |
521 |
set => $token->{set}, |
522 |
stage => $stage |
523 |
) |
524 |
); |
525 |
last MAINLOOP; |
526 |
} |
527 |
my $marcxml = ''; |
528 |
if ($stage == 1) { |
529 |
$marc_sth->execute(($biblionumber)) || die('Query failed: ' . $dbh->errstr); |
530 |
my @marc_results = $marc_sth->fetchrow_array(); |
531 |
if (@marc_results) { |
532 |
$marcxml = $marc_results[0]; |
533 |
} |
534 |
} |
535 |
my $oai_sets = GetOAISetsBiblio($biblionumber); |
536 |
my @setSpecs; |
537 |
foreach (@$oai_sets) { |
538 |
push @setSpecs, $_->{spec}; |
539 |
} |
540 |
$self->record( C4::OAI::Record->new( |
541 |
$repository, $marcxml, $timestamp, \@setSpecs, $stage == 0 || !$marcxml, |
542 |
identifier => $repository->{ koha_identifier } . ':' . $biblionumber, |
543 |
metadataPrefix => $token->{metadata_prefix} |
544 |
) ); |
493 |
} |
545 |
} |
494 |
$self->record( C4::OAI::Record->new( |
546 |
# Reset offset for next stage |
495 |
$repository, $marcxml, $timestamp, \@setSpecs, |
547 |
$offset = 0; |
496 |
identifier => $repository->{ koha_identifier } . ':' . $biblionumber, |
|
|
497 |
metadataPrefix => $token->{metadata_prefix} |
498 |
) ); |
499 |
$pos++; |
500 |
} |
548 |
} |
501 |
$self->resumptionToken( |
|
|
502 |
new C4::OAI::ResumptionToken( |
503 |
metadataPrefix => $token->{metadata_prefix}, |
504 |
from => $token->{from}, |
505 |
until => $token->{until}, |
506 |
offset => $pos, |
507 |
set => $token->{set} |
508 |
) |
509 |
) if ($pos > $token->{offset}); |
510 |
|
549 |
|
511 |
return $self; |
550 |
return $self; |
512 |
} |
551 |
} |
513 |
|
552 |
|
514 |
# __END__ C4::OAI::ListRecords |
553 |
# __END__ C4::OAI::ListRecords |
515 |
|
554 |
|
|
|
555 |
package C4::OAI::Utils; |
556 |
|
557 |
use strict; |
558 |
|
559 |
sub fix_date { |
560 |
my ($class, $date, $end) = @_; |
561 |
|
562 |
if (length($date) == 10) { |
563 |
if ($end) { |
564 |
$date .= ' 23:59:59'; |
565 |
} else { |
566 |
$date .= ' 00:00:00'; |
567 |
} |
568 |
} else { |
569 |
$date = substr($date, 0, 10) . ' ' . substr($date, 11, 8); |
570 |
} |
571 |
return $date; |
572 |
} |
573 |
|
574 |
sub build_list_sql { |
575 |
my ($class, $deleted, $set, $max, $offset) = @_; |
576 |
|
577 |
my $table = $deleted ? 'deletedbiblioitems' : 'biblioitems'; |
578 |
|
579 |
my $sql = " |
580 |
SELECT bi.biblionumber, bi.timestamp |
581 |
FROM $table bi |
582 |
WHERE bi.timestamp >= ? AND bi.timestamp <= ? |
583 |
ORDER BY bi.biblionumber |
584 |
"; |
585 |
|
586 |
# Use a subquery for sets since it allows us to use an index for the subquery in |
587 |
# biblioitems table and is quite a bit faster than a join. |
588 |
if (defined $set) { |
589 |
$sql = " |
590 |
SELECT bi.* FROM ($sql) bi |
591 |
WHERE bi.biblionumber in (SELECT osb.biblionumber FROM oai_sets_biblios osb WHERE osb.set_id = ?) |
592 |
"; |
593 |
} |
594 |
$sql .= ' |
595 |
LIMIT ' . ($max + 1) . " |
596 |
OFFSET $offset |
597 |
"; |
598 |
|
599 |
return $sql; |
600 |
} |
601 |
|
602 |
# __END__ C4::OAI::Utils; |
603 |
|
516 |
|
604 |
|
517 |
|
605 |
|
518 |
package C4::OAI::Repository; |
606 |
package C4::OAI::Repository; |
Lines 541-547
sub new {
Link Here
|
541 |
|
629 |
|
542 |
$self->{ koha_identifier } = C4::Context->preference("OAI-PMH:archiveID"); |
630 |
$self->{ koha_identifier } = C4::Context->preference("OAI-PMH:archiveID"); |
543 |
$self->{ koha_max_count } = C4::Context->preference("OAI-PMH:MaxCount"); |
631 |
$self->{ koha_max_count } = C4::Context->preference("OAI-PMH:MaxCount"); |
544 |
$self->{ koha_metadata_format } = ['oai_dc', 'marcxml']; |
632 |
$self->{ koha_metadata_format } = ['oai_dc', 'marc21', 'marcxml']; |
545 |
$self->{ koha_stylesheet } = { }; # Build when needed |
633 |
$self->{ koha_stylesheet } = { }; # Build when needed |
546 |
|
634 |
|
547 |
# Load configuration file if defined in OAI-PMH:ConfFile syspref |
635 |
# Load configuration file if defined in OAI-PMH:ConfFile syspref |
Lines 639-645
C4::OAI::Repository - Handles OAI-PMH requests for a Koha database.
Link Here
|
639 |
This object extend HTTP::OAI::Repository object. |
727 |
This object extend HTTP::OAI::Repository object. |
640 |
It accepts OAI-PMH HTTP requests and returns result. |
728 |
It accepts OAI-PMH HTTP requests and returns result. |
641 |
|
729 |
|
642 |
This OAI-PMH server can operate in a simple mode and extended one. |
730 |
This OAI-PMH server can operate in a simple mode and extended one. |
643 |
|
731 |
|
644 |
In simple mode, repository configuration comes entirely from Koha system |
732 |
In simple mode, repository configuration comes entirely from Koha system |
645 |
preferences (OAI-PMH:archiveID and OAI-PMH:MaxCount) and the server returns |
733 |
preferences (OAI-PMH:archiveID and OAI-PMH:MaxCount) and the server returns |
Lines 662-669
configuration file koha-oai.conf can look like that:
Link Here
|
662 |
metadataNamespace: http://veryspecial.tamil.fr/vs/format-pivot/1.1/vs |
750 |
metadataNamespace: http://veryspecial.tamil.fr/vs/format-pivot/1.1/vs |
663 |
schema: http://veryspecial.tamil.fr/vs/format-pivot/1.1/vs.xsd |
751 |
schema: http://veryspecial.tamil.fr/vs/format-pivot/1.1/vs.xsd |
664 |
xsl_file: /usr/local/koha/xslt/vs.xsl |
752 |
xsl_file: /usr/local/koha/xslt/vs.xsl |
665 |
marcxml: |
753 |
marc21 or marcxml: |
666 |
metadataPrefix: marxml |
754 |
metadataPrefix: marc21 or marxml |
667 |
metadataNamespace: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim |
755 |
metadataNamespace: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim |
668 |
schema: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd |
756 |
schema: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd |
669 |
oai_dc: |
757 |
oai_dc: |
670 |
- |
|
|