View | Details | Raw Unified | Return to bug 13642
Collapse All | Expand All

(-)a/C4/Record.pm (-19 / +71 lines)
Lines 25-31 use strict; Link Here
25
# please specify in which methods a given module is used
25
# please specify in which methods a given module is used
26
use MARC::Record; # marc2marcxml, marcxml2marc, changeEncoding
26
use MARC::Record; # marc2marcxml, marcxml2marc, changeEncoding
27
use MARC::File::XML; # marc2marcxml, marcxml2marc, changeEncoding
27
use MARC::File::XML; # marc2marcxml, marcxml2marc, changeEncoding
28
use MARC::Crosswalk::DublinCore; # marc2dcxml
28
use Koha::DublinCoreTransformer; # marc2dcxml
29
use Biblio::EndnoteStyle;
29
use Biblio::EndnoteStyle;
30
use Unicode::Normalize; # _entity_encode
30
use Unicode::Normalize; # _entity_encode
31
use C4::Biblio; #marc2bibtex
31
use C4::Biblio; #marc2bibtex
Lines 231-237 C<$qualified> - specify whether qualified Dublin Core should be used in the inpu Link Here
231
=cut
231
=cut
232
232
233
sub marc2dcxml {
233
sub marc2dcxml {
234
	my ($marc,$qualified) = @_;
234
    my ( $type, $marc, $qualified, $entities, $root, $xsi_schemaLocation, $rdf_subject,
235
        $rdf_format ) = @_;
235
	my $error;
236
	my $error;
236
    # test if it's already a MARC::Record object, if not, make it one
237
    # test if it's already a MARC::Record object, if not, make it one
237
    my $marc_record_obj;
238
    my $marc_record_obj;
Lines 245-268 sub marc2dcxml { Link Here
245
			$error .="\nCreation of MARC::Record object failed: ".$MARC::File::ERROR;
246
			$error .="\nCreation of MARC::Record object failed: ".$MARC::File::ERROR;
246
		}
247
		}
247
	}
248
	}
248
	my $crosswalk = MARC::Crosswalk::DublinCore->new;
249
    my $dcxml;
249
	if ($qualified) {
250
250
		$crosswalk = MARC::Crosswalk::DublinCore->new( qualified => 1 );
251
    SWITCH:
251
	}
252
    for ($type) {
252
	my $dcxml = $crosswalk->as_dublincore($marc_record_obj);
253
        if (/^simple-dc-rdf/) {
253
	my $dcxmlfinal = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
254
            my $objectDC = Koha::DublinCoreTransformer->new({
254
	$dcxmlfinal .= "<metadata
255
                type            => 'rdf',
255
  xmlns=\"http://example.org/myapp/\"
256
                qualified       => 0,
256
  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
257
                get_marc_record => $marc,
257
  xsi:schemaLocation=\"http://example.org/myapp/ http://example.org/myapp/schema.xsd\"
258
            });
258
  xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
259
259
  xmlns:dcterms=\"http://purl.org/dc/terms/\">";
260
            $objectDC->get_rdf_data({
260
261
                rdf_subject => $rdf_subject,
261
	foreach my $element ( $dcxml->elements() ) {
262
                rdf_format  => $rdf_format,
262
                $dcxmlfinal.="<"."dc:".$element->name().">".$element->content()."</"."dc:".$element->name().">\n";
263
                entities    => 1,
264
            });
265
            $dcxml = $objectDC->write_rdf();
266
            last SWITCH;
267
        }
268
        if (/^dc-rdf/) {
269
            my $objectDC = Koha::DublinCoreTransformer->new({
270
                type            => 'rdf',
271
                qualified       => 1,
272
                get_marc_record => $marc,
273
            });
274
275
            $objectDC->get_rdf_data({
276
                rdf_subject => $rdf_subject,
277
                rdf_format  => $rdf_format,
278
                entities    => 1,
279
            });
280
            $dcxml = $objectDC->write_rdf();
281
            last SWITCH;
282
        }
283
        if (/^dc-xml/) {
284
            my $objectDC = Koha::DublinCoreTransformer->new({
285
                type            => 'xml',
286
                qualified       => $qualified,
287
                get_marc_record => $marc,
288
            });
289
290
            $objectDC->get_xml_data({
291
                root               => $root,
292
                xsi_schemaLocation => $xsi_schemaLocation,
293
                entities           => 1,
294
            });
295
            $dcxml = $objectDC->write_xml();
296
            last SWITCH;
297
        }
298
        if (/^oai-dc/) {
299
            my $objectDC = Koha::DublinCoreTransformer->new({
300
                type            => 'xml',
301
                qualified       => 0,
302
                get_marc_record => $marc,
303
            });
304
305
            $objectDC->get_xml_data({
306
                root               => 'oai_dc:dc',
307
                xsi_schemaLocation => 'http://www.openarchives.org/OAI/2.0/oai_dc/' .
308
                                      ' http://www.openarchives.org/OAI/2.0/oai_dc.xsd',
309
                entities           => 0,
310
                optional_namespace => 'oai_dc',
311
                namespace_url      => 'http://www.openarchives.org/OAI/2.0/oai_dc/',
312
            });
313
            $dcxml = $objectDC->write_xml();
314
            last SWITCH;
315
        }
263
    }
316
    }
264
	$dcxmlfinal .= "\n</metadata>";
317
    return ( $error, $dcxml );
265
	return ($error,$dcxmlfinal);
