|
Lines 42-48
use C4::Biblio qw( GetXmlBiblio );
Link Here
|
| 42 |
use Koha::XSLT::Base; |
42 |
use Koha::XSLT::Base; |
| 43 |
|
43 |
|
| 44 |
my $cgi = CGI->new(); |
44 |
my $cgi = CGI->new(); |
| 45 |
binmode(STDOUT, ":encoding(UTF-8)"); #output as utf8 |
45 |
binmode( STDOUT, ":encoding(UTF-8)" ); #output as utf8 |
| 46 |
|
46 |
|
| 47 |
=head1 VARIABLES |
47 |
=head1 VARIABLES |
| 48 |
|
48 |
|
|
Lines 52-58
This hashref of hashrefs maps from a MARC flavour and unAPI format
Link Here
|
| 52 |
to the stylesheet that should be used to transform the bib MARCXML |
52 |
to the stylesheet that should be used to transform the bib MARCXML |
| 53 |
to the desired output format. As new MARC XSLT stylesheets are added, |
53 |
to the desired output format. As new MARC XSLT stylesheets are added, |
| 54 |
(particularly for UNIMARC), this map should be updated. Of course, |
54 |
(particularly for UNIMARC), this map should be updated. Of course, |
| 55 |
if/when we add support for emitting a format that is not genreated |
55 |
if/when we add support for emitting a format that is not generated |
| 56 |
by a stylesheet, the structure of this variable will have to be changed. |
56 |
by a stylesheet, the structure of this variable will have to be changed. |
| 57 |
At present, this doubles as the list of output formats supported by |
57 |
At present, this doubles as the list of output formats supported by |
| 58 |
this unAPI implementation. |
58 |
this unAPI implementation. |
|
Lines 90-194
used to describe them in an unAPI format request.
Link Here
|
| 90 |
=cut |
90 |
=cut |
| 91 |
|
91 |
|
| 92 |
my $format_info = { |
92 |
my $format_info = { |
| 93 |
'marcxml' => q(<format name="marcxml" type="application/xml" namespace_uri="http://www.loc.gov/MARC21/slim" docs="http://www.loc.gov/marcxml/" schema_location="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"/>), |
93 |
'marcxml' => |
| 94 |
'marcxml-full' => q(<format name="marcxml-full" type="application/xml" namespace_uri="http://www.loc.gov/MARC21/slim" docs="http://www.loc.gov/marcxml/" schema_location="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"/>), |
94 |
q(<format name="marcxml" type="application/xml" namespace_uri="http://www.loc.gov/MARC21/slim" docs="http://www.loc.gov/marcxml/" schema_location="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"/>), |
| 95 |
'mods' => q(<format name="mods" type="application/xml" namespace_uri="http://www.loc.gov/mods/" docs="http://www.loc.gov/mods/" schema_location="http://www.loc.gov/standards/mods/mods.xsd"/>), |
95 |
'marcxml-full' => |
| 96 |
'mods-full' => q(<format name="mods-full" type="application/xml" namespace_uri="http://www.loc.gov/mods/" docs="http://www.loc.gov/mods/" schema_location="http://www.loc.gov/standards/mods/mods.xsd"/>), |
96 |
q(<format name="marcxml-full" type="application/xml" namespace_uri="http://www.loc.gov/MARC21/slim" docs="http://www.loc.gov/marcxml/" schema_location="http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"/>), |
| 97 |
'mods3' => q(<format name="mods3" type="application/xml" namespace_uri="http://www.loc.gov/mods/v3" docs="http://www.loc.gov/mods/" schema_location="http://www.loc.gov/standards/mods/v3/mods-3-1.xsd"/>), |
97 |
'mods' => |
| 98 |
'mods3-full' => q(<format name="mods3-full" type="application/xml" namespace_uri="http://www.loc.gov/mods/v3" docs="http://www.loc.gov/mods/" schema_location="http://www.loc.gov/standards/mods/v3/mods-3-1.xsd"/>), |
98 |
q(<format name="mods" type="application/xml" namespace_uri="http://www.loc.gov/mods/" docs="http://www.loc.gov/mods/" schema_location="http://www.loc.gov/standards/mods/mods.xsd"/>), |
| 99 |
'oai_dc' => q(<format name="oai_dc" type="application/xml" namespace_uri="http://www.openarchives.org/OAI/2.0/oai_dc/" schema_location="http://www.openarchives.org/OAI/2.0/oai_dc.xsd"/>), |
99 |
'mods-full' => |
| 100 |
'rdfdc' => q(<format name="rdfdc" type="application/xml" namespace_uri="http://purl.org/dc/elements/1.1/" schema_location="http://purl.org/dc/elements/1.1/"/>), |
100 |
q(<format name="mods-full" type="application/xml" namespace_uri="http://www.loc.gov/mods/" docs="http://www.loc.gov/mods/" schema_location="http://www.loc.gov/standards/mods/mods.xsd"/>), |
| 101 |
'rss2' => q(<format name="rss2" type="application/xml"/>), |
101 |
'mods3' => |
|
|
102 |
q(<format name="mods3" type="application/xml" namespace_uri="http://www.loc.gov/mods/v3" docs="http://www.loc.gov/mods/" schema_location="http://www.loc.gov/standards/mods/v3/mods-3-1.xsd"/>), |
| 103 |
'mods3-full' => |
| 104 |
q(<format name="mods3-full" type="application/xml" namespace_uri="http://www.loc.gov/mods/v3" docs="http://www.loc.gov/mods/" schema_location="http://www.loc.gov/standards/mods/v3/mods-3-1.xsd"/>), |
| 105 |
'oai_dc' => |
| 106 |
q(<format name="oai_dc" type="application/xml" namespace_uri="http://www.openarchives.org/OAI/2.0/oai_dc/" schema_location="http://www.openarchives.org/OAI/2.0/oai_dc.xsd"/>), |
| 107 |
'rdfdc' => |
| 108 |
q(<format name="rdfdc" type="application/xml" namespace_uri="http://purl.org/dc/elements/1.1/" schema_location="http://purl.org/dc/elements/1.1/"/>), |
| 109 |
'rss2' => q(<format name="rss2" type="application/xml"/>), |
| 102 |
'rss2-full' => q(<format name="rss2-full" type="application/xml"/>), |
110 |
'rss2-full' => q(<format name="rss2-full" type="application/xml"/>), |
| 103 |
'srw_dc' => q(<format name="srw_dc" type="application/xml" namespace_uri="info:srw/schema/1/dc-schema" schema_location="http://www.loc.gov/z3950/agency/zing/srw/dc-schema.xsd"/>), |
111 |
'srw_dc' => |
|
|
112 |
q(<format name="srw_dc" type="application/xml" namespace_uri="info:srw/schema/1/dc-schema" schema_location="http://www.loc.gov/z3950/agency/zing/srw/dc-schema.xsd"/>), |
| 104 |
}; |
113 |
}; |
| 105 |
|
114 |
|
| 106 |
my $id = $cgi->param('id'); |
115 |
my $id = $cgi->param('id'); |
| 107 |
my $format = $cgi->param('format'); |
116 |
my $format = $cgi->param('format'); |
| 108 |
|
117 |
|
| 109 |
if (not defined $format) { |
118 |
if ( not defined $format ) { |
| 110 |
emit_formats($id, $format_to_stylesheet_map, $format_info, $cgi); |
119 |
emit_formats( $id, $format_to_stylesheet_map, $format_info, $cgi ); |
| 111 |
} elsif ($id) { |
120 |
} elsif ($id) { |
| 112 |
|
121 |
|
| 113 |
# koha:biblionumber:0152018484 |
122 |
# koha:biblionumber:0152018484 |
| 114 |
if ($id =~ /koha:biblionumber:(\d+)/) { |
123 |
if ( $id =~ /koha:biblionumber:(\d+)/ ) { |
| 115 |
my $biblionumber = $1; |
124 |
my $biblionumber = $1; |
| 116 |
|
125 |
|
| 117 |
my $content; |
126 |
my $content; |
| 118 |
|
127 |
|
| 119 |
my $marcxml = GetXmlBiblio($biblionumber); |
128 |
my $marcxml = GetXmlBiblio($biblionumber); |
| 120 |
unless (defined $marcxml) { |
129 |
unless ( defined $marcxml ) { |
|
|
130 |
|
| 121 |
# no bib, so 404 |
131 |
# no bib, so 404 |
| 122 |
print $cgi->header( -status => '404 record not found'); |
132 |
print $cgi->header( -status => '404 record not found' ); |
| 123 |
exit 0; |
133 |
exit 0; |
| 124 |
} |
134 |
} |
| 125 |
|
135 |
|
| 126 |
my $xslt_file = get_xslt_file( $format, $format_to_stylesheet_map, $format_info ); |
136 |
my $xslt_file = get_xslt_file( $format, $format_to_stylesheet_map, $format_info ); |
| 127 |
unless( defined $xslt_file ) { |
137 |
unless ( defined $xslt_file ) { |
| 128 |
print $cgi->header( -status => '406 invalid format requested' ); |
138 |
print $cgi->header( -status => '406 invalid format requested' ); |
| 129 |
exit 0; |
139 |
exit 0; |
| 130 |
} |
140 |
} |
| 131 |
my $xslt_engine = Koha::XSLT::Base->new; |
141 |
my $xslt_engine = Koha::XSLT::Base->new; |
| 132 |
$content = $xslt_engine->transform({ |
142 |
$content = $xslt_engine->transform( |
| 133 |
xml => $marcxml, |
143 |
{ |
| 134 |
file => $xslt_file, |
144 |
xml => $marcxml, |
| 135 |
}); |
145 |
file => $xslt_file, |
| 136 |
|
146 |
} |
| 137 |
if( !defined $content || $xslt_engine->err ) { |
147 |
); |
|
|
148 |
|
| 149 |
if ( !defined $content || $xslt_engine->err ) { |
| 138 |
print $cgi->header( -status => '500 internal error' ); |
150 |
print $cgi->header( -status => '500 internal error' ); |
| 139 |
exit 0; |
151 |
exit 0; |
| 140 |
} |
152 |
} |
| 141 |
|
153 |
|
| 142 |
print $cgi->header( -type =>'application/xml', -charset => 'UTF-8' ); |
154 |
print $cgi->header( -type => 'application/xml', -charset => 'UTF-8' ); |
| 143 |
print $content; |
155 |
print $content; |
| 144 |
} else { |
156 |
} else { |
|
|
157 |
|
| 145 |
# ID is obviously wrong, so 404 |
158 |
# ID is obviously wrong, so 404 |
| 146 |
print $cgi->header( -status => '404 record not found'); |
159 |
print $cgi->header( -status => '404 record not found' ); |
| 147 |
exit 0; |
160 |
exit 0; |
| 148 |
} |
161 |
} |
| 149 |
} else { |
162 |
} else { |
|
|
163 |
|
| 150 |
# supplied a format but no id - caller is doing it wrong |
164 |
# supplied a format but no id - caller is doing it wrong |
| 151 |
print $cgi->header( -status => '400 bad request - if you specify format, must specify id'); |
165 |
print $cgi->header( -status => '400 bad request - if you specify format, must specify id' ); |
| 152 |
exit 0; |
166 |
exit 0; |
| 153 |
} |
167 |
} |
| 154 |
|
168 |
|
| 155 |
exit 0; |
169 |
exit 0; |
| 156 |
|
170 |
|
| 157 |
sub emit_formats { |
171 |
sub emit_formats { |
| 158 |
my ($id, $format_to_stylesheet_map, $format_info, $cgi) = @_; |
172 |
my ( $id, $format_to_stylesheet_map, $format_info, $cgi ) = @_; |
| 159 |
|
173 |
|
| 160 |
if (defined $id) { |
174 |
if ( defined $id ) { |
| 161 |
print $cgi->header( -type =>'application/xml', -status => '300 multiple choices' ); |
175 |
print $cgi->header( -type => 'application/xml', -status => '300 multiple choices' ); |
| 162 |
} else { |
176 |
} else { |
| 163 |
print $cgi->header( -type =>'application/xml', -status => '200 Ok' ); |
177 |
print $cgi->header( -type => 'application/xml', -status => '200 Ok' ); |
| 164 |
} |
178 |
} |
| 165 |
|
179 |
|
| 166 |
print "<?xml version='1.0' encoding='utf-8' ?>\n"; |
180 |
print "<?xml version='1.0' encoding='utf-8' ?>\n"; |
| 167 |
if (defined $id) { |
181 |
if ( defined $id ) { |
| 168 |
print qq(<formats id="$id">\n); |
182 |
print qq(<formats id="$id">\n); |
| 169 |
} else { |
183 |
} else { |
| 170 |
print "<formats>\n"; |
184 |
print "<formats>\n"; |
| 171 |
} |
185 |
} |
| 172 |
|
186 |
|
| 173 |
my $marcflavour = uc(C4::Context->preference('marcflavour')); |
187 |
my $marcflavour = uc( C4::Context->preference('marcflavour') ); |
| 174 |
foreach my $format (sort keys %{ $format_to_stylesheet_map->{$marcflavour} }) { |
188 |
foreach my $format ( sort keys %{ $format_to_stylesheet_map->{$marcflavour} } ) { |
| 175 |
print $format_info->{$format}, "\n"; |
189 |
print $format_info->{$format}, "\n"; |
| 176 |
} |
190 |
} |
| 177 |
print "</formats>\n"; |
191 |
print "</formats>\n"; |
| 178 |
return; |
192 |
return; |
| 179 |
} |
193 |
} |
| 180 |
|
194 |
|
| 181 |
|
|
|
| 182 |
sub get_xslt_file { |
195 |
sub get_xslt_file { |
| 183 |
my ($format, $format_to_stylesheet_map, $format_info) = @_; |
196 |
my ( $format, $format_to_stylesheet_map, $format_info ) = @_; |
| 184 |
$format = lc $format; |
197 |
$format = lc $format; |
| 185 |
|
198 |
|
| 186 |
my $marcflavour = uc(C4::Context->preference('marcflavour')); |
199 |
my $marcflavour = uc( C4::Context->preference('marcflavour') ); |
| 187 |
return unless $format_to_stylesheet_map->{$marcflavour}->{$format}; |
200 |
return unless $format_to_stylesheet_map->{$marcflavour}->{$format}; |
| 188 |
|
201 |
|
| 189 |
my $xslt_file = C4::Context->config('intrahtdocs') . |
202 |
my $xslt_file = |
| 190 |
"/prog/en/xslt/" . |
203 |
C4::Context->config('intrahtdocs') . "/prog/en/xslt/" . $format_to_stylesheet_map->{$marcflavour}->{$format}; |
| 191 |
$format_to_stylesheet_map->{$marcflavour}->{$format}; |
|
|
| 192 |
|
204 |
|
| 193 |
return $xslt_file; |
205 |
return $xslt_file; |
| 194 |
} |
206 |
} |
| 195 |
- |
|
|