266
}
318
}
267
319
268
=head2 marc2modsxml - Convert from ISO-2709 to MODS
320
=head2 marc2modsxml - Convert from ISO-2709 to MODS
(-)a/Koha/DublinCoreTransformer.pm (+942 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
package Koha::DublinCoreTransformer;
3
4
#
5
# This file is part of Koha.
6
#
7
# Copyright (C) 2014 Universidad de El Salvador,
8
# Facultad Multidisciplinaria Oriental
9
#
10
# Koha is free software; you can redistribute it and/or modify it
11
# under the terms of the GNU General Public License as published by
12
# the Free Software Foundation; either version 3 of the License, or
13
# (at your option) any later version.
14
#
15
# Koha is distributed in the hope that it will be useful, but
16
# WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
# GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License
21
# along with Koha; if not, see <http://www.gnu.org/licenses>.
22
#
23
24
use Modern::Perl;
25
use strict;
26
use warnings::register;
27
use version;
28
use v5.10.1;
29
30
BEGIN {
31
    require Exporter;
32
33
    # set the version for version checking
34
    our $VERSION = version->declare("v0.01");
35
36
    # Inherit from Exporter to export functions and variables
37
    our @ISA = qw(Exporter);
38
39
    # Functions and variables which are exported by default
40
    our @EXPORT = qw(new get_xml_data get_rdf_data write_xml write_rdf);
41
42
    # Functions and variables which can be optionally exported
43
    our @EXPORT_OK =
44
      qw(type qualified get_marc_record root xsi_schemaLocation rdf_subject rdf_format entities optional_namespace namespace_url);
45
46
}
47
48
use utf8;
49
use Encode qw(is_utf8 encode decode);
50
use MARC::File::USMARC;
51
use MARC::Crosswalk::DublinCore;
52
use XML::LibXML;
53
use HTML::Entities;
54
use XML::Entities;
55
use RDF::Helper;
56
use base qw(Class::Accessor);
57
__PACKAGE__->mk_accessors(
58
    qw(type qualified get_marc_record root xsi_schemaLocation rdf_subject rdf_format entities optional_namespace namespace_url)
59
);
60
61
# Defining some constants
62
my $xsi_schema  = qq(http://www.w3.org/2001/XMLSchema-instance);
63
my $unqualified = qq(http://purl.org/dc/elements/1.1/);
64
my $qualified   = qq(http://purl.org/dc/terms/);
65
my $dcam        = qq(http://purl.org/dc/dcam/);
66
my $rdfNS       = qq(http://www.w3.org/1999/02/22-rdf-syntax-ns#);
67
my @elementupcase =
68
  qw/tableOfContents dateAccepted dateCopyrighted dateSubmitted isVersionOf hasVersion isReplacedBy isRequiredBy isPartOf hasPart isReferencedBy isFormatOf hasFormat conformsTo accrualMethod accrualPeriodicity accrualPolicy instructionalMethod rightsHolder educationLevel accessRights bibliographicCitation/;
69
70
#USAGE: Koha::DublinCoreTransformer->new({
71
#    type => 'xml|rdf',
72
#    qualified => 0|1,
73
#    get_marc_record => $record
74
#});
75
76
sub new {
77
    my ( $class, $args ) = @_;
78
    $args = {} unless defined $args;
79
    return bless( $args, $class );
80
}
81
82
sub get_xml_data {
83
84
#USAGE: oop->get_xml_data({
85
#        root => 'root',
86
#        xsi_schemaLocation => 'http://example.org/myapp/ http://example.org/myapp/schema.xsd',
87
#        entities => 0|1,
88
#        optional_namespace => 'oai_dc'
89
#        namespace_url => 'http://www.openarchives.org/OAI/2.0/oai_dc/'
90
#});
91
    my $self = shift;
92
    my ($args) = @_;
93
94
    if (@_) {
95
        $self->root( $args->{root} );
96
        $self->xsi_schemaLocation( $args->{xsi_schemaLocation} );
97
        $self->entities( $args->{entities} );
98
        $self->optional_namespace( $args->{optional_namespace} );
99
        $self->namespace_url( $args->{namespace_url} );
100
    }
101
102
    #if data not filled
103
    $self->{root}     = "metadata" unless ( defined $self->{root} );
104
    $self->{entities} = 0          unless ( defined $self->{entities} );
105
    my %dataxml = (
106
        xmlroot  => $self->{root},
107
        entities => $self->{entities},
108
        optional_namespace => $self->{optional_namespace},
109
        namespace_url => $self->{namespace_url},
110
    );
111
112
    if ( exists $self->{xsi_schemaLocation} ) {
113
        $dataxml{'xsi_schemaLocation'} = $self->{xsi_schemaLocation};
114
    }
115
    if ( exists $self->{xsi_schemaLocation} ) {
116
        $dataxml{'optional_namespace'} = $self->{optional_namespace};
117
    }
118
    if ( exists $self->{xsi_schemaLocation} ) {
119
        $dataxml{'namespace_url'} = $self->{namespace_url};
120
    }
121
    return \%dataxml;
122
}
123
124
sub get_rdf_data {
125
126
#USAGE: oop->get_rdf_data({
127
#        rdf_subject => 'http://opac.mydomain.edu/cgi-bin/koha/opac-detail.pl?biblionumber=17589',
128
#        rdf_format => 'ntriples | nquads| rdfxml | rdfjson | ntriples-canonical | turtle',
129
#        entities => 0|1,
130
#})
131
132
    my $self = shift;
133
    my ($args) = @_;
134
135
    if (@_) {
136
        $self->rdf_subject( $args->{rdf_subject} );
137
        $self->rdf_format( $args->{rdf_format} );
138
        $self->entities( $args->{entities} );
139
    }
140
141
    #if data not filled
142
    $self->{rdf_subject} = "http://koha-community.org/"
143
      unless ( defined $self->{rdf_subject} );
144
    $self->{rdf_format} = "rdfxml" unless ( defined $self->{rdf_format} );
145
    $self->{entities}   = 0        unless ( defined $self->{entities} );
146
    my %rdfdescription = (
147
        rdf_subject => $self->{rdf_subject},
148
        rdf_format  => $self->{rdf_format},
149
        entities    => $self->{entities},
150
    );
151
152
    return \%rdfdescription;
153
}
154
155
sub conversion_to_dc {
156
157
#Get the MARC record and return a Dublin Core elements, passed as argument in dc_order_execution method.
158
#USAGE:
159
#my dc = $self->conversion_to_dc();
160
#$self->dc_order_execution ($dc, $dcxml, $root);
161
    my $self            = shift;
162
    my $marc_record_obj = $self->get_marc_record();
163
    my $crosswalk;
164
    my $dc;
165
166
    #if data not filled
167
    $self->qualified(0) unless ( exists $self->{qualified} );
168
    if ( ( $self->qualified() != 0 and $self->qualified() != 1 )
169
        && warnings::enabled($self) )
170
    {
171
        warnings::warn( $self, "Only the 0 or 1 values are accepted" );
172
        die "Set qualified => " . $self->qualified() . " is no good, stopped";
173
    }
174
    if ( $self->qualified() == 1 ) {
175
        $crosswalk = MARC::Crosswalk::DublinCore->new( qualified => 1 );
176
    }
177
    elsif ( $self->qualified() == 0 ) {
178
        $crosswalk = MARC::Crosswalk::DublinCore->new( qualified => 0 );
179
    }
180
    if ( $marc_record_obj =~ /^MARC::Record/ ) {
181
        $dc = $crosswalk->as_dublincore($marc_record_obj);
182
    }
183
    else {
184
        warnings::warn( $self,
185
            "MARC::Record object failed or not a MARC::Record" );
186
        die "Stopped due get_marc_record => is not a MARC::Record";
187
    }
188
189
    return $dc;
190
191
}
192
193
sub write_xml {
194
    my $self    = shift;
195
    my $dataxml = $self->get_xml_data();
196
    my $dc      = $self->conversion_to_dc();
197
198
    #Looking for bad data
199
    if ( ( $self->type() ne 'xml' and $self->type() ne 'rdf' )
200
        && warnings::enabled($self) )
201
    {
202
        warnings::warn( $self, "Only the xml or rdf values are accepted" );
203
        die "Set type => " . $self->type() . " is no good, stopped";
204
    }
205
    elsif ( $self->type() eq 'rdf' && warnings::enabled($self) ) {
206
        warnings::warn( $self, "The constructor specified rdf" );
207
        die "Cannot use this method with rdf. This is no good, stopped";
208
    }
209
210
    if ( ( $self->entities() != 0 and $self->entities() != 1 )
211
        && warnings::enabled($self) )
212
    {
213
        warnings::warn( $self, "Only the 0 or 1 values are accepted" );
214
        die "Set entities => " . $self->entities() . " is no good, stopped";
215
    }
216
217
    #Creating XML object
218
    my $doc = XML::LibXML::Document->new( '1.0', 'utf-8' );
219
    my $root = $doc->createElement( $dataxml->{'xmlroot'} );
220
    $root->setNamespace( $xsi_schema, 'xsi', 0 );
221
222
    if (defined $dataxml->{'optional_namespace'}){
223
    $root->setNamespace( $dataxml->{'namespace_url'},
224
                        $dataxml->{'optional_namespace'}, 0 );
225
    }
226
227
    if ( $self->type() eq 'xml' ) {
228
        if ( $self->qualified() == 0 ) {
229
            if ( defined $dataxml->{'xsi_schemaLocation'} ) {
230
                $root->setAttribute(
231
                    'xsi:schemaLocation' => $dataxml->{'xsi_schemaLocation'} );
232
                $root->setNamespace( $unqualified, 'dc', 0 );
233
                $self->dc_order_execution( $dc, $doc, $root );
234
            }
235
            else {
236
                $root->setNamespace( $unqualified, 'dc', 0 );
237
                $self->dc_order_execution( $dc, $doc, $root );
238
            }
239
        }
240
        elsif ( $self->qualified() == 1 ) {
241
            if ( defined $dataxml->{'xsi_schemaLocation'} ) {
242
                $root->setAttribute(
243
                    'xsi:schemaLocation' => $dataxml->{'xsi_schemaLocation'} );
244
                $root->setNamespace( $unqualified, 'dc',      0 );
245
                $root->setNamespace( $qualified,   'dcterms', 0 );
246
                $self->dc_order_execution( $dc, $doc, $root );
247
            }
248
            else {
249
                $root->setNamespace( $unqualified, 'dc',      0 );
250
                $root->setNamespace( $qualified,   'dcterms', 0 );
251
                $self->dc_order_execution( $dc, $doc, $root );
252
            }
253
        }
254
    }
255
256
    $doc->setDocumentElement($root);
257
258
    #Enabling or desabling entities and print the xml
259
    if ( $dataxml->{'entities'} == 1 ) {
260
        my $serialized_data = $doc->toString(1);
261
        my ($dcxml_entity_encoded) = XML_entity_encode( $serialized_data );
262
        $serialized_data = $dcxml_entity_encoded;
263
        return $serialized_data;
264
    }
265
    else {
266
        return $doc->toString(1);
267
    }
268
}
269
270
sub write_rdf {
271
    my $self           = shift;
272
    my $rdfdescription = $self->get_rdf_data();
273
    my $dc             = $self->conversion_to_dc();
274
    my $rdf;
275
    my $subject = $rdfdescription->{'rdf_subject'};
276
277
    #Looking for bad data
278
    if ( ( $self->type() ne 'xml' and $self->type() ne 'rdf' )
279
        && warnings::enabled($self) )
280
    {
281
        warnings::warn( $self, "Only the xml or rdf values are accepted" );
282
        die "Set type => " . $self->type() . " is no good, stopped";
283
    }
284
    elsif ( $self->type() eq 'xml' && warnings::enabled($self) ) {
285
        warnings::warn( $self, "The constructor specified xml" );
286
        die "Cannot use this method with xml. This is no good, stopped";
287
    }
288
289
    if ( ( $self->entities() != 0 and $self->entities() != 1 )
290
        && warnings::enabled($self) )
291
    {
292
        warnings::warn( $self, "Only the 0 or 1 values are accepted" );
293
        die "Set entities => " . $self->entities() . " is no good, stopped";
294
    }
295
296
    if ( $self->qualified() == 0 ) {
297
298
        #Creating RDF::Helper object
299
        $rdf = RDF::Helper->new(
300
            BaseInterface => 'RDF::Trine',
301
            namespaces    => {
302
                rdf => $rdfNS,
303
                dc  => $unqualified,
304
            },
305
            ExpandQNames => 1,
306
            base_uri     => '',
307
        );
308
    }
309
    else {
310
        $rdf = RDF::Helper->new(
311
            BaseInterface => 'RDF::Trine',
312
            namespaces    => {
313
                rdf     => $rdfNS,
314
                dcterms => $qualified,
315
                dcam    => $dcam,
316
            },
317
            ExpandQNames => 1,
318
            base_uri     => '',
319
        );
320
    }
321
322
    if ( $self->type() eq 'rdf' ) {
323
        $self->dc_order_execution( $dc, $rdf, $subject );
324
    }
325
326
   #Enabling or desabling entities and print the xml, fixing encode with rdfjson
327
    if (   $rdfdescription->{'entities'} == 1
328
        && $rdfdescription->{'rdf_format'} eq 'rdfxml' )
329
    {
330
        my $serialized_data = $rdf->serialize( format => $rdfdescription->{'rdf_format'} );
331
        my ($dcxml_entity_encoded) = XML_entity_encode( $serialized_data );
332
        $serialized_data = $dcxml_entity_encoded;
333
        return $serialized_data;
334
    }
335
    elsif ( $rdfdescription->{'rdf_format'} eq 'rdfjson' ) {
336
        my $encoding =
337
          $rdf->serialize( format => $rdfdescription->{'rdf_format'} );
338
        my $enc = Encode::find_encoding('iso-8859-1');
339
        Encode::is_utf8 ( $encoding ) ? $encoding : $enc->decode ( $encoding );
340
        return $encoding;
341
    }
342
    else {
343
        return $rdf->serialize( format => $rdfdescription->{'rdf_format'} );
344
    }
345
}
346
347
sub upper_or_lowercase {
348
349
#This subroutine define if is necessary to convert lowercase some qualifiers or let them as crosswalk method basis
350
#USAGE: upper_or_lowercase (element->qualifier())
351
    my $dcelement = $_[0];
352
    my $count     = 0;
353
    my $result;
354
    while ( $count <= $#elementupcase ) {
355
        if ( $elementupcase[$count] eq $dcelement ) {
356
            $result = $dcelement;
357
            last;
358
        }
359
        elsif ( $dcelement ne $elementupcase[$count] ) {
360
            $result = lc($dcelement);
361
            $count++;
362
            next;
363
        }
364
    }
365
366
    return $result;
367
368
}
369
370
sub XML_entity_encode {
371
372
#This subroutine change characteres to XML entities. Since XML::LibXML only encode the five basics
373
#USAGE: This subroutine is called when get_xml_data is populated with entities => 1
374
    my @strings = @_;
375
    my @strings_entity_encoded;
376
    foreach my $string (@strings) {
377
        utf8::decode($string);
378
        my $html_entities =
379
          HTML::Entities::encode_entities( $string, '^\n\t\x20-\x26\x28-\x7e' );
380
        my $xml_entities = XML::Entities::numify( 'all', $html_entities );
381
        push @strings_entity_encoded, $xml_entities;
382
    }
383
    return @strings_entity_encoded;
384
}
385
386
sub xml_constructor {
387
388
#xml_constructor ( doc, root, namespace, attr, element_name, element_content, element_qualifier, element_scheme )
389
#USAGE: define all posible elements (name, content, qualifier, scheme) as neccesary
390
#doc: the XML object
391
#root: append root to doc
392
#namespace: defined as "dc" or "dcterms"
393
#attr: a boolean value to determinate xsi:type xml namespace for dcterms
394
#examples:
395
#xml_constructor ( $dcxml, $root, "dc", 0, element->name(), element->content() );
396
#xml_constructor ( $dcxml, $root, "dcterms", 1, element->name(), element->content(), $element->qualifier() );
397
398
    my ( $doc, $root, $namespace, $attr, $element_name, $element_content,
399
        $element_qualifier, $element_scheme )
400
      = @_;
401
402
    # This scalar is used for deleting spaces in scheme elements
403
    my $deletespaces;
404
405
    # This scalar is used for making upper or lowercase the qualifier elements
406
    my $lowercase;
407
    my $tagxml;
408
409
    given ($namespace) {
410
        when ( $namespace eq "dc" ) {
411
            $lowercase = lc($element_name);
412
        }
413
        when ( $namespace eq "dcterms" ) {
414
            $lowercase = upper_or_lowercase($element_qualifier);
415
416
            #replacing spacial to spatial, bug from dublin or crosswalk.
417
            $lowercase =~ s/spacial/spatial/;
418
        }
419
    }
420
421
    if ( ( $namespace eq "dc" or "dcterms" ) and $attr == 0 ) {
422
423
        # This will do something like: <dc:title>Title</dc:title>
424
        $tagxml = XML::LibXML::Element->new($lowercase);
425
        $tagxml->setNamespace( undef, $namespace, 1 );
426
        $tagxml->appendTextNode($element_content);
427
        $root->appendChild($tagxml);
428
    }
429
    elsif ( ( $namespace eq "dcterms" ) and $attr == 1 ) {
430
431
# This will do something like: <dcterms:spatial xsi:type="dcterms:ISO3166">us</dcterms:spatial>
432
        $deletespaces = $element_scheme;
433
        $deletespaces =~ s/\s//;
434
        $tagxml = XML::LibXML::Element->new($lowercase);
435
        $tagxml->setNamespace( undef, $namespace, 1 );
436
        my $attribute = $namespace . ':' . $deletespaces;
437
        $tagxml->setAttribute( 'xsi:type', $attribute );
438
        $tagxml->appendTextNode($element_content);
439
        $root->appendChild($tagxml);
440
    }
441
    elsif ( ( $namespace eq "dc" ) and $attr == 1 ) {
442
        given ($element_scheme) {
443
444
# This will do something like: <dc:subject xsi:type="dcterms:LCSH">Water supply.</dc:subject>
445
            when ( $element_scheme ne "DCMI Type Vocabulary" )
446
            {    #Dublin core returns DCMI Type Vocabulary
447
                $deletespaces = $element_scheme;
448
                $deletespaces =~ s/\s//;
449
                $tagxml = XML::LibXML::Element->new($lowercase);
450
                $tagxml->setNamespace( undef, $namespace, 1 );
451
                my $attribute = 'dcterms:' . $deletespaces;
452
                $tagxml->setAttribute( 'xsi:type', $attribute );
453
                $tagxml->appendTextNode($element_content);
454
                $root->appendChild($tagxml);
455
            }
456
            when ( $element_scheme eq "DCMI Type Vocabulary" )
457
            {    #Changing for DCMIType
458
                 # This will do something like: <dc:type xsi:type="dcterms:DCMIType">Text</dc:type>
459
                $tagxml = XML::LibXML::Element->new($lowercase);
460
                $tagxml->setNamespace( undef, $namespace, 1 );
461
                $tagxml->setAttribute( 'xsi:type', 'dcterms:DCMIType' );
462
                $tagxml->appendTextNode($element_content);
463
                $root->appendChild($tagxml);
464
            }
465
        }
466
    }    #if...elsif
467
468
    return $tagxml;
469
470
}    #subroutine
471
472
sub rdf_constructor {
473
474
#xml_constructor ( rdf, subject, namespace, attr, element_name, element_content, element_qualifier, element_scheme )
475
#USAGE: define all posible elements (name, content, qualifier, scheme) as neccesary
476
#rdf: the RDF object
477
#subject: the subject for the triples
478
#namespace: defined as "dc" or "dcterms". This is for Simple DC or DC-RDF recommendations.
479
#attr: a boolean value to determine the nodeID attribute for dcterms
480
481
    my ( $rdf, $subject, $namespace, $attr, $element_name, $element_content,
482
        $element_qualifier, $element_scheme )
483
      = @_;
484
485
    #This scalar is used for deleting spaces in scheme elements
486
    my $deletespaces;
487
488
    #This scalar is used for making upper or lowercase the qualifier elements
489
    my $lowercase;
490
491
    given ($namespace) {
492
        when ( $namespace eq "dc" ) {
493
            $lowercase = lc($element_name);
494
        }
495
        when ( $namespace eq "dcterms" ) {
496
            $lowercase = upper_or_lowercase($element_qualifier);
497
498
            #replacing spacial to spatial, bug from dublin or crosswalk.
499
            $lowercase =~ s/spacial/spatial/;
500
        }
501
    }
502
503
    if ( ( $namespace eq "dc" or "dcterms" ) and $attr == 0 ) {
504
505
        # This will do something like: <dc:title>Title</dc:title>
506
        my $predicate = $namespace . ':' . $lowercase;
507
        my $object    = $element_content;
508
        $rdf->assert_literal( $subject, $predicate, $object );
509
    }
510
    elsif ( ( $namespace eq "dc" ) and $attr == 2 ) {
511
512
        # This will do something like: <dcterms:title>Title</dcterms:title>
513
        my $predicate = 'dcterms:' . $lowercase;
514
        my $object    = $element_content;
515
        $rdf->assert_literal( $subject, $predicate, $object );
516
    }
517
    elsif ( ( $namespace eq "dc" ) and $attr == 1 ) {
518
        $deletespaces = $element_scheme;
519
        $deletespaces =~ s/\s//;
520
        my $predicate = 'dcterms:' . $lowercase;
521
        my $object    = $element_content;
522
        SWITCH:
523
        for ($element_scheme) {
524
            if ( /^ISO 3166/ ) {
525
526
              #  Dublin core returns DCMI Type Vocabulary
527
              #  This will do something like:
528
              #    <rdf:Description rdf:nodeID="country">
529
              #        <dcam:memberOf rdf:resource="http://purl.org/dc/terms/ISO3166"/>
530
              #        <rdf:value>us</rdf:value>
531
              #    </rdf:Description>
532
              #    <dcterms:spatial rdf:nodeID="country"/>
533
                my $bnode        = $rdf->new_bnode("country");
534
                my $uri_resource = join "", $qualified, $deletespaces;
535
                my $resource     = $rdf->new_resource($uri_resource);
536
                $rdf->assert_literal( $subject, $predicate,      $bnode );
537
                $rdf->assert_literal( $bnode,   'dcam:memberOf', $resource );
538
                $rdf->assert_literal( $bnode,   'rdf:value',     $object );
539
                last SWITCH;
540
            }
541
            if ( /^DCMI Type Vocabulary/ )
542
            {    #Changing for DCMIType
543
                my $bnode        = $rdf->new_bnode('DCMIType');
544
                my $uri_resource = $qualified . 'DCMIType';
545
                my $resource     = $rdf->new_resource($uri_resource);
546
                $rdf->assert_literal( $subject, $predicate,      $bnode );
547
                $rdf->assert_literal( $bnode,   'dcam:memberOf', $resource );
548
                $rdf->assert_literal( $bnode,   'rdf:value',     $object );
549
                last SWITCH;
550
            }
551
            if ( /^ISO 639-2/ )
552
            {    #Changing bnodeId ISO639-2 for language
553
                my $bnode        = $rdf->new_bnode('language');
554
                my $uri_resource = join "", $qualified, $deletespaces;
555
                my $resource     = $rdf->new_resource($uri_resource);
556
                $rdf->assert_literal( $subject, $predicate,      $bnode );
557
                $rdf->assert_literal( $bnode,   'dcam:memberOf', $resource );
558
                $rdf->assert_literal( $bnode,   'rdf:value',     $object );
559
                last SWITCH;
560
            }
561
            if ( /^RFC 1766/ )
562
            {    #Changing bnodeId RFC1766 for languagetag
563
                my $bnode        = $rdf->new_bnode('languagetag');
564
                my $uri_resource = join "", $qualified, $deletespaces;
565
                my $resource     = $rdf->new_resource($uri_resource);
566
                $rdf->assert_literal( $subject, $predicate,      $bnode );
567
                $rdf->assert_literal( $bnode,   'dcam:memberOf', $resource );
568
                $rdf->assert_literal( $bnode,   'rdf:value',     $object );
569
                last SWITCH;
570
            }
571
            if ( /^LCSH/ || /^MeSH/ || /^LCC/ || /^DDC/ ||
572
                 /^UDC/ || /^IMT/ || /^URI/ || /^TGN/ )
573
            {    #Scheme sharing common elements
574
                my $bnode        = $rdf->new_bnode($deletespaces);
575
                my $uri_resource = join "", $qualified, $deletespaces;
576
                my $resource     = $rdf->new_resource($uri_resource);
577
                $rdf->assert_literal( $subject, $predicate,      $bnode );
578
                $rdf->assert_literal( $bnode,   'dcam:memberOf', $resource );
579
                $rdf->assert_literal( $bnode,   'rdf:value',     $object );
580
                last SWITCH;
581
            }
582
        }
583
    }    #if-elsif
584
    return $rdf;
585
}    #subroutine
586
587
sub dc_order_execution {
588
589
    #USAGE: USAGE: Get the parameters for xml or rdf and execute in order.
590
    my $self = shift;
591
592
    if ( $self->type() eq 'xml' ) {    #Order for xml
593
        my ( $dc, $dcxml, $root ) = @_;
594
        foreach my $element ( $dc->elements() ) {
595
          SWITCH: {
596
                if (    $element->name()
597
                    and not defined $element->scheme()
598
                    and not defined $element->qualifier() )
599
                {
600
                    $dcxml =
601
                      xml_constructor( $dcxml, $root, "dc", 0, $element->name(),
602
                        $element->content() );
603
                    last SWITCH;
604
                }
605
606
                if (    $element->name()
607
                    and not defined $element->scheme()
608
                    and not defined $element->qualifier() )
609
                {
610
                    $dcxml =
611
                      xml_constructor( $dcxml, $root, "dcterms", 0,
612
                        $element->name(), $element->content() );
613
                    last SWITCH;
614
                }
615
616
                if (    $element->name()
617
                    and $element->scheme()
618
                    and $element->qualifier() )
619
                {
620
                    $dcxml = xml_constructor(
621
                        $dcxml,                $root,
622
                        "dcterms",             1,
623
                        $element->name(),      $element->content(),
624
                        $element->qualifier(), $element->scheme()
625
                    );
626
                    last SWITCH;
627
                }
628
629
                if (    $element->name()
630
                    and $element->scheme()
631
                    and ( $element->scheme ne "DCMI Type Vocabulary" ) )
632
                {
633
                    $dcxml =
634
                      xml_constructor( $dcxml, $root, "dc", 1, $element->name(),
635
                        $element->content(), $element->qualifier(),
636
                        $element->scheme() );
637
                    last SWITCH;
638
                }
639
640
                if (    $element->name()
641
                    and $element->scheme()
642
                    and ( $element->scheme() eq "DCMI Type Vocabulary" ) )
643
                {
644
                    $dcxml =
645
                      xml_constructor( $dcxml, $root, "dc", 1, $element->name(),
646
                        $element->content(), $element->qualifier(),
647
                        $element->scheme() );
648
                    last SWITCH;
649
                }
650
651
                if ( $element->name() and $element->qualifier() ) {
652
                    $dcxml = xml_constructor(
653
                        $dcxml,                $root,
654
                        "dcterms",             0,
655
                        $element->name(),      $element->content(),
656
                        $element->qualifier(), $element->scheme()
657
                    );
658
                    last SWITCH;
659
                }    #if
660
            }    #SWITCH
661
        }    #foreach 1
662
    }
663
    elsif ( $self->type() eq 'rdf' ) {    #Order for rdf/xml
664
        my ( $dc, $rdf, $subject ) = @_;
665
        foreach my $element ( $dc->elements() ) {
666
          SWITCH: {
667
                if (    $element->name()
668
                    and not defined $element->scheme()
669
                    and not defined $element->qualifier() )
670
                {
671
                    rdf_constructor( $rdf, $subject, "dc", 0, $element->name(),
672
                        $element->content() )
673
                      unless $self->qualified() == 1;
674
                    rdf_constructor( $rdf, $subject, "dc", 2, $element->name(),
675
                        $element->content() )
676
                      unless $self->qualified() == 0;
677
                    last SWITCH;
678
                }
679
680
                if (    $element->name()
681
                    and $element->scheme()
682
                    and ( $element->scheme ne "DCMI Type Vocabulary" ) )
683
                {
684
                    rdf_constructor( $rdf, $subject, "dc", 1, $element->name(),
685
                        $element->content(), $element->qualifier(),
686
                        $element->scheme() );
687
                    last SWITCH;
688
                }
689
690
                if (    $element->name()
691
                    and $element->scheme()
692
                    and ( $element->scheme() eq "DCMI Type Vocabulary" ) )
693
                {
694
                    rdf_constructor( $rdf, $subject, "dc", 1, $element->name(),
695
                        $element->content(), $element->qualifier(),
696
                        $element->scheme() );
697
                    last SWITCH;
698
                }
699
700
                if ( $element->name() and $element->qualifier() ) {
701
                    rdf_constructor(
702
                        $rdf,                  $subject,
703
                        "dcterms",             0,
704
                        $element->name(),      $element->content(),
705
                        $element->qualifier(), $element->scheme()
706
                    );
707
                    last SWITCH;
708
                }    #if
709
            }    #SWITCH
710
        }    #foreach 2
711
    }
712
    return;
713
}
714
715
END {
716
717
    #When opened with MARC::File::USMARC, close marc record if not closed
718
    sub DESTROY {
719
        my $self = shift;
720
        if ( $self->{get_marc_record} =~ /^MARC:File::USMARC/ ) {
721
            $self->{get_marc_record}->close();
722
            undef $self->{get_marc_record};
723
        }
724
    }
725
}
726
1;
727
__END__
728
729
=pod
730
731
=encoding UTF-8
732
733
=head1 NAME
734
735
Koha::DublinCoreTransformer - transform the values of MARC::Crosswalk::DublinCore
736
into metadata in XML or RDF format.
737
738
=head1 SYNOPSIS
739
740
=head2 XML-DC
741
742
  use Koha::DublinCoreTransformer;
743
  use MARC::File::USMARC;
744
  my $batch = MARC::File::USMARC->in('in.mrc');
745
746
  ## the $record will be a MARC::Record object.
747
  my $record = $batch->next();
748
749
  #For Simple DC-XML
750
  my $objectDC = DublinCoreTransformer->new({
751
        type => 'xml',
752
        qualified => 0,
753
        get_marc_record => $record});
754
755
  #For Qualified DC-XML
756
  my $objectDC = DublinCoreTransformer->new({
757
        type => 'xml',
758
        qualified => 1,
759
        get_marc_record => $record});
760
761
  #After call constructor you need to pass the root element and
762
  #the schema in .xsd format. If you prefer or you don't know nothing
763
  #about it pass the method in blank, i.e., without arguments.
764
  #Also you can determine if you want to encode with xml entities or
765
  #just with the five basics entities.
766
  #Set entities to 0 for the five basics or 1 to encode with the
767
  #complete xml entities.
768
  $objectDC->get_xml_data({
769
        root => 'metadata',
770
        xsi_schemaLocation => 'http://example.org/myapp/ http://example.org/myapp/schema.xsd',
771
  });
772
  #This print your xml file in STDOUT
773
  my $XML-DC = $objectDC->write_xml();
774
  print $XML-DC;
775
776
  #Close the file according to MARC::File::USMARC
777
  $batch->close();
778
  undef $batch;
779
780
  #Or if you want to generate a file
781
  open (OUTPUT, '> dc2xml.xml') or die $!;
782
  print OUTPUT $XML-DC;
783
  close(OUTPUT);
784
785
=head2 DC-RDF
786
787
  use Koha::DublinCoreTransformer;
788
  use MARC::File::USMARC;
789
  my $marc = MARC::File::USMARC->in('in.mrc');
790
  my $record = $marc->next();
791
792
  #Simple DC-RDF is not used but not deprecated, DublinCoreTransformer
793
  #can generate it as follow:
794
  my $objectDC = DublinCoreTransformer->new({
795
        type => 'rdf',
796
        qualified => 0,
797
        get_marc_record => $record});
798
799
  #DC-RDF
800
  my $objectDC = DublinCoreTransformer->new({
801
        type => 'rdf',
802
        qualified => 1,
803
        get_marc_record => $record});
804
805
  #The get_rdf_data method for RDF does not need to use the root element
806
  #and the schema, but you need to declare the resource being described,
807
  #i.e., the record.
808
  #Note: For Koha is the IRI identifier of the record
809
  $objectDC->get_rdf_data({
810
        rdf_subject => 'http://opac.mydomain.edu/cgi-bin/koha/opac-detail.pl?biblionumber=17589',
811
  });
812
813
  my $XML-RDF = $objectDC->write_rdf();
814
  print $XML-RDF;
815
  #Close the file according to MARC::File::USMARC
816
  $batch->close();
817
  undef $marc;
818
819
=head1 DESCRIPTION
820
821
The Koha::DublinCoreTransformer defines the interface to transform
822
and manipulate MARC records into DC-XML or DC-RDF recommendation.
823
This package transform MARC records to XML or RDF/XML Dublin Core
824
and follows the recommendations listed below:
825
826
L<DC-XML-GUIDELINES [DCMI Recommendation]|http://dublincore.org/documents/dc-xml-guidelines/>
827
828
L<Expressing Simple Dublin Core in RDF-XML|http://dublincore.org/documents/dcmes-xml/>
829
This recommendation is superseded by DC-RDFrecommendation but not obsoleted at all.
830
831
L<DC-RDF [DCMI Recommendation]|http://dublincore.org/documents/dc-rdf/>
832
833
=head2 Methods
834
835
=over 12
836
837
=item C<new>
838
839
Return a new Koha::DublinCoreTransformer object.
840
This constructor sets the output type (RDF or XML), the level of the standard (Simple DC or Qualified DC) and the MARC record to be transformed to DC.
841
842
  my $objectDC = DublinCoreTransformer->new({
843
        type => 'rdf',
844
        qualified => 0,
845
        get_marc_record => $record});
846
847
=item C<get_xml_data>
848
849
This method is just for DC-XML: Fetch the xml root element and the schema in .xsd format.
850
851
  $objectDC->get_xml_data({
852
        root => 'metadata',
853
        xsi_schemaLocation => 'http://example.org/myapp/ http://example.org/myapp/schema.xsd',
854
        entities => 1,
855
  });
856
857
The entities argument is for extended xml entities, i.e., placing entities to zero will codify only the five basic entities e.g., &lt, &gt, &quot, &amp, and &apos. Conversely if it is encoded to one, all entities will coded into decimal.
858
859
Additionally, has been included the optional_namespace and namespace_url arguments to include another XML name space.
860
861
NOTE: This method is only for use of the DC-XML recommendation, i.e., type => 'xml'.
862
See C<new> method or the section SYNOPSIS.
863
864
=item C<get_rdf_data>
865
866
This method is only for DC-RDF: Fetch the IRI identifier of the resource being described. As well, you can pass the format you want to generate with the rdf, by default the DC-RDF specify RDF/XML but RDF can represent in other formats listed below:
867
868
. ntriples
869
870
. nquads
871
872
. rdfxml
873
874
. rdfjson
875
876
. ntriples-canonical
877
878
. turtle
879
880
    $objectDC->get_rdf_data({
881
        rdf_subject => 'http://opac.fmoues.edu.sv/cgi-bin/koha/opac-detail.pl?biblionumber=17589',
882
        rdf_format => 'rdfxml',
883
        entities => 0|1,
884
    });
885
886
NOTE: The entities is needed only for rdfxml value and is used like C<get_xml_data> method.
887
888
=item C<write_xml>
889
890
Return the xml object as string.
891
892
NOTE: This method is only for use of the DC-XML recommendation, i.e., type => 'xml'.
893
See C<new> and C<get_xml_data> methods or the section SYNOPSIS.
894
895
=item C<write_rdf>
896
897
Return the rdf object as string.
898
899
NOTE: This method is only for use of the DC-RDF recommendation, i.e., type => 'rdf'.
900
See C<new> and C<get_rdf_data> methods or the section SYNOPSIS.
901
902
=back
903
904
=head1 VERSION
905
906
version 0.01
907
908
=head1 RELATES MODULES
909
910
This package requires the following modules:
911
912
DublinCore::Record
913
914
MARC::Record
915
916
MARC::File::USMARC
917
918
MARC::Crosswalk::DublinCore
919
920
HTML::Entities
921
922
XML::Entities
923
924
XML::LibXML
925
926
RDF::Helper
927
928
=head2 SEE ALSO
929
930
Dublin Core Web Page L<http://dublincore.org>.
931
932
=head1 LICENSE
933
934
Copyright (c) 2014 Koha Community. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
935
936
=head1 AUTHOR
937
938
Hector Eduardo Catro Avalos E<lt> hector.hecaxmmx at gmail dot com E<gt>
939
and the Koha Development Team.
940
941
=cut
942
(-)a/catalogue/export.pl (-2 / +28 lines)
Lines 26-31 my $format=$query->param("format"); Link Here
26
my $error = '';
26
my $error = '';
27
if ($op eq "export") {
27
if ($op eq "export") {
28
    my $biblionumber = $query->param("bib");
28
    my $biblionumber = $query->param("bib");
29
    my $recommendation = $query->param("recommendation");
30
    my $formats = $query->param("formats");
31
    my $qualifier = $query->param("qualifier");
32
    my $root_element = $query->param("root_element");
33
    my $xsischemalocation = $query->param("xsischemalocation");
34
    my $resource_url = $query->url(-base => 1) . '/cgi-bin/koha/catalogue/detail.pl?biblionumber=' . $biblionumber;
29
        if ($biblionumber){
35
        if ($biblionumber){
30
36
31
            my $marc = GetMarcBiblio($biblionumber, 1);
37
            my $marc = GetMarcBiblio($biblionumber, 1);
Lines 51-58 if ($op eq "export") { Link Here
51
                $format = "bibtex";
57
                $format = "bibtex";
52
            }
58
            }
53
            elsif ($format =~ /dc/) {
59
            elsif ($format =~ /dc/) {
54
                ($error,$marc) = marc2dcxml($marc,1);
60
                SWITCH:
55
                $format = "dublin-core.xml";
61
                    for ($recommendation) {
62
                        if (/^simple-dc-rdf/) {
63
                            ($error,$marc) = marc2dcxml($recommendation, $marc, 0,
64
                            1, undef, undef, $resource_url , $formats);
65
                            $format = "dublin-core." . $formats;
66
                            last SWITCH; }
67
                        if (/^dc-rdf/) {
68
                            ($error,$marc) = marc2dcxml($recommendation, $marc, 1,
69
                            1, undef, undef, $resource_url, $formats);
70
                            $format = "dublin-core." . $formats;
71
                            last SWITCH; }
72
                        if (/^dc-xml/) {
73
                            ($error,$marc) = marc2dcxml($recommendation, $marc, $qualifier,
74
                            1, $root_element, $xsischemalocation, undef, undef);
75
                            $format = "dublin-core.xml";
76
                            last SWITCH; }
77
                        if (/^oai-dc/) {
78
                            ($error,$marc) = marc2dcxml($recommendation, $marc);
79
                            $format = "dublin-core.xml";
80
                            last SWITCH; }
81
                    }
56
            }
82
            }
57
            elsif ($format =~ /marc8/) {
83
            elsif ($format =~ /marc8/) {
58
                $marc = changeEncoding($marc,"MARC","MARC21","MARC-8");
84
                $marc = changeEncoding($marc,"MARC","MARC21","MARC-8");
(-)a/debian/control (-2 / +6 lines)
Lines 47-53 Build-Depends: libalgorithm-checkdigits-perl, Link Here
47
 libdigest-sha-perl | perl,
47
 libdigest-sha-perl | perl,
48
 libemail-date-perl,
48
 libemail-date-perl,
49
 libemail-valid-perl,
49
 libemail-valid-perl,
50
 libfile-path-perl | perl-modules,
51
 libfile-slurp-perl,
50
 libfile-slurp-perl,
52
 libfont-ttf-perl,
51
 libfont-ttf-perl,
53
 libgd-barcode-perl,
52
 libgd-barcode-perl,
Lines 56-61 Build-Depends: libalgorithm-checkdigits-perl, Link Here
56
 libgravatar-url-perl,
55
 libgravatar-url-perl,
57
 libhtml-format-perl,
56
 libhtml-format-perl,
58
 libhtml-scrubber-perl,
57
 libhtml-scrubber-perl,
58
 libhttp-cookies-perl,
59
 libhttp-message-perl,
59
 libhttp-oai-perl,
60
 libhttp-oai-perl,
60
 libjson-perl,
61
 libjson-perl,
61
 liblibrary-callnumber-lc-perl,
62
 liblibrary-callnumber-lc-perl,
Lines 97-102 Build-Depends: libalgorithm-checkdigits-perl, Link Here
97
 libtemplate-plugin-htmltotext-perl,
98
 libtemplate-plugin-htmltotext-perl,
98
 libtemplate-plugin-json-escape-perl,
99
 libtemplate-plugin-json-escape-perl,
99
 libtest-deep-perl,
100
 libtest-deep-perl,
101
 libtest-harness-perl | perl-modules,
100
 libtest-mockmodule-perl,
102
 libtest-mockmodule-perl,
101
 libtest-mockobject-perl,
103
 libtest-mockobject-perl,
102
 libtest-simple-perl | perl-modules,
104
 libtest-simple-perl | perl-modules,
Lines 245-251 Depends: libalgorithm-checkdigits-perl, Link Here
245
 libdigest-sha-perl | perl,
247
 libdigest-sha-perl | perl,
246
 libemail-date-perl,
248
 libemail-date-perl,
247
 libemail-valid-perl,
249
 libemail-valid-perl,
248
 libfile-path-perl | perl-modules,
249
 libfile-slurp-perl,
250
 libfile-slurp-perl,
250
 libfont-ttf-perl,
251
 libfont-ttf-perl,
251
 libgd-barcode-perl,
252
 libgd-barcode-perl,
Lines 254-259 Depends: libalgorithm-checkdigits-perl, Link Here
254
 libgravatar-url-perl,
255
 libgravatar-url-perl,
255
 libhtml-format-perl,
256
 libhtml-format-perl,
256
 libhtml-scrubber-perl,
257
 libhtml-scrubber-perl,
258
 libhttp-cookies-perl,
259
 libhttp-message-perl,
257
 libhttp-oai-perl,
260
 libhttp-oai-perl,
258
 libjson-perl,
261
 libjson-perl,
259
 liblibrary-callnumber-lc-perl,
262
 liblibrary-callnumber-lc-perl,
Lines 295-300 Depends: libalgorithm-checkdigits-perl, Link Here
295
 libtemplate-plugin-htmltotext-perl,
298
 libtemplate-plugin-htmltotext-perl,
296
 libtemplate-plugin-json-escape-perl,
299
 libtemplate-plugin-json-escape-perl,
297
 libtest-deep-perl,
300
 libtest-deep-perl,
301
 libtest-harness-perl | perl-modules,
298
 libtest-mockmodule-perl,
302
 libtest-mockmodule-perl,
299
 libtest-mockobject-perl,
303
 libtest-mockobject-perl,
300
 libtest-simple-perl | perl-modules,
304
 libtest-simple-perl | perl-modules,
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc (-1 / +1 lines)
Lines 219-225 CAN_user_serials_create_subscription ) %] Link Here
219
    <button class="btn btn-small dropdown-toggle" data-toggle="dropdown"><i class="icon-download-alt"></i> Save <span class="caret"></span></button>
219
    <button class="btn btn-small dropdown-toggle" data-toggle="dropdown"><i class="icon-download-alt"></i> Save <span class="caret"></span></button>
220
    <ul class="dropdown-menu">
220
    <ul class="dropdown-menu">
221
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=bibtex&amp;op=export&amp;bib=[% biblionumber %]">BIBTEX</a></li>
221
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=bibtex&amp;op=export&amp;bib=[% biblionumber %]">BIBTEX</a></li>
222
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=dc&amp;op=export&amp;bib=[% biblionumber %]">Dublin Core (XML)</a></li>
222
        <li><a href="#" data-toggle="modal" data-target="#exportModal_">Dublin Core</a></li>
223
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=marcxml&amp;op=export&amp;bib=[% biblionumber %]">MARCXML</a></li>
223
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=marcxml&amp;op=export&amp;bib=[% biblionumber %]">MARCXML</a></li>
224
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=marc8&amp;op=export&amp;bib=[% biblionumber %]">MARC (non-Unicode/MARC-8)</a></li>
224
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=marc8&amp;op=export&amp;bib=[% biblionumber %]">MARC (non-Unicode/MARC-8)</a></li>
225
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=utf8&amp;op=export&amp;bib=[% biblionumber %]">MARC (Unicode/UTF-8)</a></li>
225
        <li><a href="/cgi-bin/koha/catalogue/export.pl?format=utf8&amp;op=export&amp;bib=[% biblionumber %]">MARC (Unicode/UTF-8)</a></li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt (-1 / +129 lines)
Lines 297-302 function verify_images() { Link Here
297
297
298
        [% END %]
298
        [% END %]
299
    });
299
    });
300
301
    //JQuery for Dublin Core Modal
302
    $(document).ready(function(){
303
        $("#input-simple").click(function(){
304
            $(".rdfoptions").removeAttr("disabled");
305
            $(".xmloptions").attr("disabled","disabled");
306
            $("#dc-rdf").toggle();
307
            $("#dc-xml").hide();
308
        });
309
    });
310
311
    $(document).ready(function(){
312
        $("#input-rdf").click(function(){
313
            $(".rdfoptions").removeAttr("disabled");
314
            $(".xmloptions").attr("disabled","disabled");
315
            $("#dc-rdf").toggle();
316
            $("#dc-xml").hide();
317
        });
318
    });
319
320
    $(document).ready(function(){
321
        $("#input-xml").click(function(){
322
            $(".xmloptions").removeAttr("disabled");
323
            $(".rdfoptions").attr("disabled","disabled");
324
                if($("#root_checked").is(':checked')){
325
                    $("#root_value").removeAttr("disabled");
326
                } else {
327
                    $("#root_value").attr("disabled","disabled");
328
                }
329
                if($("#schema_checked").is(':checked')){
330
                    $("#schema_value").removeAttr("disabled");
331
                } else {
332
                    $("#schema_value").attr("disabled","disabled");
333
                }
334
                $("#dc-xml").toggle();
335
                $("#dc-rdf").hide();
336
        });
337
    });
338
339
    $(document).ready(function(){
340
        $("#root_checked").click(function(){
341
            if($("#root_checked").is(':checked')){
342
                $("#root_value").removeAttr("disabled");
343
            } else {
344
                $("#root_value").attr("disabled","disabled");
345
            }
346
        });
347
    });
348
349
    $(document).ready(function(){
350
        $("#schema_checked").click(function(){
351
            if($("#schema_checked").is(':checked')){
352
                $("#schema_value").removeAttr("disabled");
353
            } else {
354
                $("#schema_value").attr("disabled","disabled");
355
            }
356
        });
357
    });
358
359
    $(document).ready(function(){
360
        $("#input-oai").click(function(){
361
            $(".rdfoptions").attr("disabled","disabled");
362
            $(".xmloptions").attr("disabled","disabled");
363
            $("#dc-rdf").hide();
364
            $("#dc-xml").hide();
365
        });
366
    });
367
300
//]]>
368
//]]>
301
</script>
369
</script>
302
</head>
370
</head>
Lines 1003-1009 function verify_images() { Link Here
1003
      <th>Save Record</th>   </tr>
1071
      <th>Save Record</th>   </tr>
1004
    <tr><td> Select download format:    <select name="format">
1072
    <tr><td> Select download format:    <select name="format">
1005
        <option value="mods">MODS (XML)</option>
1073
        <option value="mods">MODS (XML)</option>
1006
        <option value="dc">Dublin Core (XML)</option>
1074
        <option data-toggle="modal" data-target="#exportModal_">Dublin Core</option> <!-- trigger modal -->
1007
        <option value="marcxml">MARCXML</option>
1075
        <option value="marcxml">MARCXML</option>
1008
        <option value="marc8">MARC (non-Unicode/MARC-8)</option>
1076
        <option value="marc8">MARC (non-Unicode/MARC-8)</option>
1009
        <option value="utf8">MARC (Unicode/UTF-8)</option>    </select>
1077
        <option value="utf8">MARC (Unicode/UTF-8)</option>    </select>
Lines 1036-1039 function verify_images() { Link Here
1036
</div>
1104
</div>
1037
[% END %]
1105
[% END %]
1038
</div>
1106
</div>
1107
    <!-- Modal for Dublin Core-->
1108
    <div class="modal hide" id="exportModal_" tabindex="-1" role="dialog" aria-labelledby="exportLabelexportModal_" aria-hidden="true">
1109
        <div class="modal-header">
1110
            <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">&times;</button>
1111
            <h3 id="exportLabelexportModal_">Exporting to Dublin Core...</h3>
1112
        </div>
1113
        <!-- Form to recolect data for Dublin Core-->
1114
        <form method="get" action="/cgi-bin/koha/catalogue/export.pl">
1115
        <div class="modal-body">
1116
            <fieldset>
1117
                <input id="input-simple" type="radio" name="recommendation" value="simple-dc-rdf">Simple DC-RDF
1118
                <br>
1119
                <input id="input-rdf" type="radio" name="recommendation" value="dc-rdf" checked>DC-RDF (Recommended)
1120
                <div id="dc-rdf" style="display:none;">
1121
                    <br>DC-RDF is downloadable in &quot;rdfxml&quot; by default (this is according with the
1122
                    <br>recommendation),  but you can download the file in other formats:
1123
                    <br>
1124
                    <input class="rdfoptions" type="radio" name="formats" value="rdfxml" checked>rdfxml
1125
                    <input class="rdfoptions" type="radio" name="formats" value="rdfjson">rdfjson
1126
                    <input class="rdfoptions" type="radio" name="formats" value="ntriples">ntriples
1127
                    <input class="rdfoptions" type="radio" name="formats" value="nquads">nquads
1128
                    <input class="rdfoptions" type="radio" name="formats" value="ntriples-canonical">ntriples-canonical
1129
                    <input class="rdfoptions" type="radio" name="formats" value="turtle">turtle
1130
                </div>
1131
                <br>
1132
                <input id="input-xml" type="radio" name="recommendation" value="dc-xml">DC-XML
1133
                <div id="dc-xml" style="display:none;">
1134
                    <p><b>Output options for DC-XML</b>
1135
                    <br>
1136
                    <b>Dublin Core level</b></p>
1137
                    <p><input class="xmloptions" type="radio" name="qualifier" value="0" checked disabled>Simple Dublin Core
1138
                    <input class="xmloptions" type="radio" name="qualifier" value="1" disabled>Qualified Dublin Core</p>
1139
                    <b>Other data (Optional)</b>
1140
                    <br>
1141
                    <input id="root_checked" class="xmloptions" type="checkbox" value="root">
1142
                    Root element: <input id="root_value" class="xmloptions" type="text" name="root_element" value="metadata" disabled>
1143
                    <br>The xsischemaLocation should be filled like:
1144
                    <br>http://example.org/myapp/ http://example.org/myapp/schema.xsd
1145
                    <br>
1146
                    <input id="schema_checked" class="xmloptions" type="checkbox" value="schema" disabled>
1147
                    xsischemaLocation: <input id="schema_value" class="xmloptions" type="url" name="xsischemalocation" disabled><br>
1148
                </div>
1149
                <br>
1150
                <input id="input-oai" type="radio" name="recommendation" value="oai-dc">OAI-DC
1151
                <br>
1152
                <div>
1153
                <br>Learn more about DCMI Specifications at: <a href="http://dublincore.org/specifications/">http://dublincore.org/specifications/</a>
1154
                <br>
1155
                </div>
1156
            </fieldset>
1157
        </div>
1158
        <div class="modal-footer">
1159
            <button type="submit" class="btn">Export</button>
1160
            <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
1161
        </div>
1162
        <input type="hidden" name="op" value="export" />
1163
        <input type="hidden" name="format" value="dc" />
1164
        <input type="hidden" name="bib" value="[% biblionumber %]" />
1165
        </form>
1166
    </div>
1039
[% INCLUDE 'intranet-bottom.inc' %]
1167
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc (+64 lines)
Lines 316-318 Link Here
316
            </div>
316
            </div>
317
        </form> <!-- /#auth -->
317
        </form> <!-- /#auth -->
318
    </div>  <!-- /#modalAuth  -->
318
    </div>  <!-- /#modalAuth  -->
319
320
    <!-- Dublin Core Exporter modal form -->
321
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
322
        <div class="modal-dialog">
323
            <div class="modal-content">
324
                <div class="modal-header">
325
                    <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">&times;</button>
326
                    <h4 class="modal-title" id="myModalLabel">Exporting to Dublin Core...</h4>
327
                </div>
328
                <form method="get" action="/cgi-bin/koha/opac-export.pl">
329
                    <div class="modal-body">
330
                        <fieldset>
331
                            <input id="input-simple" type="radio" name="recommendation" value="simple-dc-rdf">Simple DC-RDF
332
                            <br>
333
                            <input id="input-rdf" type="radio" name="recommendation" value="dc-rdf" checked>DC-RDF (Recommended)
334
                            <div id="dc-rdf" style="display:none;">
335
                                <br>DC-RDF is downloadable in &quot;rdfxml&quot; by default (this is according with the
336
                                <br>recommendation),  but you can download the file in other formats:
337
                                <br>
338
                                <input class="rdfoptions" type="radio" name="formats" value="rdfxml" checked>rdfxml
339
                                <input class="rdfoptions" type="radio" name="formats" value="rdfjson">rdfjson
340
                                <input class="rdfoptions" type="radio" name="formats" value="ntriples">ntriples
341
                                <input class="rdfoptions" type="radio" name="formats" value="nquads">nquads
342
                                <input class="rdfoptions" type="radio" name="formats" value="ntriples-canonical">ntriples-canonical
343
                                <input class="rdfoptions" type="radio" name="formats" value="turtle">turtle
344
                            </div>
345
                            <br>
346
                            <input id="input-xml" type="radio" name="recommendation" value="dc-xml">DC-XML
347
                            <div id="dc-xml" style="display:none;">
348
                                <p><b>Output options for DC-XML</b>
349
                                <br>
350
                                <b>Dublin Core level</b></p>
351
                                <p><input class="xmloptions" type="radio" name="qualifier" value="0" checked disabled>Simple Dublin Core
352
                                <input class="xmloptions" type="radio" name="qualifier" value="1" disabled>Qualified Dublin Core</p>
353
                                <b>Other data (Optional)</b>
354
                                <br>
355
                                <input id="root_checked" class="xmloptions" type="checkbox" value="root">
356
                                Root element: <input id="root_value" class="xmloptions" type="text" name="root_element" value="metadata" disabled>
357
                                <br>The xsischemaLocation should be filled like:
358
                                <br>http://example.org/myapp/ http://example.org/myapp/schema.xsd
359
                                <br>
360
                                <input id="schema_checked" class="xmloptions" type="checkbox" value="schema" disabled>
361
                                xsischemaLocation: <input id="schema_value" class="xmloptions" type="url" name="xsischemalocation" disabled><br>
362
                            </div>
363
                            <br>
364
                            <input id="input-oai" type="radio" name="recommendation" value="oai-dc">OAI-DC
365
                            <br>
366
                            <div>
367
                                <br>Learn more about DCMI Specifications at: <a href="http://dublincore.org/specifications/">http://dublincore.org/specifications/</a>
368
                                <br>
369
                            </div>
370
                        </fieldset>
371
                    </div>
372
                    <div class="modal-footer">
373
                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
374
                        <button type="submit" class="btn btn-primary">Export</button>
375
                    </div>
376
                    <input type="hidden" name="op" value="export" />
377
                    <input type="hidden" name="format" value="dc" />
378
                    <input type="hidden" name="bib" value="[% biblionumber %]" />
379
                </form>
380
            </div>
381
        </div>
382
    </div><!-- End modal form -->
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-detail-sidebar.inc (-15 / +18 lines)
Lines 42-62 Link Here
42
                    <a id="format" class="dropdown-toggle" data-toggle="dropdown" href="#">Save record <b class="caret"></b></a>
42
                    <a id="format" class="dropdown-toggle" data-toggle="dropdown" href="#">Save record <b class="caret"></b></a>
43
                        <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="format">
43
                        <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="format">
44
                            [% FOREACH option IN export_options %]
44
                            [% FOREACH option IN export_options %]
45
                                <li>
45
                                [% IF option == 'dc' %]
46
                                    <a role="menuitem" href="/cgi-bin/koha/opac-export.pl?op=export&amp;bib=[% biblionumber %]&amp;format=[% option %]">
46
                                    <li><a role="menuitem" href="#" data-toggle="modal" data-target="#myModal">Dublin Core</a></li>
47
                                        [% SWITCH option %]
47
                                [% ELSE %]
48
                                            [% CASE 'bibtex' %]BIBTEX
48
                                    <li>
49
                                            [% CASE 'dc' %]Dublin Core (XML)
49
                                        <a role="menuitem" href="/cgi-bin/koha/opac-export.pl?op=export&amp;bib=[% biblionumber %]&amp;format=[% option %]">
50
                                            [% CASE 'endnote' %]EndNote
50
                                            [% SWITCH option %]
51
                                            [% CASE 'marcxml' %]MARCXML
51
                                                [% CASE 'bibtex' %]BIBTEX
52
                                            [% CASE 'marc8' %]MARC (non-Unicode/MARC-8)
52
                                                [% CASE 'endnote' %]EndNote
53
                                            [% CASE 'utf8' %]MARC (Unicode/UTF-8)
53
                                                [% CASE 'marcxml' %]MARCXML
54
                                            [% CASE 'marcstd' %]MARC (Unicode/UTF-8, Standard)
54
                                                [% CASE 'marc8' %]MARC (non-Unicode/MARC-8)
55
                                            [% CASE 'mods' %]MODS (XML)
55
                                                [% CASE 'utf8' %]MARC (Unicode/UTF-8)
56
                                            [% CASE 'ris' %]RIS
56
                                                [% CASE 'marcstd' %]MARC (Unicode/UTF-8, Standard)
57
                                        [% END %]
57
                                                [% CASE 'mods' %]MODS (XML)
58
                                    </a>
58
                                                [% CASE 'ris' %]RIS
59
                                </li>
59
                                            [% END %]
60
                                        </a>
61
                                    </li>
62
                                [% END %]
60
                            [% END %]
63
                            [% END %]
61
                        </ul>
64
                        </ul>
62
                </div>
65
                </div>
(-)a/koha-tmpl/opac-tmpl/bootstrap/js/script.js (-1 / +68 lines)
Lines 63-66 $(document).ready(function(){ Link Here
63
            $("#members").removeAttr("style");
63
            $("#members").removeAttr("style");
64
        }
64
        }
65
    });
65
    });
66
});
66
});
67
68
    //JQuery for Dublin Core Modal
69
    $(document).ready(function(){
70
        $("#input-simple").click(function(){
71
            $(".rdfoptions").removeAttr("disabled");
72
            $(".xmloptions").attr("disabled","disabled");
73
            $("#dc-rdf").toggle();
74
            $("#dc-xml").hide();
75
        });
76
    });
77
78
    $(document).ready(function(){
79
        $("#input-rdf").click(function(){
80
            $(".rdfoptions").removeAttr("disabled");
81
            $(".xmloptions").attr("disabled","disabled");
82
            $("#dc-rdf").toggle();
83
            $("#dc-xml").hide();
84
        });
85
    });
86
87
    $(document).ready(function(){
88
        $("#input-xml").click(function(){
89
            $(".xmloptions").removeAttr("disabled");
90
            $(".rdfoptions").attr("disabled","disabled");
91
                if($("#root_checked").is(':checked')){
92
                    $("#root_value").removeAttr("disabled");
93
                } else {
94
                    $("#root_value").attr("disabled","disabled");
95
                }
96
                if($("#schema_checked").is(':checked')){
97
                    $("#schema_value").removeAttr("disabled");
98
                } else {
99
                    $("#schema_value").attr("disabled","disabled");
100
                }
101
                $("#dc-xml").toggle();
102
                $("#dc-rdf").hide();
103
        });
104
    });
105
106
    $(document).ready(function(){
107
        $("#root_checked").click(function(){
108
            if($("#root_checked").is(':checked')){
109
                $("#root_value").removeAttr("disabled");
110
            } else {
111
                $("#root_value").attr("disabled","disabled");
112
            }
113
        });
114
    });
115
116
    $(document).ready(function(){
117
        $("#schema_checked").click(function(){
118
            if($("#schema_checked").is(':checked')){
119
                $("#schema_value").removeAttr("disabled");
120
            } else {
121
                $("#schema_value").attr("disabled","disabled");
122
            }
123
        });
124
    });
125
126
    $(document).ready(function(){
127
        $("#input-oai").click(function(){
128
            $(".rdfoptions").attr("disabled","disabled");
129
            $(".xmloptions").attr("disabled","disabled");
130
            $("#dc-rdf").hide();
131
            $("#dc-xml").hide();
132
        });
133
    });
(-)a/opac/opac-export.pl (-3 / +28 lines)
Lines 34-39 my $format=$query->param("format")||'utf8'; Link Here
34
my $biblionumber = $query->param("bib")||0;
34
my $biblionumber = $query->param("bib")||0;
35
$biblionumber = int($biblionumber);
35
$biblionumber = int($biblionumber);
36
my ($marc, $error)= ('','');
36
my ($marc, $error)= ('','');
37
my $recommendation = $query->param("recommendation");
38
my $formats = $query->param("formats");
39
my $qualifier = $query->param("qualifier");
40
my $root_element = $query->param("root_element");
41
my $xsischemalocation = $query->param("xsischemalocation");
42
my $resource_url = $query->url(-base => 1) . '/cgi-bin/koha/opac-detail.pl?biblionumber=' . $biblionumber;
37
43
38
$marc = GetMarcBiblio($biblionumber, 1) if $biblionumber;
44
$marc = GetMarcBiblio($biblionumber, 1) if $biblionumber;
39
if(!$marc) {
45
if(!$marc) {
Lines 61-68 elsif ($format =~ /bibtex/) { Link Here
61
    $format = 'bibtex';
67
    $format = 'bibtex';
62
}
68
}
63
elsif ($format =~ /dc/) {
69
elsif ($format =~ /dc/) {
64
    ($error,$marc) = marc2dcxml($marc,1);
70
    SWITCH:
65
    $format = "dublin-core.xml";
71
        for ($recommendation) {
72
            if (/^simple-dc-rdf/) {
73
                ($error,$marc) = marc2dcxml($recommendation, $marc, 0,
74
                1, undef, undef, $resource_url , $formats);
75
                $format = "dublin-core." . $formats;
76
                last SWITCH; }
77
            if (/^dc-rdf/) {
78
                ($error,$marc) = marc2dcxml($recommendation, $marc, 1,
79
                1, undef, undef, $resource_url, $formats);
80
                $format = "dublin-core." . $formats;
81
                last SWITCH; }
82
            if (/^dc-xml/) {
83
                ($error,$marc) = marc2dcxml($recommendation, $marc, $qualifier,
84
                1, $root_element, $xsischemalocation, undef, undef);
85
                $format = "dublin-core.xml";
86
                last SWITCH; }
87
            if (/^oai-dc/) {
88
                ($error,$marc) = marc2dcxml($recommendation, $marc);
89
                $format = "dublin-core.xml";
90
                last SWITCH; }
91
        }
66
}
92
}
67
elsif ($format =~ /marc8/) {
93
elsif ($format =~ /marc8/) {
68
    ($error,$marc) = changeEncoding($marc,"MARC","MARC21","MARC-8");
94
    ($error,$marc) = changeEncoding($marc,"MARC","MARC21","MARC-8");
69
- 

Return to bug 13642